Учебный курс AVR. Использования TWI модуля. Основы I2C. Ч1

24/10/2013 - 12:25 Павел Бобков

Введение

В составе некоторых микроконтроллеров AVR есть модуль двухпроводного последовательного интерфейса (Two -wire Serial Interface или TWI). Модуль предназначен для организации обмена данными между микросхемами, подключенными к двухпроводной шине. Основное преимущество этого интерфейса перед SPI и UART`ом - это возможность организации сети из нескольких устройств.

Двухпроводный интерфейс является аналогом I2C интерфейса фирмы Philips, только в случае AVR, не поддерживает высокие скорости передачи данных (свыше 400 kbit/s). Соображения, по которым Atmel использует другое названия, видимо связано с нежеланием платить Philips за лицензию.

В этом материале мы разберемся с основами двухпроводного последовательного интерфейса, а в следующих перейдем к работе с TWI модулем AVR.

Далее я буду опираться на даташит atmega16 и спецификацию I2C.

Подключение устройств к I2C шине

I2C шина представляет собой две двунаправленные линии связи - SDA (Serial Data Line) и SCL (Serial Clock Line). По SDA передаются данные, по SCL тактовый сигнал. Обе линии подтянуты через резисторы к плюсу питания.

Устройства на шине подразделяются на ведущих (master) и ведомых (slave). Ведущие запускают и завершают передачу данных, ведомые - отвечают на запросы. Одни - начальники, другие - подчиненные. Микроконтроллеры могут совмещать в себе обе эти функции.

Выходные каскады устройств, поддерживающих I2C, выполнены как структуры с открытым коллектором/стоком. При подключении к шине, они образуют схему монтажного "И". Это значит, что любое устройство, установившее низкий логический уровень на линии шины, "проваливает" высокий уровень остальных устройств. 


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


Существует механизм распределения приоритетов между ведущими, если они начинают передачу данных одновременно. Он заключается в том, что ведущие устанавливают на шине данные и проверяют результат. Если он отличается от ожидаемого, устройство теряет приоритет и останавливает передачу данных.

Передача данных по I2C

Данные передаются поразрядно (спасибо кэп!), старшим разрядом вперед. Каждый разряд сопровождается тактовым сигналом.


Начало и окончание передачи данных сопровождается специальными состояниями шины - СТАРТ и СТОП. Эти состояния формирует ведущее устройство. Также ведущий может сформировать состояние повторного старта до формирования состояния СТОП. 


Данные передаются по I2C шине со служебной информацией. Все вместе это называется пакетом. Существуют адресные пакеты и пакеты данных. Адресные пакеты состоят из 7-и разрядного адреса, управляющего бита R/W и бита квитирования (весь пакет - 9 бит). Адресный пакет нужен, чтобы обратиться к конкретному устройству. 


R/W - определяет последующее направление передачи данных. Бит квитирования - это ответ ведомого устройства на принятый адрес. Если адрес распознан, ведомый выдает на линию SDA низкий уровень. В противном случае на линии удерживается высокий уровень.

Под адрес отведено 7 разрядов, что как бы намекает на возможность адресации 128 устройств, но это не совсем так. Во-первых существует ряд служебных адресов, например, 0000000 - это адрес общего вызова (обращение ко всем ведомым устройствам). Во-вторых есть режим 10-и разрядной адресации, когда адрес передается двумя пакетами. Не буду углубляться в эту тему, только скажу, что адреса из диапазона 1111000...1111111 не рекомендуется использовать в TWI модуле AVR (курим даташит).

Пакеты данных состоят из байта данных и бита квитирования, то есть тоже имеют длину 9 бит. После приема каждого байта данных, принимающее устройство (приемник) отвечает передающему устройству (передатчику), устанавливая на линии SDА низкий уровень (это и есть бит квитирования). Если принимающее устройство получило последний байт или больше не может продолжать прием данных, оно должно "оставить" на линии SDA высокий уровень. 


В общем случае, полный цикл обмена по I2C состоит из следующих шагов:

- формирование состояния СТАРТ,
- передача адресного пакета,
- передача пакетов данных,
- прием пакетов данных,
- формирование состояния СТОП.

На этом все. Продолжение следует..

Комментарии   

# foxit 25.10.2013 11:03
Спасибо.
Будут ли примеры с DS1307 и 24LCxx?
Ответить | Ответить с цитатой | Цитировать
# FreshMan 26.10.2013 06:28
Цитата:
Если принимающее устройство получило последний байт или больше не может продолжать прием данных, оно должно "оставить" на линии SDA высокий уровень.
для меня сдесь есть маленькая неясность...., допустим мастер передал пакет данных но АСК от слейва не пришол, как тут быть ? надо опять передавать пакет данных до тех пор пока слейв не услышит ?
Ответить | Ответить с цитатой | Цитировать
# Pashgan 26.10.2013 10:20
Можно остановить передачу, а потом снова повторить ее сначала. Можно сформировать состояние "повторный старт" и снова попытаться передать данных.
Ответить | Ответить с цитатой | Цитировать
# FreshMan 26.10.2013 13:04
тоесть просто передавать данные слейву до тех пор пока он меня не услышит нельзя ? надо сначала сделать стоп, потом старт, а потом опять передеть данные ....., так ?
Ответить | Ответить с цитатой | Цитировать
# Pashgan 26.10.2013 14:43
Да. Смотрим спецификацию на I2C:
"...если мастер не получает сигнал подтверждения, он может сформировать состояние СТОП или повторить состояние СТАРТ, чтобы начать новую передачу. Есть пять условий, приводящих к ответу NACK:
1. На шине нет устройства с требуемым адресом.
2. Приемник не может принять или передать данные, так как занят.
3. Во время передачи приемник получил данные, которые не понимает.
4. Во время передачи приемник не может получить данных больше, чем уже есть.
5. Мастер, принимающий данные, сигнализирует об окончании передачи ведомому."
Ответить | Ответить с цитатой | Цитировать
# JoJo 27.10.2013 12:05
Долгожданная I2C :-)
Ответить | Ответить с цитатой | Цитировать
# Иван 28.10.2013 20:48
Теперь можно помучить акселерометр что-то долго ждет на полке :roll:
Ответить | Ответить с цитатой | Цитировать
# Cthulhu 24.12.2013 11:33
Спасибо за статью про I2C

Подскажите, я правильно понял что в tiny и mega аппаратно это реализовано немного по разному?
Ответить | Ответить с цитатой | Цитировать
# _Артём_ 24.12.2013 15:52
tiny они разные бывают...
Но скорее всего по-другому сделано.
Ответить | Ответить с цитатой | Цитировать
# Pashgan 25.12.2013 14:51
Не могу сказать за все attiny, но в тех, которые мне приходится использовать, I2C реализуется с помощью универсального модуля USI. Поэтому да, по разному.
Ответить | Ответить с цитатой | Цитировать
# Flint 28.02.2015 17:44
А можно узнать насколько большая разница? Сейчас читаю описание на русском (на англи2йском будет труднее), но про TWI, который упоминается в мегах, но хочу использовать в attiny2313 USI. Насколько принципиально различие, логика работы
Ответить | Ответить с цитатой | Цитировать
# Иван Герасимов 21.06.2014 22:19
Скажите пожалуйста, может быть глупый вопрос, конечно, во время передачи данных основной код программы продолжает выполняться?
Ответить | Ответить с цитатой | Цитировать
# Kodex 26.08.2014 15:06
Эй эй, вы что... Для каких целей тогда Atmel в чип аппаратный модуль TWI засунули?
Если код прерывания выполняется, естественно, основной код не будет выполнятся. А передача в любом случае будет идти, хотя и код выполняется...
Ответить | Ответить с цитатой | Цитировать
# Али 24.05.2015 21:17
Здравствуйте! Я программирую МК ATmega16A на СИ. Семисегментные индикаторы управляется через I2C на микросхемах FCА8574AT. Я в этом области новичок, помогите с этим пожалуйста!!!
Ответить | Ответить с цитатой | Цитировать
# Иван Ив 07.07.2015 10:32
добрый день,есть проблема общаются между собой AT91SAM7X512 и ATTINY2313 по TWI связь =постоянно обрывается между ними в чем может быть проблема находятся они на разных платах и питание у них у каждого свое по 3.3 вольта ,ATTINY должен выводить состояние на жк дисплей которое посылает AT91SAM7X512. В чем может быть проблема,может кто подскажет)
Ответить | Ответить с цитатой | Цитировать
# бухомуха 19.12.2015 12:47
Господа хорошие, вы все такие умные! Научите меня!
Ответить | Ответить с цитатой | Цитировать

Добавить комментарий

Защитный код
Обновить