Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: I2C в AVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
777777
Имеется система состоящая из Master receiver и Slave transmitter. Есл исходить из стандарта I2C, т количество передаваемых байт определяется мастером: при получении последнего байта он ставит NOT ACK, а передатчик получив его останавливает передачу. Мне же нужно чтобы количество передаваемых байт определялось передатчиком. С одной стороны, у него нет средств чтобы по своей инициативе остановить передачу - такты выдаются мастером. Но в описании Status Codes for Slave Transmitter Mode написано, что ведомый с передачей последнего байта может не установить TWEA и это будет означать, что передается последний байт. И есть status code 0xC8 означающий, что "Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received". Так значит он может каким-то образом остановить передачу по своей инициативе? И как это происходит аппаратно, т.е. что выдается на шину?
rezident
Цитата(777777 @ May 27 2010, 11:54) *
Так значит он может каким-то образом остановить передачу по своей инициативе? И как это происходит аппаратно, т.е. что выдается на шину?
Остановить? Точно также как и master - выдачей NAK. Как это аппаратно в МК реализуется я не знаю - не знаток AVR. laughing.gif
777777
Цитата(rezident @ May 27 2010, 21:16) *
Остановить? Точно также как и master - выдачей NAK. Как это аппаратно в МК реализуется я не знаю - не знаток AVR. laughing.gif

NAK выдает получатель данных. В данном случае это мастер. А мне надо, чтобы передача прекращалась по инициативе передатчика - при каждой передаче количество данных может быть разным и это количество знает только передатчик. Получается, что есть только один способ - сделать его мастером. Но он не знает когда начинать передачу - об этом знает получатель. И мы пришли к противоречию ©
Kane
Попробуйте ввести "команду", по которой слейвом будет выдаваться количество байт на передачу. Мастер сначала запрашивает сколько может передать слейв. После чего считывает, полученное на предыдущем этапе, нужное количество байт.
Сергей Борщ
Цитата(Kane @ May 28 2010, 09:48) *
Мастер сначала запрашивает сколько может передать слейв. После чего считывает, полученное на предыдущем этапе, нужное количество байт.
Или слейв первым байтом передает количество байтов в посылке. Некоторая неувязка будет с 0 - мастеру придется все же считать еще один байт, чтобы выдать NAСK.
rezident
Цитата(777777 @ May 28 2010, 11:10) *
NAK выдает получатель данных. В данном случае это мастер. А мне надо, чтобы передача прекращалась по инициативе передатчика
Пардон. Не полностью вник в смысл вопроса. Штатными средствами не получается. Обычно в таких случаях (в EEPROM, например) slave передает некоторый объем данных из кольцевого буфера, размер которого master должен знать заранее.
ILYAUL
Ваш slave работает в режиме "Ведомый передатчик" и может передавать данные сколько ему угодно. При передачи последнего байта , не забудьте сбросить бит TWEA , после чего передачик "впадёт" в состояние $C0 "думая" , что сейчас он получит NA , но получит естественно ACK , после чего уже и перейдёт в состояние С8 и будет гнать на шину SDA FFаки. Т.е сам то он остановится.
Мастер в регистре TWSR будет иметь скорее всего код 50 , т.е будет продолжать приём байтов. Можно попробывать отловить "неожиданный" пакет FF и сбросить мастер . Cам slave правильно остановить обмен не сможет , но он может "засадить" ,программно , шину SCL в 0 , после чего уже мастер не получив нормальный код ответа прекратит передачу. Не правильно это, но попробывать можно.
777777
Как мило, оказывается модераторы перенесли тему в "интерфейсы"! А то, что она называется I2C в AVR - это ничего? И вопрос был именно о коде состояния "Last data byte in TWDR has been transmitted", имеющейся только в AVR? И, конечно, в раздел для начинающих - после того, как она сутки провисела в разделе AVR и на нее пришел только один ответ - да, значит только начинающие могут рассказать о тонкостях в кодах состояния контроллера I2C!

Цитата(ILYAUL @ May 29 2010, 01:32) *
Ваш slave работает в режиме "Ведомый передатчик" и может передавать данные сколько ему угодно. При передачи последнего байта , не забудьте сбросить бит TWEA , после чего передачик "впадёт" в состояние $C0 "думая" , что сейчас он получит NA , но получит естественно ACK , после чего уже и перейдёт в состояние С8 и будет гнать на шину SDA FFаки. Т.е сам то он остановится.

Спасибо, я тоже наконец прочитал. smile.gif Сам он остановится, но мастер об этом не узнает. То есть сбрасывает TWEA он для самого себя.

Я решил изменить протокол - первым байтом всегда передается длина, а приемник, получив первый байт, сразу узнает сколько байт придет. Немного через задницу, но зато можно обойтись без отдельного запроса длины, как предлагал Kane

Цитата(ILYAUL @ May 29 2010, 01:32) *
Мастер в регистре TWSR будет иметь скорее всего код 50 , т.е будет продолжать приём байтов. Можно попробывать отловить "неожиданный" пакет FF и сбросить мастер.

А вдруг FF будет среди байтов данных?
Цитата(ILYAUL @ May 29 2010, 01:32) *
Cам slave правильно остановить обмен не сможет , но он может "засадить" ,программно , шину SCL в 0 , после чего уже мастер не получив нормальный код ответа прекратит передачу. Не правильно это, но попробывать можно.

Не получится, если засадить SCL в 0, то мастер остановится и будет ждать пока он не освободится, и ждать будет до бесконечности. Slave использует это для задержки передачи данных если они еще не готовы.
ILYAUL
Цитата
А вдруг FF будет среди байтов данных?

Я думал о нескольких подряд FF , но если такое возможно в получаемых данных , то не прокатит
ReAl
Цитата(777777 @ May 28 2010, 08:10) *
А мне надо, чтобы передача прекращалась по инициативе передатчика - при каждой передаче количество данных может быть разным и это количество знает только передатчик. Получается, что есть только один способ - сделать его мастером. Но он не знает когда начинать передачу - об этом знает получатель. И мы пришли к противоречию ©
Почему к противоречию? К противоречию придём только тогда, когда окажется, что источник данных невозможно сделать мастером.
А сейчас есть только то, к чему я склоняюсь в последнее время -- сделать всех "с мозгами" мастерами, превратить для них шину во write-only, они ничего не читают, только пишут. Нужно "нынешнему мастеру" что-то -- он посылает "нынешнему слейву" короткую команду "хочу то-то" и уходит с шины. "Нынешний слейв" переключается в мастера и отправляет известное ему количество информации тому, кто попросил. По загрузке шины практически то же - вместо передачи RESTART + SLA_R имеем передачу STOP+START+SLA_W

Кстати, уходит и обсуждаемая рядом тема растяжки SCL ещё не готовым "нынешним слейвом" - шина свободна, он передаст когда сможет.
Write-only шины -- правильная вещь в некоторых случаях.
ILYAUL
Цитата
Нужно "нынешнему мастеру" что-то -- он посылает "нынешнему слейву" короткую команду "хочу то-то" и уходит с шины

1. Это короткое будет START SLA+W и дальше "Я Х О Ч У Э Т О" , слейв всё таки должен как -то в потоке данных расшифровывать , когда данные , а когда "ХОЧУ" т.е он должен анализировать каждый принимаемый байт и определять к данным или "ХОЧУ" он относится. Т.е на анализ уйдёт кучка времени.
2. Он ещё как-то должен выяснить , а кому собственно послать то?
Значит , либо мастер передаёт свой SLA , либо став мастером "бывший" слейв начинает выяснять , кто хотел данные , ау!
777777
Цитата(ReAl @ May 30 2010, 00:53) *
Почему к противоречию? К противоречию придём только тогда, когда окажется, что источник данных невозможно сделать мастером.
А сейчас есть только то, к чему я склоняюсь в последнее время -- сделать всех "с мозгами" мастерами, превратить для них шину во write-only, они ничего не читают, только пишут. Нужно "нынешнему мастеру" что-то -- он посылает "нынешнему слейву" короткую команду "хочу то-то" и уходит с шины. "Нынешний слейв" переключается в мастера и отправляет известное ему количество информации тому, кто попросил. По загрузке шины практически то же - вместо передачи RESTART + SLA_R имеем передачу STOP+START+SLA_W

Да, я тоже думал сделать так. Но... страшно smile.gif

Цитата(ILYAUL @ May 30 2010, 01:47) *
1. Это короткое будет START SLA+W и дальше "Я Х О Ч У Э Т О" , слейв всё таки должен как -то в потоке данных расшифровывать , когда данные , а когда "ХОЧУ" т.е он должен анализировать каждый принимаемый байт и определять к данным или "ХОЧУ" он относится. Т.е на анализ уйдёт кучка времени.
2. Он ещё как-то должен выяснить , а кому собственно послать то?
Значит , либо мастер передаёт свой SLA , либо став мастером "бывший" слейв начинает выяснять , кто хотел данные , ау!

Почему каждый? Можно сделать первый байт командным и в нем кодировать "что хочу" и "кто хочет". Кроме того, можно сделать чтобы контроллер отвечал на несколько адресов, для этого в регистр TWAMR записывается битовая маска, показывающая, какие биты будут игнорироваться при сравнении с приходящим адресом. Например, если записать 0x1e, то он будет отвечать на 16 адресов, а младшие 4 бита могут быть любыми. Их можно использовать для передачи адреса запрашивающего устройства ("кто хочет").
ReAl
Цитата(777777 @ May 30 2010, 07:33) *
Да, я тоже думал сделать так. Но... страшно smile.gif
Пока у меня I2C "было мало", я об этом и не задумывался. Но сейчас висит на основном процессоре десяток слейвов и уже прото неприлично выглядит выдача команд а потом опрос по кругу -- кто же готов, чтобы из него вынуть информацию и пнуть дальше. Шина постоянно занята тупым опросом. Сейчас уже доделаю как есть, оно должно работать, а потом переделаю на мультимастер и сравню ощущения.
Будет время, почитаю (до этого только проглядывал) спецификации ACCESS.bus. Хотя там, пожалуй, несколько перенавороченные протоколы ввид универсальности шины.

Цитата(777777 @ May 30 2010, 07:33) *
Почему каждый? Можно сделать первый байт командным и в нем кодировать "что хочу" и "кто хочет".
Именно так.
Кстати, в заменителе системы с одним мастером _не_нужно_ выяснять -- кому же понадобились данные. Они понадобились "бывшему единственному мастеру" и его адрес может быть жёстко выделен на этапе проектирования системы. У меня при переделке так и будет -- пульт реально один.
А так -- нет никаих проблем в формате данных в пакетах с комадой "дай" завести поля "вот-это" и "вон-тому", причём "вон-тому" может и не совпадать с адресом того, кто выдал саму команду.
rezident
777777, почитайте спецификацию ACCESS.bus. Может чем-то вам поможет.
ILYAUL
Цитата
Но сейчас висит на основном процессоре десяток слейвов и уже прото неприлично выглядит выдача команд а потом опрос по кругу -- кто же готов, чтобы из него вынуть информацию и пнуть дальше. Шина постоянно занята тупым опросом.

Какая-то ситуация не совсем логичная для I2C. Не понимаю , что мешает слейву , который готов отдать данные , назначить cебя мастером , захватить шину и передать данные. Пусть у Вас все будут слейвами , до тех пор пока они не готовы выдать информацию для остальных или основному процессору. Любое устройство ,с "мозгами", может быть мастером и слейвом и в зависимости от Вашей программы может работать в этих двух режимах.
А если Ваш слейв , от которого требует мастер данные , просто не готов их ему дать laughing.gif , занят он чем то другим? Причём может быть более важным maniac.gif , чем общение с мастером. Мастер при этом вместо того что бы выполнять свою работу тупо ждёт получение данных от этого слейва smile3046.gif , когда , например, остальные уже готовы дать ему информацию и продолжить свою работу.

Цитата
А так -- нет никаих проблем в формате данных в пакетах с комадой "дай" завести поля "вот-это" и "вон-тому", причём "вон-тому" может и не совпадать с адресом того, кто выдал саму команду

Вы посчитайте этот формат. И при этом посчитайте , что слейв должен отличать на шине команду ("дай" "вот-это" и "вон-тому" ) от просто данных , которые ему может посылать мастер. Поэтому нужен ещё и префикс , что идёт команда , а не данные. А в диапазоне 8 бит , очень сложно ( а практически невозможно) найти свободное число для префикса команды, т.к. любое число в одном байте можно интерпретировать как данные и как команду. Поэтому потребуется не один байт , а несколько , которые слейв "сложит" в понимание , что получает команду. И тут время опять удлиняется, слейв должен "расшифровать" , что он получает.
rezident
Цитата(ILYAUL @ May 31 2010, 12:48) *
Поэтому потребуется не один байт , а несколько , которые слейв "сложит" в понимание , что получает команду.
Если слейвы имеют программную, а не аппаратную реализацию, то можно признак команда/данные поместить в самый первый байт "аппаратной" адресации. Рядышком с битом R/W, например.
ReAl
Цитата(ILYAUL @ May 31 2010, 09:48) *
Какая-то ситуация не совсем логичная для I2C. Не понимаю , что мешает слейву , который готов отдать данные , назначить cебя мастером , захватить шину и передать данные.
...
Вы посчитайте этот формат. И при этом посчитайте , что слейв должен отличать на шине команду ("дай" "вот-это" и "вон-тому" ) от просто данных , которые ему может посылать мастер.
"Какое-то не совсем логичное" с Вами общение. Когда я говорю, что при наличии информации "бывший слейв" должен переключиться в мастера и передать, шина должна быть по сути write-only -- Вы мне объясняете, что тут возникают нюансы с форматами, что-то от чего-то отличать надо, разбираться с тем, кому и что передавать (так вроде бы я говорил, что это не нужно - у меня и сейчас слейвы принимают десяток команд с разными данными для них и пяток команд на формирование данных от них).
А когда я говорю, что то, что сделано сейчас (полчилось в результате развития простой системы) мне надоело и я это собираюсь передалать на мультимастер -- вы пропускаете, что я собираюсь это делать и начинаете мне рассказывать, что слейв должен переключиться в мастера -- т.е. то, с чего я и начал в этой теме.
ILYAUL
Цитата(ReAl @ Jun 1 2010, 01:33) *
"Какое-то не совсем логичное" с Вами общение....
А сейчас есть только то, к чему я склоняюсь в последнее время -- сделать всех "с мозгами" мастерами, превратить для них шину во write-only.

Да, нет . Именно это мы и обсуждаем. Может не совсем понимаем друг друга. Я например не могу понять Вашу идею - мультимастер (всех "с мозгами" мастерами), какой от этого существенный выигрыш? Вот , какие Вы видите (+) от такой организации шины?
Поэтому и придерживаюсь , той точки зрения , что все слейвы и только при необходимости они становиться мастерами.
Вот Вы пишите:
Цитата
Кстати, в заменителе системы с одним мастером _не_нужно_ выяснять -- кому же понадобились данные. Они понадобились "бывшему единственному мастеру" и его адрес может быть жёстко выделен на этапе проектирования системы. У меня при переделке так и будет -- пульт реально один.

Т.е всё таки все данные собранные слейвами/мастерами в итоге предназначены только одному мастеру?

P.S И уточните , плиз, у Вас программная или аппаратная реализация, тогда и по форматам вопросов не будет.
ReAl
Цитата(ILYAUL @ Jun 1 2010, 11:05) *
Я например не могу понять Вашу идею - мультимастер (всех "с мозгами" мастерами), какой от этого существенный выигрыш? Вот , какие Вы видите (+) от такой организации шины?
Поэтому и придерживаюсь , той точки зрения , что все слейвы и только при необходимости они становиться мастерами.
Ну да. Если на шине несколько точек "при необходимости становятся мастерами" - то мастеров уже несколько. Если повезёт - в разные моменты времени, если нет -- два "бывших слейва" (в смысле "бывших исключительно слейва") могут достаточно одновремённо перейти в состояние "готовы данные" и полезть на шину мастерами или "бывший единственный мастер" может кому-то что-то захотеть сказать тогда, когда кто-то (в том числе и тот, кому мастер решил сказать) оказался готов передавать данные. И всё, имеем полное использование мультимастерного режима I2C с невозможностью доступа к шине, так как она в данный момент занята либо одновремённый выход на шину и арбитраж.

Поэтому и не могу понять, как это -- "не мультимастер, а все слейвы и только при необходимости они становиться мастерами".
Реализовывать поверх I2C передачу маркера с гарантированно единственным мастером на шине в каждой фазе функицонирования системы, как это делают иногда на RS485 и тем уйти от возможных конфликтов на шине? А зачем, если есть нормальный I2C-шный режим мультимастера?

В пульт (в любого, кто раньше был "мастером-читателем") добавляется режим слейва для приёма затребованных данных, в слейвов добавляется режим мастера для передачи этих дынных. С точки зрения обработчика контроллера I2C (TWI) они становятя одинаковые, слейвы получают право подать голос. По логике работы системы они всё равно остаются подчинёнными устройствами.
Никто не мешает при этом на шине иметь "чистых слейвов" вида RTC, EEPROM, к которым все, кому это нужно, обращаются в классическом режиме. А всё своё (== "всё с мозгами") переделать.

Цитата(ILYAUL @ Jun 1 2010, 11:05) *
Т.е всё таки все данные собранные слейвами/мастерами в итоге предназначены только одному мастеру?
И у меня, и, как я понимаю, у автора темы - именно так. Мастер один. Собственно, весь мой разговор - о переделке системы с одним мастером в систему с несколькими мастерами (мультимастер) для ухода от постоянного опроса готовности и инициативной передачи затребованных ранее данных.

Цитата(ILYAUL @ Jun 1 2010, 11:05) *
P.S И уточните , плиз, у Вас программная или аппаратная реализация, тогда и по форматам вопросов не будет.
Если я в принципе могу переделать хотя бы часть "бывших слейвов" в мастера -- то какая разница, переделаю я ASM, C или verilog (до asic-ов не дорос)? Часы и 24с64 не могу, "бывший единственны мастер" будет к ним обращаться как и раньше, а дюжина mega48 будут переделаны, как и пульт на mega328.
defunct
ReAl:

А Вы учитываете, что в Multimaster придется разгребать еще коллизии? Это на бумаге кажется, что есть только один пульт. А в реале есть "n" мастеров и все они потенциально могут одновременно начать транзкцию. А в таком свете не факт, что тупой опрос будет хуже, даже с учетом аппаратного conflict avoidance для on-going транзакции, т.к. обработка коллизий на разных девайсах должна будет происходить по-разному.

На мой взгляд куда более выгодно держать слейвы всегда на подхвате, т.е. чтобы на любой запрос мастера уже заранее был подготовлен ответ, чтобы исключить тормоза и затягивания SCL.

Вопрос о длине данных от слейва, (когда мастеру прекращать прием по требованию слейва) это помоему мелочь. Как мимимум два простых варианта реализации:
1. Байт-терминатор.
2. Байт длины сообщения.
есть еще и третий вариант 7-бит кодировка и бит-терминатор.
ASDFG123
Подскажите по I2C интерфейсу в атмега 16, Нужно сделать слейв. Получаем запрос с адресом от мастера, в ответ отправляем данные. Взял аппноут AVR311 как его довести до работоспособности?
Не понятен момент как слейв узнает что ему пришел SLA-R
в main.c строчка #define TWI_CMD_MASTER_READ 0x20 что она означает ? это 0010 0000 но SLA-R это ведь 1 и 7битов адресов
и почему функция чтения того что пришло слейву, состоит из 2 массивов ?
TWI_Get_Data_From_Transceiver(messageBuf, 2);

что нужно дописать (вырезать) что бы использовать эту библиотеку ?
IF_P
Цитата(ASDFG123 @ Jun 22 2013, 20:48) *
Подскажите по I2C интерфейсу в атмега 16, Нужно сделать слейв. Получаем запрос с адресом от мастера, в ответ отправляем данные. Взял аппноут AVR311 как его довести до работоспособности?
Не понятен момент как слейв узнает что ему пришел SLA-R
в main.c строчка #define TWI_CMD_MASTER_READ 0x20 что она означает ? это 0010 0000 но SLA-R это ведь 1 и 7битов адресов
и почему функция чтения того что пришло слейву, состоит из 2 массивов ?
TWI_Get_Data_From_Transceiver(messageBuf, 2);

что нужно дописать (вырезать) что бы использовать эту библиотеку ?

Это написано для связки Master (AVR315) - Slave (AVR311). Команда TWI_CMD_MASTER_READ 0x20 поступает от Master'а. Slave только отвечает на нее.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.