среда, 16 июля 2014 г.

Последовательный интерфейс I2C. Часть 1. Описание.

Интерфейс I2C (I²C или TWI) был разработан компанией Philips для внутренней связи периферии в бытовой электронике. Для передачи данных и адресации используются всего два провода. При первом, беглом взгляде на структуру кадра и описание в Datasheet, кажется что интерфейс I2C очень сложен и сразу в структуре его кадра не разобраться. Также думал и я, когда впервые с ним познакомился, но в итоге полюбил работать с этим интерфейсом больше чем с SPI.
По сравнению с интерфейсом SPI, у I2C есть как плюсы:

  • более наглядная структура кадра
  • возможность отслеживания возникающих ошибок при приеме и передаче
  • возможность использования прерывания, при поступлении данных по шине I2C в то время, когда микроконтроллер находится в спящем режиме
  • для выбора устройства не требуется задействовать дополнительные выводы микроконтроллера
  • медленные устройства самостоятельно снижают скорость шины
так и минусы:
  • низкая скорость передачи данных, до 400 кбит/с (а если учесть еще, что сначала передается адрес устройства, то реальная скорость еще ниже)
  • ограничения по числу одинаковых адресуемых устройств (обычно производители периферии с шиной I2C оставляют 3 бита адреса устройства на выбор пользователя, а значит максимум можно использовать 8 одинаковых устройств)
К двухпроводной шине I2C все устройства подключаются параллельно и оба провода подтягиваются к шине питания. По линии SDA передаются данные, а по SCL осуществляется тактирование.



Рисунок 1 - Схема подключения подтягивающих резисторов и устройств к шине I2C

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

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

Сигналы управления:


Чтобы начать передачу, ведущее устройство (в нашем случае микроконтроллер) должен послать на шину I2C сигнал "START" - сначала низкий уровень устанавливается на линии SDA, а затем на линии SCL. Далее следует передача адреса и данных. По окончании передачи на шину посылается сигнал "STOP" - сначала высокий уровень устанавливается на шине SCL, а затем на шине SDA.



Рисунок 2 - Сигналы "START", "STOP"


Формат посылок:


Адрес и данные передаются пакетами по 8 бит. В пакете адреса 1 бит используется для информирования ведомого устройства, будем ли мы из него считывать (1) данные или же записывать (0).



Рисунок 3 - Пакеты адреса и данных

К каждому пакету добавляется еще один бит - подтверждение (ACK) или не подтверждение (NACK). При передачи адреса, а также записи данных, этот бит передает ведомое устройство. При чтении - ведущее (микроконтроллер).

Далее представлены режимы работы Master Write и Master Read:


Рисунок 4 - режим Master Write

В режиме Master Write микроконтроллер после после команды "START" передает адрес устройства, в которое хочет записать данные (устанавливая бит чтения/записи в 0). Если на шине присутствует устройство с таким адресом, то оно посылает ответ "ACK", и далее следует пересылка данных от ведущего устройства. Если устройства с таким адресом нет, то передача заканчивается. После окончания передачи данных ведущее устройство посылает в шину команду "STOP".



Рисунок 5 - режим Master Read

В режиме Master Read микроконтроллер после после команды "START" передает адрес устройства, из которого хочет считать данные (устанавливая бит чтения/записи в 1). Если на шине присутствует устройство с таким адресом, то оно посылает ответ "ACK", и далее следует пересылка данных от ведомого устройства, которая подтверждается ведущим устройством. После принятия последнего байта данных от ведомого устройства, ведущее посылает ответ "NACK" Если устройства с таким адресом нет, то передача заканчивается. После окончания передачи данных ведущее устройство посылает в шину команду "STOP".

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