STM32 Интерфейс I2C. Описание

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

Где может пригодиться шина I2C? Во-первых, существует ряд микросхем, которые управляются по этой шине. Из наиболее часто используемых в любительских устройствах это: датчики температуры, EEPROM-память. Во-вторых, можно объединить несколько контроллеров  или сделать некоторые автономные модули, каждый из которых выполняет определенную задачу, и объединить их в одну систему.

В этой статье не будет описания самого интерфейса. На просторах интернета достаточно много информации об этом (мне понравилось описание, приведенное здесь).

Какими же возможностями работы с интерфейсом I2C наделили свое детище разработчики  микроконтроллеров STM32 ?

Модуль I2C контроллера может работать в режиме мастера и в режиме ведомого. Имеется возможность работать в режиме стандартной скорости (до 100 кБит/сек) и повышенной скорости (до 400 кБит/сек).

Поддерживает два режима адресации – семи битный и десяти битный.

Также предусмотрены всякие-разные флаги, которые позволяют контролировать состояние шины, ошибки, и конечно прерывания и использование  ДМА.

Также предусмотрен  аппаратный подсчет CRC, что можно использовать для контроля правильности передачи данных.

Обзор регистров

Регистр данных DR  содержит принятый байт данных и в него загружаем передаваемый байт данных.

Регистр OAR1 содержит адрес, на который будет откликаться устройство в режиме ведомого. Регистр позволяет работать с 7 и 10 разрядными адресами.

image

Разряд ADDMODE осуществляет выбор режима адресации: 0 – семиразрядный режим, 1 – десятиразрядный режим. При семиразрядном режиме адрес нужно загружать в разряды 1..7

Для семиразрядной адресации имеется возможность задать два адреса, на которые будет откликаться устройство. Для выбора этого режима и задания второго адреса предназначен регистр OAR2.

image

Разряды 1..7 содержат второй адрес. Разряд ENDUAL включает(1)/выключает(0) режим двойной адресации.

Дальше немного сложнее – регистры управления. Их два – CR1 и CR2. CR1 имеет такую структуру:

image

PE – включение(1)/выключение(0) модуля. При включении модуля выводы, которые будут задействованы, конфигурируются как выводы альтернативной ф-ии.

SMBUS, SMBTYPE, ENARP и ALERT предназначены для работы в режиме SMBus. Если данный режим не используется,  можно записать в них нули и не обращать на эти разряды внимания.

ENPEC – включает(1)/выключает(0) подсчет аппаратный CRC.

ENGC — включает(1)/выключает(0) реагирование на широковещательный адрес (0х00).

NOSTRETCH – разряд, актуальный только для ведомого. Это своего рода “тормоз”. Когда ведомый принял байт данных или адрес (включая бит подтверждения) ему на обработку данных может понадобиться время. Чтобы остановить ведущее устройство ему достаточно притянуть линию SCL к земле и держать её до тех пор, пока он не будет в состоянии обрабатывать данные дальше (это предусмотрено спецификацией интерфейса).

Если этот бит сброшен, то “тормоз” активирован. При совпадении адреса (установлен флаг ADDR) или окончании приёма байта (установлен флаг BTF) устройство будет удерживать SCL в нуле до тех пор, пока не будут сброшены указанные выше флаги. Мастер будет вынужден всё это время ждать.

START – генерирует сигнал СТАРТ (если устройство в режиме ведомого) или ПОВСТАРТ (устройство в режиме ведущего). Устанавливается программно. Сбросится аппаратно по окончанию формирования сигнала.

STOP – генерирование сигнала СТОП. В режиме ведущего установка этого разряда приведёт к генерированию сигнала STOP по окончанию передачи текущего байта или сигнала START. Сбросится он аппаратно.

ACK – если этот разряд установлен, то  по окончанию приёма байта или совпадении адреса в ответ будет послан сигнал ACK, если не установлен – NACK.

SWRST – используется для программного сброса модуля I2C.

 

Для настройки I2С одного регистра недостаточно, поэтому существует второй, CR2:

image

FREQ[5:0] – задает частоту тактирования модуля. Значение FREQ может изменяться в пределах 2..36, соответственно значение PCLK1 должно находиться в этом диапазоне.

Насколько я понял, в эти разряды нужно записать значения частоты тактирования модуля PCLK1, которая зависит от кварца и прочего. Благодаря правильному значению в этих разрядах модуль будет тактироваться частотой, нужной для корректной работы и в режиме FAST и в режиме STANDART (для режима FAST значение PCLK1 должно быть не меньше 10 МГц). Эти разряды актуальны для работы в режиме мастера и ведомого, а вот регистр CCR задает частоту шины, если модуль является мастером.

ITERREN – разрешает(1)/запрещает(0) прерывания при обнаружении ошибок (всего семь ошибок).

ITEVTEN — разрешает(1)/запрещает(0) прерывания при возникновении события.

ITBUFEN –  позволяет запретить/разрешить генерирование прерываний при установке флагов TxE или RxNE. Это полезно при обмене данными через DMA. Если этот разряд сброшен, то возможны все прерывания, кроме прерываний от TxE и RxNE.

DMAEN — разрешает(1)/запрещает(0) запрос ДМА при установке флагов TxE или RxNE.

 

Регистр SR1 содержит следующие флаги:

image

SB – устанавливается, если  был сгенерирован сигнал START. Для сброса нужно прочитать SR1 и записать в регистр DR данные.

ADDR – при работе в режиме мастера устанавливается по окончанию передачи адреса, в режиме ведомого – при совпадении адреса. Для сброса нужно прочитать регистр SR1 затем SR2.

BTF – флаг окончания передачи/приема байта данных. Для его работы разряд NOSTRETCH регистра CR1 должен быть равен 0.

При работе в режиме приема BTF будет установлен, если принят байт данных (включая ACK), а регистр DR еще не был прочитан.

При работе в режиме передачи BTF будет установлен, если байт данных был передан, а регистр DR еще не были загружены новые данные.

Для сброса BTF нужно прочитать SR1 с последующей записью/чтением DR (или же он сбросится после приема сигнала start или stop).

Флаг BTF не будет установлен, если принят сигнал NACK.

STOPF – при работе ведомым устанавливается при обнаружении сигнала STOP, если перед этим был сигнал ACK. Сбрасывается чтением SR1 с последующей записью в CR1.

RxNE – устанавливается, если при работе в режиме приема данных регистр DR не пуст, т.е. принятый байт данных был помещен в DR. Сбрасывается после чтения DR.

TxE – устанавливается, если при работе в режиме передачи данных регистр данных DR освободился, т.е. байт данных из него был перемещен в сдвиговый регистр передатчика. Чтобы сбросить TxE, нужно записать в DR новые данные, или же он сбросится автоматически при поступлении сигнала start или stop.

BERR – ошибка шины. Устанавливается при обнаружении сигнала start или stop в “неуместном” месте.

Для сброса BERR необходимо записать в него 0.

ARLO – флаг потери арбитража (в режиме мастера). Для сброса нужно записать 0.

AF – устанавливается при получении сигнала NACK. Для сброса нужно записать 0.

 

Для управления частотой тактирования шины используется регистр CCR:

image

F/S – выбор скорости (STANDART или FAST режимы)

DUTY – задает скважность импульса SCL в режиме FAST

CCR[11:0] – при работе в режиме мастера задает тактовую частоту линии SCL.

Работа модуля I2C в режиме ведомого устройства

Находясь в режиме ведомого, модуль ожидает переход шины в состояние СТАРТ. Обнаружив этот переход оно готово принять первый байт данных, который является адресом устройства.

Приняв байт-адрес устройство сравнивает его с собственным адресом, который находится в регистре OAR1.  Если адрес не совпал – уходит в ожидание  до следующего СТАРТа.

Если адрес совпал модуль выполняет следующее:

  1. Уведомляет об этом ядро.  Для этого модуль устанавливает разряд ADDR регистра SR1. Если при настройке регистра CR2 был установлен разряд ITEVTEN, будет сгенерировано прерывание.
  2. Выдает на шину бит подтверждения ACK. Данный сигнал будет сформирован, если установлен разряд ACK регистра CR1. Получив бит подтверждения мастер поймет, что ведомое устройство обнаружено и готово к обмену.

После принятия байта-адреса флаг TRA регистра CR2 будет определять режим работы модуля: 0 – ведомый приемник, 1 – ведомый передатчик. Значение этого флага  зависит от младшего разряда байта-адреса.

Помимо основного адреса (регистр OAR1) устройство может откликаться на дополнительный адрес (регистр OAR2). Для этого нужно установить разряд ENDUAL в регистре OAR2. При совпадении будет установлен флаг  DUALF. Чтобы модуль реагировал на “широковещательный” адрес (00) необходимо установить разряд ENGC регистра CR1. При обнаружении этого адреса будет установлен флаг GENCALL.

После  установки разряда ADDR модуль будет удерживать линию SCL в нуле, чем приостановит работу мастера.  Чтобы его сбросить (и тем самым возобновить работу мастера) необходимо прочитать регистр SR1 с последующим чтением регистра SR2.

После сброса ADDR в зависимости от состояния разряда TRA (а оно определяется младшим разрядом в байте адреса) происходит прием или передача данных.

Режим ведомого передатчика

В этом режиме модуль выдает данные мастеру, который в ответ выдает бит подтверждения ACK или  NACK, если он хочет остановить дальнейший прием.

Процесс передачи контролируется флагами TxE и AF.

Разряд TxE устанавливается, если освобожден регистр данных DR и получен от мастера сигнал подтверждения ACK. Установка разряда TxE указывает ведомому, что мастер ожидает очередной байт данных, который нужно загружать в регистр DR.

Если мастер закончил прием данных, он вместо ACK выдает сигнал NACK, что приведёт к установке флага AF в модуле ведомого.

Режим ведомого приемника

В этом режиме модуль принимает данные от мастера и если установлен разряд ACK регистра CR1 выдает бит подтверждения ACK.

Процесс передачи контролируется флагами RxNE и STOPF.

Приняв очередной байт от мастера, ведомый загружает эти данные в регистр DR и выставляет флаг RxNE, который будет сброшен после чтения данных из DR. Если регистр данных не был прочитан (ну не успел контроллер это сделать, был занят), а поступили новые данные, то будет установлен флаг BTF и ведомый потянет линию SCL вниз, приостановив работу мастера до тех пор, пока не будет сброшен этот флаг и прочитаны данные из DR.

По окончанию передачи данных мастер выдаст сигнал STOP, а модуль ведомого установит флаг STOPF.

 

 

продолжение следует…

Оставить комментарий

Spam Protection by WP-SpamFree