|
|
  |
Проблема с TWI |
|
|
|
Dec 19 2005, 14:15
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(James D. @ Dec 19 2005, 15:42)  Продолжаю добивать TWI. Хочу разобраться в конце-концов. Вопрос такой: на вызов мастера-передатчика должны отвечать оба слэйва? Какие действия должен предпринимать тот слэйв, адрес которого не совпал с переданным мастером? Раньше я делал так: от мастера к каждому слэйву кроме линий TWI шли еще по одной линии - разрешение на связь с мастером. Соответствующая линия сбрасывается в "0", если мастер хочет передавать данные на этот слэйв; вторая линия в "1", т.е. второй слэйв вообще не заходит в программу приема данных по TWI. Так не заработало - могу передать только на первый слэйв, при попытке передать на второй - все зависало - окончательно и безнадежно. Теперь сделал по-другому. Должно, по идее, работать так: мастер сбрасывает в "0" обе линии (разрешение на связь с мастером). Тот слэйв, адрес которого не совпал, выходит из программы приема данных, и продолжает выполнять основную прогу. А тот слэйв, адрес которого совпал - принимает данные. Но и здесь не все гладко. Мастер (m32) передает данные на слэйв1 (m32) - тут все нормально. Но слэйв2 (m16) при этом висит! Нажимаю на кнопочку, чтобы начать передавать данные на слэйв2 - он при этом выходит из зависания, и данные передаются на оба контроллера - так и должно быть. При этом слэйв1 не зависает. При включении передачи на слэйв1 - слэйв2 опять зависает.
Как тут быть?
P.S. Кстати, описанная ситуация происходит, если при связи с обоими МК мастер выдает повторный старт. Если мастер дает сигнал старт - все безнадежно зависает (при попытке передать на слэйв2). ИМХО вы не разобрались с протоколм I2C. Зачем вы ведёте линии разрешения если в протокол заложена АДРЕСАЦИЯ? вероятно у вас с этим и глюки связаны. Слэйв, адрес которого не совпадает, с адресом, который передаётся по шине НИЧЕГО С ШИНОЙ ДЕЛАТЬ НЕ ДОЛЖЕН.
|
|
|
|
|
Dec 19 2005, 14:49
|

Местный
  
Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466

|
TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно. Начало обработки TWI (слэйв): Код
Fr_M: sbic PIND,6;Проверка: мастер готов передавать данные? rjmp Go_prog;Если нет - прога выполняется дальше
Fr_M_n: ldi temp,$20;Инициализация режима "Приемник" out TWAR,temp
TWINT_n:ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN) out TWCR,temp
wait1n: in temp,TWCR;Ожидаем вызова от мастера sbrs temp,TWINT rjmp wait1n
in temp,TWSR andi temp,$F8 cpi temp,$60;Проверка принятого адреса от мастера breq Pr_data
ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp
rjmp Go_prog
;Прием данных:
Pr_data:
Сообщение отредактировал James D. - Dec 19 2005, 14:51
|
|
|
|
|
Dec 19 2005, 23:02
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Цитата(James D. @ Dec 19 2005, 17:49)  TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно. Начало обработки TWI (слэйв): Тут не просто кажеться ,тут 200% будут глюки. Если мастера еще можно сделать в основной программе,то подчиненного только по прерыванию. Слейв выдает NACK если адресс не совпадает и наоборот ACK если совпадает. По этому и ориентируется мастер,а слейв выдает по TWSR &h60 если к нему обратились и &h80 если после адресса пошли данные. Если делать по прерыванию,не нужно ничего ждать и проверять. В подпрограмме обработки прерывания достаточно проверять значения TWSR и соответственно реагировать.
|
|
|
|
|
Dec 20 2005, 05:56
|

Местный
  
Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466

|
Цитата В подпрограмме обработки прерывания достаточно проверять значения TWSR и соответственно реагировать. Что должен делать слэйв, адрес которого не совпал? Должен ли он выдавать NACK (см. ниже - я так понял, так выдается NACK): ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp Потом он выходит из прерывания - это понятно. В основной проге я сделал обработку TWI, потому что так было удобнее. Если это не правильно, тогда, конечно, придется делать по спец. прерываниям. На вызов мастера-передатчика должны отвечать ВСЕ слэйвы? В даташите написано, что все МК должны быть просто запитаны. Вот я и делал, что у меня отвечал только один, а второй вообще игнорировал вызов.
|
|
|
|
|
Dec 20 2005, 08:05
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(James D. @ Dec 20 2005, 08:56)  Что должен делать слэйв, адрес которого не совпал? ........ На вызов мастера-передатчика должны отвечать ВСЕ слэйвы? НАСТОЯТЕЛЬНО рекомендую перечитать информацию о I2C и TWI в частности. в неккоторых AVR'ках присутствует АППАРАТНЫЙ I2C~TWI. это обозначает что большинство действий с протоколом возложено на плечи железа, например генерация NACK(а точнее отсутствие генерации ACK) если адрес не совпал... т.е. ваши действия по работе с TWI (slave): 1) на каждое устройство придумать УНИКАЛЬНЫЙ адрес из диапазона 1-127. (0 адрес используется для массовых сообщений его выставлять НЕ надо). 2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево. 3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1. 4) ждать прерывание. 5) при прирывании в зависимости от регистра TWSR выполнить соответствуюшие действия (какие именно расписано в даташите) 6) поблагодарить меня за то что научил уму-разуму =) 7) получить пилюлей от IgorKossak за п. 6)
Сообщение отредактировал IgorKossak - Dec 20 2005, 09:49
|
|
|
|
|
Dec 20 2005, 10:51
|

Местный
  
Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466

|
Цитата 2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево. Зачем? Цитата 3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1. А TWINT не надо сбрасывать(в слэйве) при настройке, и в процессе работы (а также при выходе из обработчика прерывания)? Пока что у меня мастер зависает при попытке что-либо передать на любой из слэйвов... А слэйвы работают.
Сообщение отредактировал James D. - Dec 20 2005, 10:58
|
|
|
|
|
Dec 20 2005, 11:53
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(James D. @ Dec 20 2005, 13:51)  Цитата 2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево. Зачем? Цитата 3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1. А TWINT не надо сбрасывать(в слэйве) при настройке, и в процессе работы (а также при выходе из обработчика прерывания)? Пока что у меня мастер зависает при попытке что-либо передать на любой из слэйвов... А слэйвы работают. 1) конктретизуй вопрос. Зачем адрес записывать или зачем сдвигать на бит его. 2) мастер зависает скорее всего НЕ дожидаясь ACK от устройства. 3) TWINT надо сбрасывать только в обработчике прерываний, после того, как необходимая реакция на прерывание будет выполнена.
Сообщение отредактировал Petka - Dec 20 2005, 11:54
|
|
|
|
|
Dec 20 2005, 13:21
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(Petka @ Dec 20 2005, 13:53)  1) конктретизуй вопрос. Зачем адрес записывать или зачем сдвигать на бит его. "Сдвиг на бит" это если не сказать "записать адрес слейва в поле адреса". Делать это надо, чтобы слейв реагировал только на СВОЙ адрес, записанный в указанный регистр Цитата(Petka @ Dec 20 2005, 13:53)  2) мастер зависает скорее всего НЕ дожидаясь ACK от устройства. И не дождётся, т. к. у слейва не прописан свой адрес по которому его мастер спрашивает. Цитата(Petka @ Dec 20 2005, 13:53)  3) TWINT надо сбрасывать только в обработчике прерываний, после того, как необходимая реакция на прерывание будет выполнена. Или в фоновой программе если прерывания не применяются (тогда опрашивать надо быстро, чтобы не пропустить события).
|
|
|
|
|
Dec 20 2005, 14:31
|

Местный
  
Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466

|
Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так? При запуске контроллеров мастер передает слэйву несколько байт в фоновом режиме (в основной программе), до разрешения общих прерываний, настройки таймеров и т.д. Проходит нормально, даже если у слэйва адрес $20, или $40 (мастер передает адрес $20). Вот, что получается потом. Код ;Инициализация TWI:
ldi temp,$40 ;Инициализация режима "Приемник" out TWAR,temp ldi temp,(1<<TWEA)|(1<<TWEN)|(1<<TWIE) out TWCR,temp
sei Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает. Если мастер пытается что-либо передать, то зависает после загрузки адреса + WR (TWDR) на этапе ожидания, когда TWINT уст. в "1". Код wait: in temp,TWCR;Ожидаем ответа от слэйва sbrs temp,TWINT rjmp wait А этот бит устанавливаться не хочет. В чем же тут дело?
|
|
|
|
|
Dec 20 2005, 14:45
|
Профессионал
    
Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886

|
Цитата(James D. @ Dec 20 2005, 17:31)  Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так? ........ Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает. ........... В чем же тут дело? 1) Адреса должны совпадать. 2) В прерывании вы ДОЛЖНЫ обрабатывать все события, не только $60. у меня, например сеть висла, если я не обрабатывал $F8 и $00. 3) успехов!
|
|
|
|
|
Dec 20 2005, 18:26
|
Знающий
   
Группа: Свой
Сообщений: 543
Регистрация: 22-10-05
Пользователь №: 9 984

|
Хорошо,обьясняю популярнее.
Слейву вообще по барабану что твориться на шине, все гораздо проще чем вы думаете. Если на шине не то что ему нужно,он просто не выдаст прерывания
Первое прерывание возникнет только после того,когда проидет СТАРТ и совпадет адресс слейва,TWSR выдаст НЕХ 60, кричим УРА ,устанавливаем TWINT=1 и дружно выходим из прерывания. TWI при этом АППАРАТНО выдает АСК.
Второе и ДАЛЕЕ прерывание возникнет после того,когда прибудут данные ЕСЛИ ПЕРЕД ЭТИМ СОВПАЛ АДРЕСС ( то есть уже прошли первое прерывание) TWSR выдаст НЕХ 80.устанавливаем TWINT=1 и в TWDR имеем полученные данные,отправляем их куда хотим. выходим из прерывания.
И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении данных или нет. ЕСЛИ НЕТ тогда в следующем прерывании TWSR выдаст НЕХ 88 а МАСТЕР должен выдать СТОП. Соответственно мастер должен определять NACK и выдавать СТОП на шину.
ПОСЛЕДНЕЕ в принципе не обязательно. Просто если охота делать так как книжка пишет.
Сложно? Я думаю проще некуда.
У меня при таком раскладе слев легко берет пакеты со скоростью 800Кбит в сек ,при частоте проца 8Мгц
|
|
|
|
|
Dec 21 2005, 07:35
|

Местный
  
Группа: Участник
Сообщений: 315
Регистрация: 10-10-05
Пользователь №: 9 466

|
Цитата(Petka @ Dec 20 2005, 17:45)  Цитата(James D. @ Dec 20 2005, 17:31)  Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так? ........ Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает. ........... В чем же тут дело?
1) Адреса должны совпадать. 2) В прерывании вы ДОЛЖНЫ обрабатывать все события, не только $60. у меня, например сеть висла, если я не обрабатывал $F8 и $00. 3) успехов! 1. А кто мне говорил, что адрес в слэйве надо сдвигать на 1 бит? 2. Что нужно делать, если выпадет $F8 и $00? 3. Спасибо! Хорошо бы, чтоб они появились! То bodja74: "Если на шине не то что ему нужно,он просто не выдаст прерывания" А вот и нет - выдает постоянно, даже если к нему никто не обращается. А если слэйву из прерывания не выходить, при приеме адреса, данных, а принимать все в пределах одного прерывания по TWI? Просто ждать, когда TWINT уст. в "1"? "И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении данных или нет." Что-то я не пойму все-таки, как слэйв должен выдавать ACK или NACK. Это же делается аппаратно? Как это сделать программно? Мастер на шине один, и два подчиненных. Значит обработку ошибок касательно арбитража можно откинуть? Что должен делать слэйв, если его адрес не совпал с переданным мастером? В даташитовской таблице для подч-приемника это не описано.
|
|
|
|
|
Dec 21 2005, 10:06
|
Местный
  
Группа: Свой
Сообщений: 242
Регистрация: 27-01-05
Пользователь №: 2 225

|
Цитата(DeXteR @ Dec 21 2005, 13:00)  Вот бы кто из действительно шарящих людей описал бы подробно процесс обмена в случае с однирм мастером (приемником и передатчиком) и 2 слейвами а чем ,простите, шит не устраивает . имхо все доходчиво
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|