Mega 8 + TWI (I2C) Slave Помогите.
-
Kirill_west
- Родился
- Сообщения: 5
- Зарегистрирован: Ср мар 18, 2009 10:31:35
- Контактная информация:
Mega 8 + TWI (I2C) Slave Помогите.
Добрый день, Коты. Конечно тема избитая, но все-же помогите разобраться.
Иметься некое мастер –устройство I2C (а именно LEGO MINDSTORMS NXT)
Подключаю Мегу8 (аппаратный TWI Slave) в итоге получаю что-то не очень понятное.
Может я что-то напутал в коде.
Код меги.
######################################
#include <mega8>
#include <lcd>
#include <delay>
unsigned char w,r;
interrupt [TWI] void twi_isr(void) // 2 Wire bus interrupt service routine
{
if (TWSR == 0xA8){TWDR=r;};
TWCR=0xC5;//в прерывании устанавливаются биты 7(TWINT),6(TWEA),2(TWEN) и 0(TWIE)-иначе не работает
w=TWDR;
//w=w/2;
}
#asm
.equ __lcd_port=0x12 ;PORTD // Alphanumeric LCD Module functions
#endasm
void main(void)
{
r=0;
w=0;
ACSR=0x80;//аналоговый компаратор ВЫКЛ
TWBR=0x0C;// Bit Rate: 100,000 kHz
TWAR=0x64;//любой адрес,который хочется,но нулевой бит отвечает за поведение при общем вызове(0-откл;1-вкл)
TWCR=0x45;//включаем для режима работы "ведомый приёмник" 0(TWIE), 2(TWEN) и 7(TWEA) биты
//lcd_init(16); // LCD module initialization
#asm("sei") // Global enable interrupts
while (1)
{
r=w+5;
};
}
#####################################################
Данный код не совсем мой…
В итоге вот что получаю:
Отправляю с мастера ##адрес##дата1(число 20 )##дата2( число 33) ##
Полуаю на мастер ответ ##адрес##дата1(число 40 +5 )##
Вопрос почему я получил Удвоенную Дату1+5. почему именно Удвоенная?
Вопрос почему я НЕ получил в мегу Дату2. почему?
Просьба помочь …
Иметься некое мастер –устройство I2C (а именно LEGO MINDSTORMS NXT)
Подключаю Мегу8 (аппаратный TWI Slave) в итоге получаю что-то не очень понятное.
Может я что-то напутал в коде.
Код меги.
######################################
#include <mega8>
#include <lcd>
#include <delay>
unsigned char w,r;
interrupt [TWI] void twi_isr(void) // 2 Wire bus interrupt service routine
{
if (TWSR == 0xA8){TWDR=r;};
TWCR=0xC5;//в прерывании устанавливаются биты 7(TWINT),6(TWEA),2(TWEN) и 0(TWIE)-иначе не работает
w=TWDR;
//w=w/2;
}
#asm
.equ __lcd_port=0x12 ;PORTD // Alphanumeric LCD Module functions
#endasm
void main(void)
{
r=0;
w=0;
ACSR=0x80;//аналоговый компаратор ВЫКЛ
TWBR=0x0C;// Bit Rate: 100,000 kHz
TWAR=0x64;//любой адрес,который хочется,но нулевой бит отвечает за поведение при общем вызове(0-откл;1-вкл)
TWCR=0x45;//включаем для режима работы "ведомый приёмник" 0(TWIE), 2(TWEN) и 7(TWEA) биты
//lcd_init(16); // LCD module initialization
#asm("sei") // Global enable interrupts
while (1)
{
r=w+5;
};
}
#####################################################
Данный код не совсем мой…
В итоге вот что получаю:
Отправляю с мастера ##адрес##дата1(число 20 )##дата2( число 33) ##
Полуаю на мастер ответ ##адрес##дата1(число 40 +5 )##
Вопрос почему я получил Удвоенную Дату1+5. почему именно Удвоенная?
Вопрос почему я НЕ получил в мегу Дату2. почему?
Просьба помочь …
-
Kirill_west
- Родился
- Сообщения: 5
- Зарегистрирован: Ср мар 18, 2009 10:31:35
- Контактная информация:
Ну не хотите помочь , я сам Вам расскажу что получилось. )))
Я попробовал с учетом того что я только примерно знаю скорость и прочие характеристики шины-I2C работающей в LEGO – уверен что там тоже много ошибок. т.к. шина там не 100% I2C а написана кем-то программно…. )
ну после некоторых «танцев с бубном» получил вот такое более менее работающее чудо…
#include <mega8>
#include <delay>
unsigned char w,t;
interrupt [TWI] void twi_isr(void) // 2 Wire bus interrupt service routine
{
if (TWSR == 0xA8){TWDR=t; TWCR=0xC5; while (TWSR == 0xC0){};} // ждем пока не получим подтверждение передачи
TWCR=0xC5; //в прерывании устанавливаются биты 7(TWINT),6(TWEA),2(TWEN) и 0(TWIE)-иначе не работает
while (TWSR == 0x80){w=TWDR;} // читаем TWDR только после получения подтверждения приема иначе читает весь мусор из TWDR
}
void main(void)
{
w=0;
t=0;
ACSR=0x80;//аналоговый компаратор ВЫКЛ
TWBR=0x0C;// Bit Rate: 100,000 kHz
TWAR=0x64;//любой адрес,который хочется,но нулевой бит отвечает за поведение при общем вызове(0-откл;1-вкл)
TWCR=0x45;//включаем для режима работы "ведомый приёмник" 0(TWIE), 2(TWEN) и 7(TWEA) биты
#asm("sei") // Global enable interrupts
while (1)
{
t=w+1; // ну это так вроде что-то делаем
};
}
Я попробовал с учетом того что я только примерно знаю скорость и прочие характеристики шины-I2C работающей в LEGO – уверен что там тоже много ошибок. т.к. шина там не 100% I2C а написана кем-то программно…. )
ну после некоторых «танцев с бубном» получил вот такое более менее работающее чудо…
#include <mega8>
#include <delay>
unsigned char w,t;
interrupt [TWI] void twi_isr(void) // 2 Wire bus interrupt service routine
{
if (TWSR == 0xA8){TWDR=t; TWCR=0xC5; while (TWSR == 0xC0){};} // ждем пока не получим подтверждение передачи
TWCR=0xC5; //в прерывании устанавливаются биты 7(TWINT),6(TWEA),2(TWEN) и 0(TWIE)-иначе не работает
while (TWSR == 0x80){w=TWDR;} // читаем TWDR только после получения подтверждения приема иначе читает весь мусор из TWDR
}
void main(void)
{
w=0;
t=0;
ACSR=0x80;//аналоговый компаратор ВЫКЛ
TWBR=0x0C;// Bit Rate: 100,000 kHz
TWAR=0x64;//любой адрес,который хочется,но нулевой бит отвечает за поведение при общем вызове(0-откл;1-вкл)
TWCR=0x45;//включаем для режима работы "ведомый приёмник" 0(TWIE), 2(TWEN) и 7(TWEA) биты
#asm("sei") // Global enable interrupts
while (1)
{
t=w+1; // ну это так вроде что-то делаем
};
}
Re: Mega 8 + TWI (I2C) Slave Помогите.
Уважаемые кошаки помогите разобраться с слев моде в TWI МК
Мастер МК:
Библиотека для работы (работает проверено на часовой МК):
гдето в начале глобальные переменные
var1
var2
err_twi_code // для отладки
На мастере имеем запрос.
Слейв:
в Слейве есть прерывание
в Майне инициализация:
//напомню TWCR = 0b TWINT TWEA TWSTA TWSTO TWWC TWEN 0 TWIE
Проблема в том что вся связка намертво виснет при попытке считать байты. В каком направлении дальше копать?
Мастер МК:
Библиотека для работы (работает проверено на часовой МК):
Код: Выделить всё
#define TWEN 2
#define TWIE 0
#define TWINT 7
#define TWEA 6
#define TWSTA 5
#define TWSTO 4
#define TWWC 3
#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_SLA_NACK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NACK 0x30
#define SR_SLA_ACK 0x60
#define SR_DATA_ACK 0x80
#define TWCR_default_M (1<<TWINT)|(1<<TWEN)|(1<<TWIE)
#define TWCR_default_S (1<<TWEA)|(1<<TWEN)|(1<<TWIE)
void twi_start(void) {
TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {; }
}
void twi_stop(void) {
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
void twi_write(unsigned char _data)
{
TWDR = _data;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {;}
}
unsigned char twi_read(unsigned char _ack) {
unsigned char _data;
if (_ack==1)
{
TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN);
}
else
{
TWCR = (1<<TWINT) | (1<<TWEN);
}
while (!(TWCR & (1<<TWINT)))
{
}
_data = TWDR;
return _data;
}
гдето в начале глобальные переменные
var1
var2
err_twi_code // для отладки
На мастере имеем запрос.
Код: Выделить всё
void read_i2c_mydev(void){
byte tmp;
twi_start();
twi_write(0b10000001);//0b10000001 адрес слейв МК на чтение
if ((TWSR & 0xF8) != MT_SLA_ACK) {err_twi_code=1; return; }
var1=twi_read(1);
var2=twi_read(0);
twi_stop();
}Слейв:
в Слейве есть прерывание
Код: Выделить всё
// 2 Wire bus interrupt service routine
interrupt [TWI] void twi_isr(void)
{
PORTC.1=0;
if (TWSR == 0x60){ }
if (TWSR == 0x80){ TWDR=2;}
if (TWSR == 0x88){ TWDR=3;}
TWCR=TWCR | 0b10000000; // сброс int флага
PORTC.1=1;
}в Майне инициализация:
Код: Выделить всё
TWSR=0b00000000;
TWBR=0x48; // 100кГц
TWAR=0b10000000; //адрес. 0бит=0 - не отзываться по общему вызову.
TWCR=0b11000101;//напомню TWCR = 0b TWINT TWEA TWSTA TWSTO TWWC TWEN 0 TWIE
Проблема в том что вся связка намертво виснет при попытке считать байты. В каком направлении дальше копать?
в спорах рождается ИСТИНА [AND] flud.
- ChipKiller
- Сверлит текстолит когтями
- Сообщения: 1163
- Зарегистрирован: Ср янв 05, 2011 16:25:15
Re: Mega 8 + TWI (I2C) Slave Помогите.
... ИМХО определить для начала на каком именно участке виснет - вставить, например, в функции "отладочный вывод" ( зажечь/погасить светодиод на свободном выводе МК)demson писал(а):В каком направлении дальше копать?
Re: Mega 8 + TWI (I2C) Slave Помогите.
Смотрю с мастера.
шлем старт
ждем завершения
ок - 0×08 Start Был сделан старт. Теперь мы решаем что делать дальше, например послать адрес ведомого
шлем адрес
тут ради прикола глянул неопределенное состояние регистра оно F8
ждем
ок - 0×40 SLA+R+ACK Послали адрес с битом на чтение, а ведомый отозвался. Хорошо! Будем читать
и вылетает на проверке (TWSR & 0xF8) != MT_SLA_ACK)
опана вот ошибка похоже тут и пряталась. удалим.
далее приняли посыл 50 58
0×50 Receive Byte Мы приняли байт. И думаем что бы ответить ведомому. ACK или NACK.
0×58 Receive Byte+NACK Мы приняли байт от ведомого и сказали ему “иди NACK!” И он обиженый ушел, освободив шину.
шлем старт
ждем завершения
ок - 0×08 Start Был сделан старт. Теперь мы решаем что делать дальше, например послать адрес ведомого
шлем адрес
тут ради прикола глянул неопределенное состояние регистра оно F8
ждем
ок - 0×40 SLA+R+ACK Послали адрес с битом на чтение, а ведомый отозвался. Хорошо! Будем читать
и вылетает на проверке (TWSR & 0xF8) != MT_SLA_ACK)
опана вот ошибка похоже тут и пряталась. удалим.
далее приняли посыл 50 58
0×50 Receive Byte Мы приняли байт. И думаем что бы ответить ведомому. ACK или NACK.
0×58 Receive Byte+NACK Мы приняли байт от ведомого и сказали ему “иди NACK!” И он обиженый ушел, освободив шину.
в спорах рождается ИСТИНА [AND] flud.
Re: Mega 8 + TWI (I2C) Slave Помогите.
Да, стоило закаментить строчку и все стало работать отлично.
в спорах рождается ИСТИНА [AND] flud.
- apwork
- Первый раз сказал Мяу!
- Сообщения: 21
- Зарегистрирован: Ср май 11, 2011 12:24:54
- Откуда: Лисичанск
Re: Mega 8 + TWI (I2C) Slave Помогите.
У меня ATmega8 категорически отказывалась работать с прерыванием TWI. Где-то в недрах инета находил, что это давняя болезнь ATmega8 и сей баг был поправлен в ATmega88.
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=24259&start=0
http://kazus.ru/forums/showthread.php?t=17864
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=24259&start=0
http://kazus.ru/forums/showthread.php?t=17864
Re: Mega 8 + TWI (I2C) Slave Помогите.
странно мастер 16 мега слейв 8я все отлично работает. Оправка мастером без прерываний слейв на прерываниях. Внешние кварцы 16Мгц и там и там.
Старт, повторный старт, стоп генерирует мастер. Слейв только скидывает флаги прерываний, причем независимо от того какой статус регистра статуса. Не замечал чтобы что-то висло.
Старт, повторный старт, стоп генерирует мастер. Слейв только скидывает флаги прерываний, причем независимо от того какой статус регистра статуса. Не замечал чтобы что-то висло.
в спорах рождается ИСТИНА [AND] flud.