Учебный курс 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 состоит из следующих шагов:

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

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

Comments   

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

Подскажите, я правильно понял что в tiny и mega аппаратно это реализовано немного по разному?
# _Артём_ 2013-12-24 15:52
tiny они разные бывают...
Но скорее всего по-другому сделано.
# Pashgan 2013-12-25 14:51
Не могу сказать за все attiny, но в тех, которые мне приходится использовать, I2C реализуется с помощью универсального модуля USI. Поэтому да, по разному.
# Flint 2015-02-28 17:44
А можно узнать насколько большая разница? Сейчас читаю описание на русском (на англи2йском будет труднее), но про TWI, который упоминается в мегах, но хочу использовать в attiny2313 USI. Насколько принципиально различие, логика работы
# Иван Герасимов 2014-06-21 22:19
Скажите пожалуйста, может быть глупый вопрос, конечно, во время передачи данных основной код программы продолжает выполняться?
# FreshMan 2014-08-18 13:32
нет
# Kodex 2014-08-26 15:06
Эй эй, вы что... Для каких целей тогда Atmel в чип аппаратный модуль TWI засунули?
Если код прерывания выполняется, естественно, основной код не будет выполнятся. А передача в любом случае будет идти, хотя и код выполняется...
# Али 2015-05-24 21:17
Здравствуйте! Я программирую МК ATmega16A на СИ. Семисегментные индикаторы управляется через I2C на микросхемах FCА8574AT. Я в этом области новичок, помогите с этим пожалуйста!!!
# Иван Ив 2015-07-07 10:32
добрый день,есть проблема общаются между собой AT91SAM7X512 и ATTINY2313 по TWI связь =постоянно обрывается между ними в чем может быть проблема находятся они на разных платах и питание у них у каждого свое по 3.3 вольта ,ATTINY должен выводить состояние на жк дисплей которое посылает AT91SAM7X512. В чем может быть проблема,может кто подскажет)
# бухомуха 2015-12-19 12:47
Господа хорошие, вы все такие умные! Научите меня!

У вас недостаточно прав для комментирования.