James D.
Nov 10 2005, 11:34
Тихо шифером шурша ...
Ситуация такая. Слэйв м16 восстановил так, как было вчера - TWI работает не по прерыванию (зациклено в основной программе), по прерыванию мигает диод.
Мастер м32 вначале (сразу после инициализации контроллера) передает данные на слэйв м32.
Потом, по прерыванию (по переполнению) таймера, мастер м32 постоянно передает данные на слэйв м32, и после этого (в этом же обработчике прерыв.) передает данные на слэйв м16.
Такая комбинация при передаче на слэйв м32 работает, а на слэйв м16 не работает.
Но если убрать в проге мастера м32 вначале и в обработчике прерыв. передачу на слэйв м32, то передача на слэйв м16 работает.
Может там как-то с сигналами START, повторный START и STOP надо порядок навести? Но я перебрал уже разные варианты - ничего не помогает.
beer_warrior
Nov 10 2005, 12:35
Артем, запись 1 в TWINT сбрасывает триггер, а прервывание его взводит.
James, если м16 слэйв работает нормально, при отключенном м32слэйв. Значит предыдущая сессия обмена не закрывалась.
Вообще в отличии от большинства меговской перефирии TWI живет
как конечный автомат с кучей состояний.
Внимательно просмотрите таблицы с кодами TWSTA, в последней колонке список предлагаемых дествий после каждого этапа передачи. Т.е. тупая линейная программа - дали команду ждем завершения не катит, особенно если на линии больше двух устройств.
Т.е. мы отлавливаем каждый код возврата и ждем не только
ожидаемого исхода, но и обрабатываем возможные Nack, arbitration lost итд.
По этому коду принимаем решение о продолжении обмена, рестарте,
аварийном завершении итп.
Насколько я вижу картину, автомат сейчас заносит в какоето состояние которое не обрабатываеться. После чего невозврат ACK
и вечный цикл в ожидании TWINT который уже не придет.
Попробую скомпилировать вышеприведенный С код и кинуть листинг
для наглядности.
James D.
Nov 10 2005, 16:34
Хорошо, если можно запустить программу обработки ошибок (знать бы еще как ее сделать), а если зацикливается в цикле ожидания wait1 (такое иногда бывает, только сейчас не вспомню при каких условиях - я их столько перебрал, вспомнить страшно)? Как тогда быть?
ldi temp,$00 ;Установка скорости передачи = 100 kHz
out TWSR,temp
ldi temp,12
out TWBR,temp
Pusk_St:ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR,temp ;Посылка сигнала "START"
wait1: in temp,TWCR ;Ожидаем ответа от слэйв контроллера
sbrs temp,TWINT
rjmp wait1
_artem_
Nov 10 2005, 18:17
2 beer_warrior, ya s samogo nachala zametil chto po 1 TWINT sbrasyvaetsya , no etot data sheet v tom meste kotoroe ya ukazal govorit drugoe, mozet byt ya chtoto nepravilno ponyal iz napisannogo v DS . Erratu dlya atmegi 16 ne nasel.
Yesli tebe ne trudno, mozes li posmotret na stranicu 189 v data shite atmega16 ?
beer_warrior
Nov 10 2005, 18:41
to artem:
• Bit 7 – TWINT: TWI Interrupt Flag
This bit is set by hardware when the TWI has finished its current job and expects application
software response. If the I-bit in SREG and TWIE in TWCR are set, the MCU will
jump to the TWI Interrupt Vector. While the TWINT Flag is set, the SCL low period is
stretched.
The TWINT Flag must be cleared by software by writing a logic one to it.
Страница 179 описание TWCR
to James:
Не хочеться раздувать топик, на выходных склепаю заметочку с подробным разбором этой
темы и выложу у себя на страничке.
Я тоже очень долго воевал c TWI, в моем случае был multimaster да еще на очень кривом железе,
поэтому опыта поднабрался немало <_<
James D.
Nov 10 2005, 20:41
Я очень благодарен вам за помощь. Буду ждать подробного разбора полетов, но и со своей стороны приложу максимум усилий для решения этой проблемы.
James D.
Nov 11 2005, 07:37
Маленький вопрос.
Если писать программы на Си, можно ли для AVR-контроллеров написать программы рассчета тригонометрических функций, возведение в степень, извлечение корней, операций с плавающей запятой и прочей математики? С какой скоростью МК AVR будет рассчитывать такие функции?
Можно ли где-то найти обучение программированию на С для AVR?
beer_warrior
Nov 11 2005, 08:16
James D.
Nov 11 2005, 09:46
Нашел на диске обучение языку С. Что-то типа книги, правда там уклон на написание программ для компьютера. В качастве компилятора использую - "CodeVisionAVR C Compiler". Попробую применить этот С для написания прог для МК...
Цитата(James D. @ Nov 11 2005, 12:46)

Попробую применить этот С для написания прог для МК...
Весьма похвально. Но имейте ввиду, что CVAVR-овский компайлер,
так сказать, имеет много гитик, то есть девиаций, иногда полезных,
от стандартного C. Да и кто их не имеет.. Но все равно могу
предсказать вам радость от сокращения в десятки разов, если не
в сотни, времени разработки. Я вас даже зауважал, писать для
32-й меги на авээровском асме - это да!
James D.
Nov 11 2005, 19:24
Дело привычки. На асме пишется легко, и код меньше, чем на Си. У меня м32 уже заполнена на 3/4, а еще надо кое-что сделать, да вот застопорило на TWI. Прямо беда. Какой вариант решения не выберу - как в глухую стену упираюсь!
Кстати, не посоветуете ли, где можно скачать книгу или что-нибудь про обучение программированию на С именно для AVR контроллеров - желательно, конечно, на русском. А то книга, которую я нашел, куда-то не туда уводит. Конечно, азы я оттуда, наверное, почерпну, а вот дальше...
James D.
Nov 14 2005, 13:10
Вопрос.
Каждый раз, при необходимости что-либо передать, мастер м32 производит установку скорости:
ldi temp,$00 ;Установка скорости передачи= 100 kHz
out TWSR,temp
ldi temp,12
out TWBR,temp
это надо делать каждый раз, или только один - при инициализации контроллера?
Далее.
После передачи команды "START", мастер получает код $08, дальше идет загрузка адреса слэйв м16:
ldi temp,$04 ;Загрузка адреса слэйв м16 + "WRITE"
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
после этого идет цикл ожидания:
wait2r: in temp,TWCR ;Ожидаем ответа от слэйв м16
sbrs temp,TWINT
rjmp wait2r
и все на этом зацикливается. Как тут быть?
И еще непонятно: когда надо передавать "START", а когда "Повторный START", и чем они отличаются?
Напомню: мастер на шине один, он обращается в произвольном порядке к двум подчиненным.
James D.
Nov 14 2005, 14:11
Получается так, что передача с мастера м32 на слэйв м32 проходит только если мастер задает "Повторный START".
А на слэйв м16 можно давать "START", эта операция проходит нормально.
По-моему я запутался окончательно...

P.S. Должен ли мастером, после каждого сеанса связи, выдаваться сигнал "STOP"?
Касаемо, конечно же, рассматриваемой ситуации.
IgorKossak
Nov 16 2005, 08:17
Цитата(James D. @ Nov 14 2005, 16:11)

... Должен ли мастером, после каждого сеанса связи, выдаваться сигнал "STOP"?
Касаемо, конечно же, рассматриваемой ситуации.
Должен касаемо любой ситуации, но ждать окончания выполнения этой операции не нужно (зависнет пожизнено)!!!
James D.
Nov 16 2005, 15:40
При передаче с мастера м32 на слэйв м32 я поубирал команды STOP у обоих МК - работает, как ни в чем не бывало!
А с м16 полный ступор. И со STOP'ом и без оного...
IgorKossak
Nov 16 2005, 16:51
Цитата(James D. @ Nov 16 2005, 17:40)

При передаче с мастера м32 на слэйв м32 я поубирал команды STOP у обоих МК - работает, как ни в чем не бывало!
А с м16 полный ступор. И со STOP'ом и без оного...
Трюкачеством можно заниматься сколько угодно.
И в некоторых случаях это даже срабатывает.
Но если хочется, чтобы работало ПРАВИЛЬНО и ВСЕГДА, то желательно в точности соблюсти требования спецификации на интерфейс, особенности его реализации на конкретном МК и, в конце концов, определиться - чего же мы хотим получить в результате (может мы хотим того, чего нельзя хотеть?).
James D.
Nov 16 2005, 19:32
Я хочу, очень хочу, чтобы все работало ПРАВИЛЬНО и ВСЕГДА!
Вы мне лучше скажите, требования спецификации на интерфейс для разных МК отличаются?
А насчет того, что "может мы хотим того, чего нельзя хотеть?" - я хочу переслать данные с м32 на м16, и они таки пересылаются, но, если перед этим не передавать данные на другую м32.
Все подробно описано в этой теме.
IgorKossak
Nov 17 2005, 07:51
Цитата(James D. @ Nov 16 2005, 21:32)

...требования спецификации на интерфейс для разных МК отличаются?
Нет, не отличаются.
Цитата
...я хочу переслать данные с м32 на м16, и они таки пересылаются, но, если перед этим не передавать данные на другую м32...
У меня была похожая ситуация пока я не стал обрабатывать все Status Codes касающиеся режимов Slave Receiver и Slave Transmitter а также приводить интерфейс в исходное состояние (буферы, указатели ...) по приёму STOP или repeated START, а также отслеживать состояния ошибок.
Ещё надо следить кто и когда должен выставлять ACK.
И ещё вдобавок. Поскольку интерфейс синхронный, то он может работать на предельно низких скоростях вплоть до дёргания ножек руками и слежения что и когда происходит.
PS: у меня с TWI работают mega128, mega32, mega16, mega8 (программный модуль один и тот же, основа которого взята из описания).
_artem_
Nov 17 2005, 10:30
Может вам интересно будет - послал мeйл Атмелу насчет TWI slave polled mode. Сначала ответили примером из AN который на сайте . После этого обьяснил им что хочу polled а не interrupted ,
ответили что не рекомендуем, а если хочешь разрабатывай сам. Ну а я им - обьясните почему не рекомендуете.
Вот жду ответ на этот вопрос . Надеюсь они будут честно настолько чтобы признать ошибку в дизайне микрухи.
James D.
Nov 17 2005, 21:33
IgorKossak, я был бы вам безмерно благодарен, если бы вы привели здесь пример программок приема-передачи, желательно на асме, потому как на С я ничего не пойму... Только начал изучать, поэтому пока я в С ни бум-бум.
Как правильно приводить интерфейс в исходное состояние (буферы, указатели ...) по приёму STOP или repeated START, а также отслеживать состояния ошибок? И ACK, с этим тоже непонятки.
Но у меня бывает, что зацикливается здесь:
wait2r: in temp,TWCR ;Ожидаем ответа от слэйв м16
sbrs temp,TWINT
rjmp wait2rи мастер, и слэйв могут зациклится на этом этапе. Как тут отследить состояние ошибок?
И еще. TWI у меня работает не по своим прерываниям: прога мастера м32 находится в обработчике прерыв. по переполнению таймера, а слэйв м16 вообще не в обработчике прерывания, а в состоянии постоянного ожидания - зациклено и все. Т.е. принял данные, поместил их в регистры, и ждет нового вызова. Хотя тут, наверное, можно и по прерыванию TWI сделать - знать бы как!
Артем, мне тоже было бы интересно узнать их ответ, но вряд ли он будет. Сомневаюсь я. Называется - ломайте головы сами.
P.S. Что-то давненько beer_warrior не заглядывает. Жалко, так хорошо сидели...
IgorKossak
Nov 18 2005, 09:00
Уважаемый James D., с ассемблером я сталкиваюсь только когра просматриваю листинги.
Пишу я на EC++, да ещё и в контексте операционной системы, да ещё и только по прерываниям, так что мои тексты Вам врядли помогут.
Тем не менее, если Вам удастся выдавать байты от мастера в слейв пошагово с анализом байта состояния слейва, то Вы и сами сможете найти ошибку.
Рекомендую протестировать сначала всю связку в простейшем случае, когда больше ничего другого система не делает.
James D.
Nov 18 2005, 19:41
У меня на всех трех МК (м16 и два м32) стоят кварцы по 4 MHz.
Фузы прошиты так, как показано ниже:
Fuse Bit(s):
CKSEL0=1
CKSEL1=1
CKSEL2=1
CKSEL3=1
SUT0=1
SUT1=1
BODEN=0
BODLEVEL=0
BOOTRST=1
BOOTSZ0=1
BOOTSZ1=1
EESAVE=1
CKOPT=0
JTAGEN=1
OCDEN=1
правильно ли это? Может надо прошить для 4 MHz?
Неиспользуемые пины всех МК надо ли настраивать на вывод, и устанавливать в "0"? Или подтягивать внутренними резисторами к +5V? Типа, чтобы не болтались в воздухе? Надо ли как-то настраивать пины, которые использует TWI (PC0, PC1)?
Может быть, после всего этого заработает, наконец, TWI?
Сейчас у меня нет доступа к МК, чтобы проверить, поэтому и спрашиваю.
P.S. Еще такой вопрос. Каждый сеанс связи мастера со слэйвом надо заканчивать просто подавая команду STOP? Надо ли обнулять бит TWEN?
А передачу на другой МК надо начинать со START или Повторный START? Мастер на шине один.
Установку скорости передачи (она одна для обоих слэйвов) надо производить каждый раз при начале передачи, или можно ее установить один раз при включении МК?
В режиме слэйв-приемник, адрес приемника (TWAR) устанавливать также - один раз при включении МК?
Цитата(_artem_ @ Nov 17 2005, 13:30)

Может вам интересно будет - послал мeйл Атмелу насчет TWI slave polled mode. Сначала ответили примером из AN который на сайте . После этого обьяснил им что хочу polled а не interrupted ,
ответили что не рекомендуем, а если хочешь разрабатывай сам. Ну а я им - обьясните почему не рекомендуете.
Вот жду ответ на этот вопрос . Надеюсь они будут честно настолько чтобы признать ошибку в дизайне микрухи.
Кстати, господа, у Атмелей в аппнотах 311 и 315 БААЛЬШОЙ баг, то исть их ISR в ряде случаев не
ресетит TWINT в обработчике прерывания, что не есть гуд, ибо в даташите сказано прямо и честно,
пока выставлен TWINT, SCL шины лежит в нуле, что вообще-то, корректно. Но если вы пользуете
атмелевский код (даа, тот, который с прерываниями) и на дай Бог попали на кэйс с незарешеченным
TWINT, то можете долго любоваться шиной с заваленным SCL. Требую линчевать писавшего код
под эти аппноты индуса (не читал даташит, сцуко)! А с дизайном микрухи все ОК (это я про TWI),
разве что соображения про минвэлью в TWBR.
James D.
Nov 20 2005, 13:32
Сделал простейший случай, когда больше ничего другого система не делает.
Никаких прерываний, передача идет после инициализации стека и портов.
Мастер м32 должен передать на слэйв м32, после, сразу же, на слэйв м16. После этого все программы принудительно зависают.
Так вот, что получилось.
Мастер сначала передает на слэйв м32 - передача проходит нормально. На слэйв м16 передачи нет.
Делал так:
1. на слэйв м32 мастер подает "START" (код $08), на слэйв м16 - "START" (код $08); при передаче на слэйв м16 зацикливается на этапе загрузки адреса м16 и ожидания уст. TWINT в "1";
2. на слэйв м32 мастер подает "START" (код $08), на слэйв м16 - "Повторный START" (код $10); при передаче на слэйв м16 зацикливается на этапе проверки соответствия кода $10 (нет соответствия);
3. на слэйв м32 мастер подает "Повторный START" (код $10), на слэйв м16 - "Повторный START" (код $10); при передаче на слэйв м16 зацикливается на этапе проверки соответствия кода $10 (нет соответствия);
4. на слэйв м32 мастер подает "Повторный START" (код $10), на слэйв м16 - "START" (код $08); при передаче на слэйв м16 зацикливается на этапе загрузки адреса м16 и ожидания уст. TWINT в "1".
Теперь наоборот: мастер сначала передает на слэйв м16, потом на слэйв м32.
Делал так:
1. на слэйв м16 мастер подает "START" (код $08), на слэйв м32 - "START" (код $08); нет передачи на слэйв м16 - зацикливается на этапе проверки соответствия кода $18 (нет соответствия);
2. на слэйв м16 мастер подает "START" (код $08), на слэйв м32 - "Повторный START" (код $10); нет передачи на слэйв м16 - зацикливается на этапе проверки соответствия кода $18 (нет соответствия);
3. на слэйв м16 мастер подает "Повторный START" (код $10), на слэйв м32 - "Повторный START" (код $10); есть передача на слэйв м16; при передаче на слэйв м32 зацикливается на этапе проверки соответствия кода $10 (нет соответствия);
4. на слэйв м16 мастер подает "Повторный START" (код $10), на слэйв м32 - "START" (код $08); есть передача на слэйв м16; при передаче на слэйв м32 зацикливается на этапе загрузки адреса м32 и ожидания уст. TWINT в "1".
То есть, если передается на один МК, то на второй уже не идет. При любых вариантах.
Может быть кто-нибудь наконец сжалится надо мной, и поделится правильным кодом на асме приема-передачи??? Как это все надо делать ПРАВИЛЬНО?
Помогите! F1! HELP!! SOS!!!
James D.ну за что ж Вы так шиты не любите. Я делал с полным анализом состояния регистра TWSR и выполнял все рекомендации согласно каждому состоянию - работает без глюков при такте 1мгц. По ссылке перевод шита меги128 . Удачи
http://gaw.ru/html.cgi/txt/doc/micros/avr/arh128/18_6.htm
James D.
Nov 20 2005, 15:25
Да есть у меня полный перевод м128 с этого сайта. Читал, конечно же читал.
Допустим, ситуация такая: вместо кода $18 получаем код $20. Согласно таблицы, что нужно сделать в этом случае? В TWCR записывается новое значение? Но какое из 4-х?
Там, например, говорится "Передается байт данных", да как же он может передаваться, если нет подтверждения адреса от слейва?
Елки-палки, ну ткните меня носом, что нужно делать в ошибочных ситуациях!!!
Цитата(James D. @ Nov 20 2005, 18:25)

Допустим, ситуация такая: вместо кода $18 получаем код $20. Согласно таблицы, что нужно сделать в этом случае? В TWCR записывается новое значение? Но какое из 4-х?
Там, например, говорится "Передается байт данных", да как же он может передаваться, если нет подтверждения адреса от слейва?
ну что тут непонятного - после передачи пакета SLA+W принято NACK . действия : выдать STOP затем по новой START/ SLA+W/ и таким образом дожидаться ACK. чтобы не зациклиться - организуй количество попыток и собственно в шите есть пример на асме
http://gaw.ru/html.cgi/txt/doc/micros/avr/arh128/18_5.htm
James D.
Nov 20 2005, 16:42
Но там вот что написано:
1. Пepeдaeтcя бaйт дaнныx, пpинимaется или нe пpинимaeтcя ПOДTBepждeниe
2. Пepeдaeтcя ПOBTOPHЫЙ CTAPT
3. Пepeдaeтcя услoвиe CTOП и cбpacывaeтcя флaг TWSTO
4. Bcлeд зa ycлoвием CTAPT пepeдaeтcя ycлoвиe CTOП и cбpacывaется флaг TWSTO
Это варианты ответных действий, или это одна процедура, которую надо выполнить?
Цитата(James D. @ Nov 20 2005, 19:42)

Но там вот что написано:
1. Пepeдaeтcя бaйт дaнныx, пpинимaется или нe пpинимaeтcя ПOДTBepждeниe
2. Пepeдaeтcя ПOBTOPHЫЙ CTAPT
3. Пepeдaeтcя услoвиe CTOП и cбpacывaeтcя флaг TWSTO
4. Bcлeд зa ycлoвием CTAPT пepeдaeтcя ycлoвиe CTOП и cбpacывaется флaг TWSTO
Это варианты ответных действий, или это одна процедура, которую надо выполнить?
в таблице даны
возможные варианты действий имхо первый пункт нуна выбросить тк он абсурден ну а далее исходя из алгоритма проги выбирается СТОП , ПОВСТАРТ, СТОП - СТАРТ , более доходчиво на рисунке 97 Форматы и состояния в режиме ведущего передатчика.
James D.
Nov 20 2005, 17:15
SLA_W: ldi temp,$04 ;Загрузка адреса слэйв м16 + "WRITE"
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
wait: in temp,TWCR ;Ожидаем ответа от слэйв м16
sbrs temp,TWINT
rjmp wait
У меня зацикливается в цикле ожидания "wait", шины SDA, SCL в состоянии "0".
Как тут быть?
а где старт и опрос состояния после оного?
James D.
Nov 20 2005, 17:33
Не, ну я кусок привел - где ошибка. А полностью вот:
To_m16: ldi temp,$03 ;Установка скорости передачи= ? kHz (поставил самую низкую, кварц на 4 MHz)
out TWSR,temp
ldi temp,$FF
out TWBR,temp
Pusk_Sq:ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR,temp ;Посылка сигнала "START"
wait1q: in temp,TWCR ;Ожидаем ответа от слэйв м16
sbrs temp,TWINT
rjmp wait1q
in temp,TWSR
andi temp,$F8
cpi temp,$08 ;Проверка подтверждения приема от слэйв м16
brne Pusk_Sq
SLA_Wq: ldi temp,$04 ;Загрузка адреса слэйв м16 + "WRITE"
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
wait2q: in temp,TWCR ;Ожидаем ответа от слэйв м16
sbrs temp,TWINT
rjmp wait2q
in temp,TWSR
andi temp,$F8
cpi temp,$18
brne SLA_Wq ;Переход, если ответ от слэйв м16 неверный
Далее идет прием данных. По идее...
пора уходить. приложил рабающий код для работы с ееprom может поможет
James D.
Nov 20 2005, 18:49
Не знаю насколько код работающий, пока не разобрался, но вот две ошибки:
ldi tempA,t5000
rcall l
Да и сложный у вас код, запутанный (как на первый взгляд), я пользуюсь такими п/п:
;************************************
;Подпрограмма чтения байта из EEPROM:
EEPROM_read:
sbic EECR,EEWE
rjmp EEPROM_read
out EEARH,temp1
out EEARL,temp2
sbi EECR,EERE
in data,EEDR
ret
;************************************
;************************************
;Подпрограмма записи байта в EEPROM:
EEPROM_write:
sbic EECR,EEWE
rjmp EEPROM_write
out EEARH,temp1
out EEARL,temp2
out EEDR,data
sbi EECR,EEMWE
sbi EECR,EEWE
ret
;*************************************
James D.
Nov 20 2005, 19:13
Кстати, приемник - слэйв м16 зацикливается здесь (выделено цветом):
ldi temp,$04 ;Инициализация режима "Приемник"
out TWAR,temp
TWINT_0:ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
out TWCR,temp
wait1: in temp,TWCR ;Ожидаем вызова от мастера м32
sbrs temp,TWINT
rjmp wait1
in temp,TWSR
andi temp,$F8
cpi temp,$60 ;Проверка принятого адреса от м32
brne TWINT_0
James D.
Nov 20 2005, 19:49
Если линии SDA и SCL в "0" состоянии, значит бит TWINT установлен. Судя по даташиту. А моя программа говорит, что он в "0" состоянии, при "0" на линиях SDA и SCL... Что за дела? Ничего не понимаю!
Цитата(James D. @ Nov 20 2005, 21:49)

Не знаю насколько код работающий, пока не разобрался, но вот две ошибки:
ldi tempA,t5000
rcall l
Да и сложный у вас код, запутанный (как на первый взгляд), я пользуюсь такими п/п:
я же писал что пп для eeprom . это зажержка 5мс между записью блоков.
и потом , зачем Вы приемник делаете ведущим?
James D.
Nov 21 2005, 10:31
Почему ведущим? Приемник у меня подчиненный.
Бит TWINT не надо сбрасывать? Написать так:
ldi temp,(1<<TWEA)|(1<<TWEN)
out TWCR,temp
именно
(1<<TWEA)|(1<<TWEN) - ведомый приемник
(1<<TWINT)|(1<<TWEA)|(1<<TWEN) - ведущий приемник
James D.
Nov 21 2005, 11:24
Понял, вечерком попробую с такой комбинацией.
Посмотрел даташит - "ведущий приемник" - там бит TWEA вообще не участвует.
START - (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
SLA+R - (1<<TWINT)|(1<<TWEN)
DATA - (1<<TWINT)|(1<<TWEN)
Вот дальше я не понял. Читаем:
"Данная последовательность повторяется до приема последнего байта. После этого ведущий приемник информирует подчиненный передатчик отправкой НЕТ ПОДТВерждения после приема последнего принятого байта данных."
Как мастер-приемник должен отправлять "НЕТ ПОДТВерждения после приема последнего принятого байта данных"?
Последняя команда:
STOP - (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
Цитата(James D. @ Nov 21 2005, 14:24)

Понял, вечерком попробую с такой комбинацией.
Посмотрел даташит - "ведущий приемник" - там бит TWEA вообще не участвует.
обшибся.конечно же TWSTA
Цитата
Как мастер-приемник должен отправлять "НЕТ ПОДТВерждения после приема последнего принятого байта данных"?
Последняя команда:
STOP - (1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
после приема последнего байта приемник должен выдать NACK- (1<<TWINT)|(1<<TWEN) а затем STOP
James D.
Nov 21 2005, 16:03
В приемнике убрал (1<<TWINT), оставил везде только (1<<TWEA)|(1<<TWEN).
Приемник стопорит на этапе приема байта данных - в TWSR код отличный от $80.
Передатчик, после посылки START (получен код $18), не может передать байт данных:
wait3: in temp,TWCR ;Ожидаем ответа от слэйв м32
sbrs temp,TWINT
rjmp wait3
бит TWINT не устанавливается.
Судя по всему, ошибка в мастере-передатчике, потому как он не может даже начать передачу.
Почему же TWINT не устанавливается?
ЗЫ. Но, если вернуть в код приемника код (1<<TWINT), то данные на слэйв м32 передаются нормально.
А вот на слэйв м16 данные не передаются в любом случае - если на него идет передача после м32.
А если сначала передавать на м16 - передается нормально, но потом нет передачи на м32...
Крыша едет.
вообще то если на шине нет ошибки (код F8) после передачи СТАРТ должен быть код 08 далее загрузить SLA+W и выдать (1<<TWINT) и если в этом случае получаем код 18 то выдаем данные и тд.
James D.
Nov 21 2005, 17:10
Дык я так и делаю (прога передатчика целиком):
ldi temp,$03 ;Установка скорости передачи= ? kHz
out TWSR,temp
ldi temp,$FF
out TWBR,temp
Pusk_Sq:ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR,temp ;Посылка сигнала "START"
wait1q: in temp,TWCR ;Ожидаем ответа от приемника
sbrs temp,TWINT
rjmp wait1q
in temp,TWSR
andi temp,$F8
cpi temp,$08 ;Проверка подтверждения приема от приемника (START)
brne Pusk_Sq
SLA_Wq: ldi temp,$04 ;Загрузка адреса приемника + "WRITE"
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
wait2q: in temp,TWCR ;Ожидаем ответа от приемника
sbrs temp,TWINT
rjmp wait2q
in temp,TWSR
andi temp,$F8
cpi temp,$18
brne SLA_Wq
;Начинаем передавать данные:
DATA_q: out TWDR,BYTE1 ;Отправка: байт данных 1
rcall Writeq
Pu_Menq:rjmp STOP_q ;Передача данных завершена
;*******************************************************************
Writeq: ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
wait3q: in temp,TWCR ;Ожидаем ответа от приемника
sbrs temp,TWINT
rjmp wait3q
in temp,TWSR
andi temp,$F8
cpi temp,$28
brne Writeq ;Переход, если ответ от приемника неверный
ret
;*******************************************************************
;Все данные переданы - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_q: ldi temp,(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)
out TWCR,temp
Inits: rjmp Inits
;***********************
Стопорит в цикле wait3q - ежели в проге приемника повыкидывать (1<<TWINT).
Цитата(James D. @ Nov 21 2005, 20:10)

Дык я так и делаю (прога передатчика целиком):
lSLA_Wq: ldi temp,$04 ;Загрузка адреса приемника + "WRITE"
out TWDR,temp
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
wait2q: in temp,TWCR ;Ожидаем ответа от приемника
sbrs temp,TWINT
rjmp wait2q
in temp,TWSR
andi temp,$F8
cpi temp,$18
brne SLA_Wq SLA не может повторно выдаваться только через стоп или повстарт
;Начинаем передавать данные:
DATA_q: out TWDR,BYTE1 ;Отправка: байт данных 1
rcall Writeq
Pu_Menq:rjmp STOP_q ;Передача данных завершена
;
Стопорит в цикле wait3q - ежели в проге приемника повыкидывать (1<<TWINT).
а что в приемнике? код в студию
James D.
Nov 21 2005, 18:04
Приемник:
ldi temp,$04 ;Инициализация режима "Приемник"
out TWAR,temp
TWINT_0:ldi temp,(1<<TWEA)|(1<<TWEN)
out TWCR,temp
wait1: in temp,TWCR ;Ожидаем вызова от передатчика
sbrs temp,TWINT
rjmp wait1
in temp,TWSR
andi temp,$F8
cpi temp,$60 ;Проверка принятого адреса от передатчика
brne TWINT_0
;Прием данных:
Pr_data:rcall TW_NT_1 ;Прием: байт данных
in temp,TWDR
rjmp STOP_1
;*******************************************************************
TW_NT_1:ldi temp,(1<<TWEA)|(1<<TWEN)
out TWCR,temp
wait21: in temp,TWCR ;Ожидаем ответа от передатчика
sbrs temp,TWINT
rjmp wait21
in temp,TWSR
andi temp,$F8
cpi temp,$80
brne TW_NT_1 ;Переход, если данные от передатчика не получены
ret
;*******************************************************************
;Все данные приняты - STOP (линия приема/передачи переходит в высокоимпедансное состояние)
STOP_1: ldi temp,(1<<TWEA)|(1<<TWEN)
out TWCR,temp
wait31: in temp,TWCR ;Ожидаем ответа от передатчика
sbrs temp,TWINT
rjmp wait31
in temp,TWSR
andi temp,$F8
cpi temp,$A0
brne STOP_1 ;Переход, если данные от передатчика не получены
Inits: rjmp Inits
Цитата(James D. @ Nov 21 2005, 21:04)

Приемник:
ldi temp,$04 ;Инициализация режима "Приемник"
out TWAR,temp вот и ошибочка : в 0-м разряде (TWGCE) сидит нолик что означает запрещение распознования общих вызовов на шине
а должно быть
ldi temp,$05 ;Инициализация режима "Приемник"
out TWAR,temp
дальше не смотрел, пора домой .удачи
совет дня закажи по почте книгу
http://www.dodeca.ru/books/me9.php не пожалеешь
James D.
Nov 21 2005, 20:18
Урра!!! Заработало!!!
Значит так:
1. в приемниках м32 и м16 оставил адреса $02 и $04 соответственно (без записи "1" в TWGCE).
2. в обоих приемниках пишется так:
ldi temp,(1<<TWINT)|(1<<TWEA)|(1<<TWEN)
out TWCR,temp
бит TWINT должен присутствовать, иначе просто не работает!
Ну и наконец, самое главное!
3. в приемнике м32, после команды STOP и получения кода $A0 пишем:
ldi temp,(1<<TWINT)|(1<<TWEN)
out TWCR,temp
Спасибо, m16, за твою подсказку: "после приема последнего байта приемник должен выдать NACK- (1<<TWINT)|(1<<TWEN) а затем STOP". Я решил применить это в моем случае.
Только я сначала даю STOP, а потом уже NACK.
Попробовал после приема последнего байта выдавать NACK (после команды STOP убрал) - тоже работает.
А теперь самое загадочное: убрал выдачу NACK везде в программах-приемниках - все равно работает. Но раньше-то не работало! Такое впечатление, как будто в контроллере после выдачи NACK сработала какая-то "защелка", которая наставила контроллер на путь истинный, и даже после удаления этой команды стало работать нормально. Но это мои домыслы.
Теперь попробуем новую задачу: после передачи на м32, потом на м16, надо принять данные с м16.
Ну как, одолеем?
James D.
Nov 22 2005, 12:58
М-да... Работать-то оно работает, но появились проблемы с записью в EEPROM - иногда (не всегда) при попытке что-либо записать в EEPROM все зависает.
Задержку пришлось поставить в мастере-передатчике:
Pusk_Sn:ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
out TWCR,temp ;Посылка сигнала "START"
wait1n: in temp,TWCR ;Ожидаем ответа от слэйв м32
sbrs temp,TWINT
rjmp wait1n
rcall Delay
.
.
.
Delay:push r20
push r21
push r22
ldi r20,$FF
ldi r21,$0F
ldi r22,$01
D_r_2: dec r20
brne D_r_2
ldi r20,$FF
dec r21
brne D_r_2
ldi r21,$FF
dec r22
brne D_r_2
pop r22
pop r21
pop r20
ret
по-другому работать не хочет!
Очень не нравится мне ента TWI. Капризная и нестабильная штука.
Добрый вечер!
Вот нужна какая помощь: Я передаю три байта как Master Transmitter , а вот четвёртый и пятый байты мне нужно принять как Master Receiver. После третьего байта только Acknowledge , а следующий такт уже я должен начать принимать данные. В регистре TWDR - последнее отосланное мной значение.
Ну не знаю я что делать. Помогите! Желательно на СИ!