Skip to main content

I2C

Интерфейс I2C применяется для связи между собой однокристальных микроконтроллеров, ЖКИ-индикаторов, портов ввода-вывода, микросхем памяти, аналого-цифровых и цифро-аналоговых преобразователей и т.д.

Основные характеристики:

  • только две линии – последовательная линия данных (SDA) и последовательная линия синхронизации (SCL)
  • возможностью работы в multi-master среде
  • последовательная передача данных по 8 бит
  • скорости передачи данных: 100 кбит/с, 400 кбит/с
  • фильтрация сигналов на линиях передачи данных (SDA, SCL) от помех
  • глубина буфера приемника и передатчика 8 слов

Все операции на шине I2C осуществляются при помощи двух проводов SDA и SCL. Как SDA, так и SCL являются двунаправленными линиями, которые необходимо подсоединить к положительному источнику питания через подтягивающий резистор. Когда шина свободна, обе линии за счет подтягивающих резисторов принимают высокий логический уровень. Выходные каскады устройств, подключенных к шине, должны иметь открытый сток или открытый коллектор.

Структурная схема

Структурная схема I2C

I2C состоит из следующих блоков:

  • REGISTERS – блок для хранения управляющих данных и статусов;
  • FIFO_TX – буфер передатчика;
  • FIFO_RX – буфер приемника;
  • SEQUENCER/ARBITER – управляющий автомат интерфейса;
  • SERIALIZER/DESERIALIZER – блок предназначен для преобразования параллельного потока данных от управляющего автомата в последовательный, а также для преобразования последовательно потока с внешней шины, в параллельный – для управляющего автомата.

Алгоритмы работы

Процедура передачи данных ведущим

  • в регистрах I2C_MSK0, I2C_MSK1, I2C_MSK2 разрешить необходимые прерывания;
  • в регистре I2C_CFG установить биты FILT_DEPTH, определяющие глубину фильтрации;
  • в регистре I2C_PRSC0 определить длительность высокого и низкого уровня SCL, установив младшие 8 бит PRSC;
  • в регистре I2C_PRSC1:
    • определить режим работы битом F/S, если выбран Fast-mode, то задать коэффициент заполнения битом DUTY;
    • определить длительность высокого и низкого уровня SCL, установив старшие 4 бита PRSC.
  • в регистре I2C_PRSC3 установить максимальную длительность петли обратной связи линии SCL битами TRISE;
  • записать адрес c «0» в младшем бите и отправляемые данные в регистр I2C_TXFIFO (данный этап можно провести после включения или подачи START последовательности; также данные можно дописывать как во время передачи, контролируя состояние буфера посредствам регистра I2C_TXWORDS, статуса BTF регистра I2C_ST0 или статуса FIFO_EMPTY_TX регистра I2C_ST1 и соответствующего прерывания, так и после когда бит статуса TX_END_EMPTY_FIFO регистра I2C_ST2 уже выставлен);
  • в регистре I2C_CTRL:
    • определить тип адресации битом ADDR_MOD;
    • установить бит START;
    • включить модуль битом EN.
  • по статусному биту FIFOEMPTY_TX регистра I2C_ST1 или TX_END_EMPTY_FIFO регистра I2C_ST2 установить бит STOP регистра I2C_CTRL (если бит STOP устанавливается по флагу FIFO_EMPTY_TX, т.е. во время передачи последнего слова, то STOP последовательность будет развернута незамедлительно после отправки последнего байта данных и считывания его бита подтверждения, в противном случае между последним _Tlow/2 и началом STOP последовательности возникает задержка, связанная с уходом на обработчик прерываний, чтением и записью регистров);
  • на основании статусного бита STOP регистра I2C_ST0 установить момент завершения подачи STOP последовательности, выключить модуль или продолжить работу.

При потере арбитража во время отправки данных в случае, если адрес записан в первом байте FIFO_TX, пользователь имеет возможность предпринять вторую попытку после освобождения шины без повторного заполнения буфера, сбросив указатель чтения битом RST_TX_RDP регистра I2C_CTRL.

Процедура приема данных ведущим

  • в регистрах I2C_MSK0, I2C_MSK1, I2C_MSK2 разрешить необходимые прерывания;
  • в регистре I2C_CFG:
    • установить биты FILT_DEPTH, определяющие глубину фильтрации;
    • определить режим работы FIFO_RX битом EN_OV.
  • в регистре I2C_PRSC0 определить длительность высокого и низкого уровня SCL, установив младшие 8 бит PRSC;
  • в регистре I2C_PRSC1:
    • определить режим работы битом F/S, если выбран Fast-mode, то задать коэффициент заполнения битом DUTY;
    • определить длительность высокого и низкого уровня SCL, установив старшие 4 бита PRSC.
  • в регистре I2C_PRSC3 установить максимальную длительность петли обратной связи линии SCL битами TRISE;
  • записать адрес c «1» в младшем бите в регистр I2C_TXFIFO;
  • если необходимо принять более одного байта, то необходимо установить количество слов, 
    при котором формируется соответствующий статус в регистре I2C_RXTHRESHOLD 
    (для завершения приема необходимо отправить NACK во время передачи последнего байта, поэтому установленное значение должно быть как минимум на одно меньше, чем принимаемых байт);
  • в регистре I2C_CTRL:
    • определить тип адресации битом ADDR_MOD;
    • если необходимо принять более одного байта установить бит ACK;
    • установить бит START;
    • включить модуль битом EN.
  • в регистре I2CCTRL по статусному биту RX_THRESHOLD_PASS регистра I2C_ST1 или FIFO_RX_NOT_EMPTY, или TX_END_EMPTY_FIFO регистра I2C_ST2 (в зависимости 
    от количества принимаемых байт; если бит STOP устанавливается по FIFO_RX_NOT_EMPTY, 
    то между последним _Tlow
    /2 и началом STOP последовательности возникает задержка, связанная с уходом на обработчик прерываний, чтением и записью регистров):
    • если принимается более одного байта записать «0» в бит ACK;
    • установить бит STOP.
  • на основании статусного бита STOP регистра I2C_ST0 установить момент завершения подачи STOP последовательности, cчитать полученные данные из регистра I2C_RXFIFO, выключить модуль или продолжить работу.

Пользователь имеет возможность считывать буфер принятых данных и изменять регистр I2C_RXTHRESHOLD во время передачи данных ведомым, что позволяет принимать более 8 байт.

Процедура передачи данных ведомым

  • в регистрах I2C_MSK0, I2C_MSK1, I2C_MSK2 разрешить необходимые прерывания;
  • в регистре I2C_CFG:
    • установить биты FILT_DEPTH, определяющие глубину фильтрации;
    • определить режим работы FIFO_RX битом EN_OV.
  • задать адрес устройства в регистрах I2C_ADDR1 и I2C_ADDR0;
  • в регистре I2C_PRSC2 определить длительность удержания уровня SDA после заднего фронта SCL;
  • записать отправляемые данные в регистр I2C_TXFIFO;
  • в регистре I2C_CTRL:
    • определить тип адресации битом ADDR_MOD;
    • установить бит ACK;
    • включить модуль битом EN.
  • дописывать данные в регистр I2C_TXFIFO по мере опустошения выходного буфера, отслеживая его состояние с помощью бит BTF, FIFO_EMPTY_TX или TX_END_EMPTY_FIFO статусных регистров, а также регистра I2C_TXWORDS.

Если на момент чтения нового слова из выходного буфера он пуст, то будут отправлены нули. Мастер должен отправить NACK после приема последнего байта данных, иначе ведомый предпримет попытку продолжить передачу.

Процедура приема данных ведомым

  • в регистрах I2C_MSK0, I2C_MSK1, I2C_MSK2 разрешить необходимые прерывания;
  • в регистре I2C_CFG:
    • установить биты FILT_DEPTH, определяющие глубину фильтрации;
    • определить режим работы FIFO_RX битом EN_OV.
  • задать адрес устройства в регистрах I2C_ADDR1 и I2C_ADDR0;
  • в регистре I2C_PRSC2 определить длительность удержания уровня SDA после заднего фронта SCL;
  • в регистре I2C_RXTHRESHOLD установить количество слов, при котором формируется соответствующий статус;
  • в регистре I2C_CTRL:
    • определить тип адресации битом ADDR_MOD;
    • установить бит ACK;
    • включить модуль битом EN.
  • считывать данные и управлять битом ACK регистра I2C_CTRL по мере формирования соответствующих статусов.

Статусы и прерывания

В отличии от остальных модулей в I2C:

  • прерывание по биту-флагу не формируется, если бит уже находится в «1», и в этот момент разрешается прерывание;
  • прерывание по биту-событию не формируется от последующих событий после перехода бита 
    в «1», пока он не будет сброшен чтением обратно в «0».

Остальные принципы работы, описанные в разделе «Типы статусов и прерывания», остаются неизменными.

Регистры I2C

АббревиатураДоступОписание
2A00hI2C_CFGRWРегистр конфигурации
2A04hI2C_CTRLRWРегистр управления
2A08hI2C_ST0RРегистр статуса 0
2A09hI2C_ST1RРегистр статуса 1
2A0AhI2C_ST2RРегистр статуса 2
2A0ChI2C_ADDR0RWРегистр адреса приемника 0
2A0DhI2C_ADDR1RWРегистр адреса приемника 1
2A10hI2C_PRSC0RWПредделитель 0
2A11hI2C_PRSC1RWПредделитель 1
2A12hI2C_PRSC2RWПредделитель 2
2A13hI2C_PRSC3RWПредделитель 3
2A14hI2C_MSK0RWРегистр маски прерываний 0
2A15hI2C_MSK1RWРегистр маски прерываний 1
2A16hI2C_MSK2RWРегистр маски прерываний 2
2A18hI2C_TXFIFORWБуфер данных на передачу
2A1ChI2C_RXFIFORБуфер принятых данных
2A20hI2C_TXWORDSRКоличество непрочитанных слов в буфере передачи
2A24hI2C_RXTHRESHOLDRWУказывает количество непрочитанных слов в буфере приема, при котором формируется соответствующий признак в регистре ST

I2C_CFG

Бит76543210
НазначениеРезервFILT_DEPTHEN_OV
Начальное значение0

FILT_DEPTH – настройка глубины фильтров для входных сигналов SDA, SCL.

Выбирается следующим образом:

FILT_DEPTH>TnoiseTclkFILT\_DEPTH > \frac {T_{noise}}{ {T_{clk}}}

где TnoiseT_{noise} – максимальная длительность помехи, которую необходимо отфильтровать, TclkT_{clk} – период частоты тактирования системы.

Соответственно при максимальном значении битов FILT_DEPTH может быть отфильтрована помеха длительностью менее Tclk. При значении «0» фильтр выключен.

EN_OV – при переполнении буфера FIFO приемника разрешает или запрещает перезаписывать данные:

  • 1 – перезапись данных разрешена;
  • 0 – перезапись данных запрещена.

При приеме в режиме «ведущий», когда переполнение разрешено, контроллер может запрашивать от ведомого новые слова и записывать их поверх старых. При возникновении переполнения поднимается признак FIFO_RX_OV. Если переполнение запрещено ведущий остановит прием после появления признака FIFO_RX_FULL.

При приеме в режиме «ведомый», когда переполнение разрешено, можно записывать новые слова поверх старых. При возникновении переполнения установится признак FIFO_RX_OV. Если переполнение запрещено, ведомый не будет записывать новые слова поверх старых, однако при приеме нового слова и наличии признака FIFO_RX_FULL установится признак FIFO_RX_OV.

I2C_CTRL

Бит76543210
НазначениеRST_RX_PNTRSRST_TX_RDPRST_TX_PNTRSADDR_MODACKSTOPSTARTEN
Начальное значение0

RST_RX_PNTRS – запись единицы приводит к сбросу указателей FIFO_RX.

RST_TX_RDP (Reset Transmitter Read Pointer) – запись единицы приводит к сбросу указателя чтения FIFO_TX.

RST_TX_PNTRS – запись единицы приводит к сбросу указателей FIFO_TX.

ADDR_MOD – тип адресации:

  • 1 – 10-ти битная адресация;
  • 0 – 7-ми битная адресация.

ACK – разрешение подтверждение после приема байта (адреса или данных):

  • 1 – отправлять подтверждение;
  • 0 – не отправлять подтверждение.

При переводе бита в «0» модуль запишет последний байт в буфер приема и подаст на линию NACK.

STOP – сформировать STOP последовательность:

  • 1 – в режиме «ведущий» формируется STOP;
  • 0 – STOP не формируется.

Бит переводится в «0» устройством после STOP.

START – сформировать START последовательность.:

  • 1 – в режиме «ведущий» формируется START;
  • 0 – START не формируется.

Бит переводится в «0» устройством после START.

EN – разрешение работы модуля:

  • 1 – модуль включен;
  • 0 – модуль выключен.

I2C_ST0

Бит76543210
НазначениеFIFO_RX_OVFIFO_RX_FULLARB_LOSTBUS_ERRORACK_FAILUREBTFSTOPSTART
Тип статусаFLAGEVENTEVENTEVENTEVENTEVENTEVENT
Начальное значение0

FIFO_RX_OV – FIFO_RX переполнен.

FIFO_RX_FULL – FIFO_RX полностью заполнен. При наличии FIFO_RX_OV обнуляется, контролироваться не должен.

ARB_LOST – признак потери арбитража (только для режима «ведущий»). При потере арбитража в процессе передачи слова данных ведущий продолжает формировать импульсы SCL для всех 8 бит данных, затем освобождает линию SCL, и после этого формирует статус ARB_LOST.

BUS_ERROR – признак несвоевременного события START или STOP. Признак появляется, если зафиксирован перепад линии SDA на фоне единичного уровня SCL во время передачи байта данных или бита подтверждения.

ACK_FAILURE – не было подтверждения после передачи байта данных/адреса.

BTF (Byte Transfer Completed) – обмен байтом завершен:

  • 1 – обмен байтом завершился успешно;
  • 0 – обмена байтом не было/завершился не успешно.

Переводится в единицу, если:

  • при приеме, когда принят новый байт и отправлен ACK/NACK;
  • при передаче, если байт был передан и получен ACK.

Примечание: если при передаче байта принят NACK, BTF не переводится в единицу.

STOP – в режиме «ведущий» сформирован STOP, в режиме «ведомый» обнаружен STOP.

START – в режиме «ведущий» сформирован START, в режиме «ведомый» обнаружен START.

I2C_ST1

Бит76543210
НазначениеRX
THRESHOLD
PASS
MODEBUS_CLEARSLV_RXSLV_TXFIFO
EMPTY
TX
FIFO
FULL
TX
FIFO
RX
NOT_EMPTY
Тип статусаFLAG
Начальное значение10100100

RX_THRESHOLD_PASS – количество непрочитанных слов в буфере приема больше либо равно значению регистра I2C_RX_THRESHOLD.

MODE – режим:

  • 1 – блок находится в режиме «ведущий»;
  • 0 – блок находится в режиме «ведомый».

BUS_CLEAR – признак того, что на линии не идет обмен. Линия будет считаться занятой, если зафиксирован низкий уровень на линиях SDA или SCL, и свободной – если произошло событие STOP.

SLV_RX – признак, что в режиме «ведомый» устройство адресовано на запись.

SLV_TX – признак, что в режиме «ведомый» устройство адресовано на чтение.

FIFO_EMPTY_TX – FIFOTX пуст. Возникает перед передачей последнего слова данных в момент чтения из буфера (за такт системной частоты до выдачи первого бита на линии SDA в момент времени _Tlow/2).

FIFO_FULL_TX – FIFO_TX полностью заполнен.

FIFO_RX_NOT_EMPTY – FIFO_RX не пуст. При наличии FIFO_RX_OV обнуляется, контролироваться не должен.

I2C_ST2

Бит76543210
НазначениеРезервTX_END_EMPTY_FIFO
Тип статусаEVENT
Начальное значение0

TX_END_EMPTY_FIFO – признак того, что в момент завершения передачи слова буфер передачи был пуст. Возникает в момент завершения приема ACK либо NACK после передачи слова (за такт системной частоты до Tlow/2).

I2C_ADDR0

Бит76543210
НазначениеADDR
Начальное значение0

ADDR – адрес в режиме «ведомый», младшая часть.

I2C_ADDR1

Бит76543210
НазначениеРезервADDR
Начальное значение0

ADDR – адрес в режиме «ведомый», старшая часть.

I2C_PRSC0

Бит76543210
НазначениеPRSC
Начальное значение0

PRSC – предделитель, младшая часть.

I2C_PRSC1

Бит76543210
НазначениеF/SDUTYРезервPRSC
Начальное значение0

F/S – режим:

  • 1 – Fast-mode;
  • 0 – Standard-mode.

DUTY – коэффициент заполнения для Fast-mode:

1ThighTlow=9161 - \frac {T_{high}}{T_{low}} = \frac {9}{16} 1ThighTlow=121 - \frac {T_{high}}{T_{low}} = \frac {1}{2}

PRSC – предделитель, определяет длительность высокого (Thigh) и низкого (Tlow) уровня SCL в режиме «ведущий», старшая часть.

При Fast-mode и DUTY = 1:

Thigh=9PRSCTclkT_{high} = 9 \cdot PRSC \cdot T_{clk} Tlow=16PRSCTclkT_{low} = 16 \cdot PRSC \cdot T_{clk}

При Fast-mode и DUTY = 0:

Thigh=PRSCTclkT_{high} = PRSC \cdot T_{clk} Tlow=2PRSCTclkT_{low} = 2 \cdot PRSC \cdot T_{clk}

При Standard-mode:

Thigh=2PRSCTclkT_{high} = 2 \cdot PRSC \cdot T_{clk} Tlow=2PRSCTclkT_{low} = 2 \cdot PRSC \cdot T_{clk}

При установке битов PRSC необходимо, чтобы общее время, затраченное на обратную связь при спаде SCL, не превышало Tlow/2 . Для этого достаточно выполнения следующего неравенства:

Tlow2Tclk>TfallTclk+FILT_DEPTH+2\frac {T_{low}}{2 \cdot T_{clk}} > \lceil \frac{T_{fall}}{T_{clk}}\rceil + FILT\_DEPTH +2

где Tfall – максимальная длительность заднего фронта SCL на входе устройства. Из этого следует, что при Standard-mode или Fast-mode с DUTY в «0» и Tfall намного меньше Tclk минимальное значение битов PRSC равно 3 при выключенном фильтре (биты FILT_DEPTH в «0»), однако рекомендуется округлять отношение длительности заднего фронта и периода синхросигнала в большую сторону.

I2C_PRSC2

Бит76543210
НазначениеSLV_HLD
Начальное значение0

SLV_HLD – длительность удержания уровня SDA, младшая часть.

I2C_PRSC3

Бит76543210
НазначениеРезервTRISESLV_HLD
Начальное значение0

TRISE – максимальная длительность петли обратной связи линии SCL в режиме «ведущий». Используется с целью установить корректную скважность на линии SCL, которая не будет зависеть от длительности переднего фронта SCL на входе устройства и глубины фильтрации. Значение должно быть установлено исходя из максимального времени нарастания переднего фронта SCL, выраженного в периодах частоты тактирования системы:

TRISE=TriseTclk+FILT_DEPTH+3 TRISE = \lceil \frac{T_{rise}}{T_{clk}}\rceil + FILT\_DEPTH + 3

где Trise – максимальная длительность переднего фронта SCL на входе устройства.

Также следует учитывать:

TRISEThighTclkTRISE \le \frac {T_{high}}{T_{clk}}

SLV_HLD – длительность удержания уровня SDA, старшая часть. В режиме «ведомый» через поле SLV_HLD определяется длительность удержания уровня SDA от заднего фронта SCL до выдачи бита ведомым I2C:

Thold=Tfall+(FILT_DEPTH+SLV_HLD+6)TclkT_{hold} = T_{fall} + (FILT\_DEPTH + SLV\_HLD +6) \cdot T_{clk}

I2C_MSK0

Возможно формирование прерывания по любому биту статусного регистра I2C_ST0. Расположение битов в I2C_ST0 и I2C_MSK0 аналогично.

Бит76543210
НазначениеFIFO_RX_OVFIFO_RX_FULLARB_LOSTBUS_ERRORACK_FAILUREBTFSTOPSTART
Начальное значение0

Для каждого из битов справедливо:

  • 1 – данное прерывание формируется;
  • 0 – данное прерывание не формируется.

I2C_MSK1

Возможно формирование прерывания по любому биту статусного регистра I2C_ST1. Расположение битов в I2C_ST1 и I2C_MSK1 аналогично.

Бит76543210
НазначениеRX_THRESHOLD_PASSMODEBUS_CLEARSLV_RXSLV_TXFIFO_EMPTY_TXFIFO_FULL_TXFIFO_RX_NOT_EMPTY
Начальное значение0

Для каждого из битов справедливо:

  • 1 – данное прерывание формируется;
  • 0 – данное прерывание не формируется.

I2C_MSK2

Расположение статусного бита аналогично I2C_ST2.

Бит76543210
НазначениеРезервTX_END_EMPTY_FIFO
Начальное значение0

TX_END_EMPTY_FIFO - разрешить прерывание по статусу TX_END_EMPTY_FIFO:

  • 1 – данное прерывание формируется;
  • 0 – данное прерывание не формируется.

I2C_TXFIFO

Бит76543210
НазначениеTX_FIFO
Начальное значение0

TX_FIFO – буфер передаваемых данных. При передаче адреса в режиме «ведущий» пользователь должен самостоятельно задать R/W битом 0.

I2C_RXFIFO

Бит76543210
НазначениеRX_FIFO
Начальное значение0

RX_FIFO – буфер принятых данных.

I2C_TXWORDS

Бит76543210
НазначениеРезервTX_WORDS
Начальное значение0

TX_WORDS – количество непрочитанных слов в буфере передачи (от 0 до 8).

I2C_RXTHRESHOLD

Бит76543210
НазначениеРезервRX_THRES
Начальное значение0

RX_THRES – количество непрочитанных слов в буфере приема (от 0 до 8), при котором формируется соответствующий признак в регистре статуса.