Petka 0 19 декабря, 2005 Опубликовано 19 декабря, 2005 · Жалоба Продолжаю добивать TWI. Хочу разобраться в конце-концов. Вопрос такой: на вызов мастера-передатчика должны отвечать оба слэйва? Какие действия должен предпринимать тот слэйв, адрес которого не совпал с переданным мастером? Раньше я делал так: от мастера к каждому слэйву кроме линий TWI шли еще по одной линии - разрешение на связь с мастером. Соответствующая линия сбрасывается в "0", если мастер хочет передавать данные на этот слэйв; вторая линия в "1", т.е. второй слэйв вообще не заходит в программу приема данных по TWI. Так не заработало - могу передать только на первый слэйв, при попытке передать на второй - все зависало - окончательно и безнадежно. Теперь сделал по-другому. Должно, по идее, работать так: мастер сбрасывает в "0" обе линии (разрешение на связь с мастером). Тот слэйв, адрес которого не совпал, выходит из программы приема данных, и продолжает выполнять основную прогу. А тот слэйв, адрес которого совпал - принимает данные. Но и здесь не все гладко. Мастер (m32) передает данные на слэйв1 (m32) - тут все нормально. Но слэйв2 (m16) при этом висит! Нажимаю на кнопочку, чтобы начать передавать данные на слэйв2 - он при этом выходит из зависания, и данные передаются на оба контроллера - так и должно быть. При этом слэйв1 не зависает. При включении передачи на слэйв1 - слэйв2 опять зависает. Как тут быть? P.S. Кстати, описанная ситуация происходит, если при связи с обоими МК мастер выдает повторный старт. Если мастер дает сигнал старт - все безнадежно зависает (при попытке передать на слэйв2). ИМХО вы не разобрались с протоколм I2C. Зачем вы ведёте линии разрешения если в протокол заложена АДРЕСАЦИЯ? вероятно у вас с этим и глюки связаны. Слэйв, адрес которого не совпадает, с адресом, который передаётся по шине НИЧЕГО С ШИНОЙ ДЕЛАТЬ НЕ ДОЛЖЕН. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 19 декабря, 2005 Опубликовано 19 декабря, 2005 (изменено) · Жалоба 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: Изменено 19 декабря, 2005 пользователем James D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 19 декабря, 2005 Опубликовано 19 декабря, 2005 · Жалоба TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно. сделайте как полагается, по своим прерываниям. а потом можете говорить что TWI не работает. Мне кажется из-за этих разрешений-запрещений шина и виснет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bodja74 0 19 декабря, 2005 Опубликовано 19 декабря, 2005 · Жалоба TWI у меня работает не по своим прерываниям, а в основной программе (в обработчике таймера). Линии разрешения я сделал для того, чтобы слэйвы не ждали, когда к ним обратится мастер, из-за этого прога будет работать очень медленно. Начало обработки TWI (слэйв): Тут не просто кажеться ,тут 200% будут глюки. Если мастера еще можно сделать в основной программе,то подчиненного только по прерыванию. Слейв выдает NACK если адресс не совпадает и наоборот ACK если совпадает. По этому и ориентируется мастер,а слейв выдает по TWSR &h60 если к нему обратились и &h80 если после адресса пошли данные. Если делать по прерыванию,не нужно ничего ждать и проверять. В подпрограмме обработки прерывания достаточно проверять значения TWSR и соответственно реагировать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 · Жалоба В подпрограмме обработки прерывания достаточно проверять значения TWSR и соответственно реагировать. Что должен делать слэйв, адрес которого не совпал? Должен ли он выдавать NACK (см. ниже - я так понял, так выдается NACK): ldi temp,(1<<TWINT)|(1<<TWEN) out TWCR,temp Потом он выходит из прерывания - это понятно. В основной проге я сделал обработку TWI, потому что так было удобнее. Если это не правильно, тогда, конечно, придется делать по спец. прерываниям. На вызов мастера-передатчика должны отвечать ВСЕ слэйвы? В даташите написано, что все МК должны быть просто запитаны. Вот я и делал, что у меня отвечал только один, а второй вообще игнорировал вызов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 (изменено) · Жалоба Что должен делать слэйв, адрес которого не совпал? ........ На вызов мастера-передатчика должны отвечать ВСЕ слэйвы? НАСТОЯТЕЛЬНО рекомендую перечитать информацию о 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) :twak: Изменено 20 декабря, 2005 пользователем IgorKossak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 (изменено) · Жалоба 2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево. Зачем? 3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1. А TWINT не надо сбрасывать(в слэйве) при настройке, и в процессе работы (а также при выходе из обработчика прерывания)? Пока что у меня мастер зависает при попытке что-либо передать на любой из слэйвов... А слэйвы работают. Изменено 20 декабря, 2005 пользователем James D. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 (изменено) · Жалоба 2) записать адрес в регистр TWAR выбранный адрес сдвинутый на один бит влево. Зачем? 3) настроить контрольный регистр TWI (TWСR) TWIE=1, TWEN=1, TWEA=1. А TWINT не надо сбрасывать(в слэйве) при настройке, и в процессе работы (а также при выходе из обработчика прерывания)? Пока что у меня мастер зависает при попытке что-либо передать на любой из слэйвов... А слэйвы работают. 1) конктретизуй вопрос. Зачем адрес записывать или зачем сдвигать на бит его. 2) мастер зависает скорее всего НЕ дожидаясь ACK от устройства. 3) TWINT надо сбрасывать только в обработчике прерываний, после того, как необходимая реакция на прерывание будет выполнена. Изменено 20 декабря, 2005 пользователем Petka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 · Жалоба 1) конктретизуй вопрос. Зачем адрес записывать или зачем сдвигать на бит его. "Сдвиг на бит" это если не сказать "записать адрес слейва в поле адреса". Делать это надо, чтобы слейв реагировал только на СВОЙ адрес, записанный в указанный регистр 2) мастер зависает скорее всего НЕ дожидаясь ACK от устройства. И не дождётся, т. к. у слейва не прописан свой адрес по которому его мастер спрашивает. 3) TWINT надо сбрасывать только в обработчике прерываний, после того, как необходимая реакция на прерывание будет выполнена. Или в фоновой программе если прерывания не применяются (тогда опрашивать надо быстро, чтобы не пропустить события). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 · Жалоба Установил адрес слэйва - $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 А этот бит устанавливаться не хочет. В чем же тут дело? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 · Жалоба Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так? ........ Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает. ........... В чем же тут дело? 1) Адреса должны совпадать. 2) В прерывании вы ДОЛЖНЫ обрабатывать все события, не только $60. у меня, например сеть висла, если я не обрабатывал $F8 и $00. 3) успехов! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bodja74 0 20 декабря, 2005 Опубликовано 20 декабря, 2005 · Жалоба Хорошо,обьясняю популярнее. Слейву вообще по барабану что твориться на шине, все гораздо проще чем вы думаете. Если на шине не то что ему нужно,он просто не выдаст прерывания Первое прерывание возникнет только после того,когда проидет СТАРТ и совпадет адресс слейва,TWSR выдаст НЕХ 60, кричим УРА ,устанавливаем TWINT=1 и дружно выходим из прерывания. TWI при этом АППАРАТНО выдает АСК. Второе и ДАЛЕЕ прерывание возникнет после того,когда прибудут данные ЕСЛИ ПЕРЕД ЭТИМ СОВПАЛ АДРЕСС ( то есть уже прошли первое прерывание) TWSR выдаст НЕХ 80.устанавливаем TWINT=1 и в TWDR имеем полученные данные,отправляем их куда хотим. выходим из прерывания. И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении данных или нет. ЕСЛИ НЕТ тогда в следующем прерывании TWSR выдаст НЕХ 88 а МАСТЕР должен выдать СТОП. Соответственно мастер должен определять NACK и выдавать СТОП на шину. ПОСЛЕДНЕЕ в принципе не обязательно. Просто если охота делать так как книжка пишет. Сложно? Я думаю проще некуда. У меня при таком раскладе слев легко берет пакеты со скоростью 800Кбит в сек ,при частоте проца 8Мгц Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
James D. 0 21 декабря, 2005 Опубликовано 21 декабря, 2005 · Жалоба Установил адрес слэйва - $40, а мастер вызывает адресом - $20. Так? ........ Слэйв-приемник постоянно входит в обработчик прерывания TWI, производит проверку адреса (код $60 не соответствует, и выходит из прерывания), даже если мастер вообще передачу по TWI не начинает. ........... В чем же тут дело? 1) Адреса должны совпадать. 2) В прерывании вы ДОЛЖНЫ обрабатывать все события, не только $60. у меня, например сеть висла, если я не обрабатывал $F8 и $00. 3) успехов! 1. А кто мне говорил, что адрес в слэйве надо сдвигать на 1 бит? 2. Что нужно делать, если выпадет $F8 и $00? 3. Спасибо! Хорошо бы, чтоб они появились! То bodja74: "Если на шине не то что ему нужно,он просто не выдаст прерывания" А вот и нет - выдает постоянно, даже если к нему никто не обращается. А если слэйву из прерывания не выходить, при приеме адреса, данных, а принимать все в пределах одного прерывания по TWI? Просто ждать, когда TWINT уст. в "1"? "И ПОСЛЕДНЕЕ решаем выставлять нам АСК при следующем получении данных или нет." Что-то я не пойму все-таки, как слэйв должен выдавать ACK или NACK. Это же делается аппаратно? Как это сделать программно? Мастер на шине один, и два подчиненных. Значит обработку ошибок касательно арбитража можно откинуть? Что должен делать слэйв, если его адрес не совпал с переданным мастером? В даташитовской таблице для подч-приемника это не описано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DeXteR 0 21 декабря, 2005 Опубликовано 21 декабря, 2005 · Жалоба Добрый день Вот бы кто из действительно шарящих людей описал бы подробно процесс обмена в случае с однирм мастером (приемником и передатчиком) и 2 слейвами Ну типа там 1. Мастер посылает АСК .... 2. ..... Всем Спасибо De}{teR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
m16 0 21 декабря, 2005 Опубликовано 21 декабря, 2005 · Жалоба Вот бы кто из действительно шарящих людей описал бы подробно процесс обмена в случае с однирм мастером (приемником и передатчиком) и 2 слейвами а чем ,простите, шит не устраивает . имхо все доходчиво Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться