Низкоуровневый i2c

Практические рекомендации по шине I2C – Технический форум разработчиков электроники

  • Ниже мы рассмотрим основные трудности, связанные с использованием шины I2C в целом, а также типичные ошибки, возникающие на начальных этапах реализации алгоритмов обмена.Удобства применения шины I2C очевидны – малое количество соединительных линий и высокая скорость обмена, простота аппаратной реализации линии связи. Наиболее широко поддерживает шину I2C, конечно же, фирма Philips, производящая множество ИС различной сложности с управлением по I2C. В первую очередь, можно выделить микросхемы энергонезависимой памяти (EEPROM) серии 24Cхх в 8-ми выводных корпусах, фактически ставшие промышленным стандартом. Из широко распространенных ИС можно выделить: микросхемы часов PCF8583, параллельный порт PCF8574, 4-х канальный 8-ми разрядный АЦП PCF8591. Cуществует множество модификаций этих ИС и более специализированные контроллеры.I2C-абоненты жестко разделяются по классам:”Master”- и “Slave”- устройство. Тот факт, что сигнал SCL всегда генерируется “Master”-устройством означает, что “Master”-абонент может быть достаточно легко реализован чисто программными средствами, так как все изменения на шине будут происходить только по сигналу SCL. И наоборот, реализация “Slave”-устройства требует аппаратной поддержки, кроме случая очень низких скоростей обмена. Существуют однокристальные микро-ЭВМ (ОМЭВМ) поддерживающие “Slave”-операции шины I2C. Это прежде всего Philips PCF80C552 (652), Microchip PIC16C62 (64, 73 и др.), Motorola MC68HC705CJ4 (BD3, E5). Кроме того, ОМЭВМ фирмы Philips аппаратно поддерживают “Master”-протокол, хотя практически аппаратные “Master”-контроллеры применяются редко.Типичная ошибка при реализации программ “Master”-абонента – управление значением порта ОМЭВМ для установки нулевого и единичного состояний линий SCL и SDA. Если для ОМЭВМ семейства MCS-51 это нормальный режим работы, так как единичное состояние порта у них реализуется встроенным подтягивающим резистором = 50 кОМ, то для ОМЭВМ с симметричными портами (Motorola 68HCxx, Microchip PIC, Atmel AVR) это будет порождать электрические конфликты. Например, в руководстве “Microchip. Embedded Control Handbook 1994/1995” приведены практические программы для связи PIC c ИС EEPROM, содержащие подобные грубые ошибки. Положение усугубляется тем, что в случае микросхем EEPROM такой вариант может сработать, так как оин являются 100% аппаратными схемами и не вносят задержек в связной протокол, а пазу ожидания окончания цикла программирования производят переходом в пассивное состояние. Использование таких подпрограмм с ИС, производящими захват линии SCL (практически любой “Slave”-абонент, реализованный с применением ОМЭВМ), приведет к невозможности связи, а возможно, и к выходу ИС из строя.Реализовать настоящую имитацию ОК (мы назвали этот режим имитацией ОК, так он не позволяет устанавливать на линии напряжение выше напряжения питания, что было бы нормально для настоящего ОК, но так как по спецификации I2C напряжение на линиях SCL и SDA не должно превышать напряжение питания, его вполне законно можно считать выходом с ОК) на порте с симметричным выходом можно, если установить значение порта постоянно в ноль, а управлять состоянием линии через манипуляции с регистром направления данных. Для ОМЭВМ PIC это будет регистр “TRISx”, переводящий порт либо в третье состояние, либо подключающий линии в соответствии с состоянием регистра “PORTx”. Практически так же это реализуется в AVR и MC68HC05 (08, 11), где “DDRx” коммутирует порт “PORTx”, с той лишь разницей, что у них другая полярность управляющего сигнала – у PIC ноль в “TRISx” соответствует нулю на выходе, а у AVR и MC68HC05 единица в “DDRx” соответствует нулю на выходе.Еще одна тонкость связанная с PIC, не имеющая собственно к I2C никакого отношения заключается в том, что у него совмещены регистр чтения состояния линий порта и регистр записи значения порта, в результате чего, если часть линий порта запрограммирована на вывод, а другая находится в третьем состоянии, то при выполнении PIC'а установленных в третье состояние, что может нарушить (и скорее всего нарушит) работу программы обмена (потеряются нули обеспечивающие имитацию выходов с ОК). Поэтому лучше производить принудительную установку в ноль битов в “PORTx”, например, перед каждой операцией обмена, скажем такой последовательностью:movlw b'11100111' ; Маска линий SCL и SDA в порте С (RC3 и RC4) andwf portc,f ; Сбр. значений линий SCL и SDA в порте С в нольДругая важная сторона вопроса-необходимость тщательного соблюдения параметров временной диаграммы процесса обмена. Несмотря на то, что шина I2C асинхронная и позволяет затягивать передачу бита (байта) на сколь угодно длительное время (это свойство позволяет реализовывать программы I2C-обмена на самом низком уровне приоритета, прерывая процесс передачи в любое время), требования к минимальным значениям длительностей импульсов очень жесткие. Ситуация усугубляется тем, что положительные перепады состояния линии имеют склонность затягиваться, так как несимметричные управляющие выходы не могут создать крутые положительные фронты.При написании программ очень важно контролировать время между операциями на шине, реализуемыми различными подпрограммами, например выдача “Start” и “Stop”-условия, передача бита, передача байта. При состыковке этих подпрограмм не должны быть нарушены минимальные значения времени, что очень легко происходит при использовании высокоскоростных процессоров (AVR, PIC). Кроме того, необходимо следить, чтобы время между изменением на линии SDA и стробированием положительным импульсом на линии SCL было не меньше половины минимальной длительности полупериода SCL (4.7 мкс/2=2.4 мкс). Помимо этого, некоторые “Slave”-приборы могут ужесточить требования к максимальной частоте обмена (например, CE110-48 кГц), в этом случае необходимо пропорционально снижению частоты обмена увеличивать значения минимумов временных допусков. Еще одна распространенная ошибка – игнорирование требования слежения за захватом линии SCL “Slave”-абонентом. Грамотно реализованные прграммы операций “Master”-абонента должны контролировать возврат линии SCL после того, как переводят ее в единичное состояние, и только дождавшись реальной установки линии SCL в единичное состояние продолжать операции приемо-передачи. Теперь мы опишем минимально необходимый набор операций для реализации “Master”-абонента. Прежде всего, это подпрограммы выдачи “Start”- и “Stop”-условия, подпрограмма передачи байта, подпрограмма приема байта, выдающая сигнал АСК и подпрограмма приема байта, не выдающая сигнал АСК. Три последние используют подпрограммы передачи бита и приема бита.Во временных промежутках между подпрограммами линия SCL имеет нулевое значение. Как уже говорилось ранее, важно правильно согласовывать все временные характеристики подпрограмм. Если, к примеру, вы вызываете повторный “Start” сразу за передачей (приемом) байта, то необходимо, чтобы полностью завершился нулевой полупериод (>4.7 мкс), предшествующий “Start”-условию, а подпрограмма, реализующая “Start”-условие, переведя линии SDA и SCL в единичное состояние, дождавшись их реального возврата, должна удерживать ее в таком состоянии не менее установленного времени (>4.7 мкс), и так во всех случаях.Оперируя этими пятью подпрограммами можно легко наладить обмен по шине I2C. Можно выдать на шину “Start”-условие, за ним “Siave Adress”, далее данные, в соответствии с протоколом конкретной I2C-ИС. Можно выдать повторное “Start”-условие, новый “Slave Adress” и так далее, формируя процесс обмена как из элементов конструктора. Обычно протоколы обмена “Slave”-устройств довольно логично соответствуют программированию в таком стиле.

Источник: http://www.eham.ru/articles/interfejsy/1523-prakticheskie-rekomendacii-po-shine-i2c

Интерфейс I2C | РОБОТОША

Имеется большое число различных синхронных последовательных протоколов. Многие из них широко применяются, и для их реализации доступны необходимые аппаратные средства.

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

Этот недостаток отсутствует у интерфейса I2C (Inter-Integrated Circuit).

Он был первоначально разработан фирмой Philips в конце 1970-х годов специально для того, чтобы обеспечивать такой способ подключения периферийных устройств к микропроцессорам, который не требовал бы использования традиционных шин адреса, данных и управления, а кроме того, позволял бы нескольким микропроцессорам работать с одними и теми же периферийными устройствами (multimastering). Philips запатентовал название интерфейса и до 2007 у различных производителей этот микроконтроллер имел свое название. Например, в микроконтроллерах ATmega, на которых строится Arduino, этот интерфейс носит название 2-wire Serial Interface (двухпроводной последовательный интерфейс).

Интерфейс RS-232 использует асинхронный протокол передачи данных, потому что приемник не получает какого-либо сигнала тактирования в явном виде. На рисунке ниже показаны временные диаграммы сигналов при синхронной передаче данных. Здесь приемник фиксирует данные на линии Data по переднему или заднему фронту синхроимпульсов Clock.

Синхронная передача данных

Интерфейс I2C использует всего две линии — они именуются SCL (Serial Clock) и SDA (Serial Data).

Первая предназначена для передачи синхроимпульсов (они формируются тем устройством, которое в настоящий момент передает данные), а вторая — для передачи самих данных и команд, управляющих этим процессом.

Обе линии имеют открытый коллектор (как и во многих других случаях, когда необходимо, чтобы к одной линии мого подключаться несколько различных устройств), поэтому требуют подключения «подтягивающих» резисторов сопротивлением 1-10 кОм.

Для примера на рисунке ниже показана структурная схема устройства управления стереосистемой.

Устройство управления стереосистемой на основе интерфейса I2C

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

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

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

Напряжение высокого уровня на линии SCL показывает, что шина пока свободна.

Перед началом процесса передачи задатчик устанавливает напряжение низкого уровня сначала на линии SDA, а затем на линии SCL (см. рисунок ниже). В процессе передачи данных такое состояние линий невозможно, поскольку сигнал на линии SDA не должен изменяться во время действия тактового импульса на линии SCL.

Начало и конец передачи данных по интерфейсу I2C

Затем начинается передача данных от ведущего устройства к ведомому (slave) или наоборот, но в любом случае источником синхроимпульсов является задатчик. Данные фиксируются приемником по заднему фронту синхроимпульсов.

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

В отличие от интерфейса RS-232, передача данных производится начиная со старшего бита; при этом используются обычные логические уровни микросхем ТТЛ/КМОП.

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

Перед посылкой очередного бита сигнал низкого уровня действует на обеих линиях. Временные диаграммы на рисунке ниже иллюстрируют процесс передачи одного байта данных по интерфейсу I2C.

Передача данных по интерфейсу I2C

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

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

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

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

Задатчик делает это, удерживая сигнал высокого уровня на линии SCL после приема или передачи предыдущего бита.

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

Cуществуют три максимальные скорости передачи. В так называемом стандартном режиме это 100 Кбит/с (частота синхроимпульсов 100 кГц), в быстром режиме — 400 Кбит/с (частота синхроимпульсов 400 кГц), в высокоскоростном режиме – 3.4 Мбит/с и в ультравысокоскоростном режиме — до 5 Мбит/с.

Правда, устройств, работающих на мегабитных скоростях еще нужно поискать. Помимо скоростных ограничений, есть и ограничения на максимальное количество подключенных к шине I2C устройств. В стандартном режиме можно адресовать 127 устройств (7-битный адрес), в быстром режиме до 1023 устройств (10-битный адрес).

На рисунке ниже показаны минимальные временные задержки для обоих режимов (все значения указаны в микросекундах).

Минимальные временные задержки для двух режимов передачи данных по интерфейсу I2C

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

Формат управляющих команд интерфейcа I2C

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

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

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

Конфликты разрешаются благодаря тому, что на линии с открытым коллектором подача сигнала высокого уровня реализуется, на самом деле, простым отключением активного устройства (вспомните о «подтягивающих» резисторах).

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

Тогда втрое устройство, «увидев», что действующий на линии уровень напряжения не совпадает с тем, который оно пытается установить, «понимает», что на шине активен еще один задатчик, и на время отключается, чтобы дать ему возможность беспрепятственно закончить обмен информацией.

Реализация интерфейса I2C с помощью микроконтроллеров весьма проста. Однако, из-за программной его реализации трудно достичь высоких скоростей передачи. Даже максимальная скорость стандартного режима (100 Кбит/с) может оказаться недостижимой.

Программная реализация интерфейса I2C все же является наилучшим решением, если кроме микроконтроллера на шине не может быть других задатчиков. Ведь в этом случае, не требуется синхронизировать его работу с какими-либо быстрыми устройствами, в которых используется аппаратная реализация этого интерфейса.

Полную спецификацию и руководство пользователя для шины I2C можно скачать по ссылке:

Category: Documents
Date: 04.03.2015

 

Преимущества интерфейса I2C

  • необходим всего один микроконтроллер для управления набором устройств;
  • используется всего два проводника для подключения многих устройств;
  • возможна одновременная работа нескольких ведущих (master) устройств, подключенных к одной шине I2C;
  • стандарт предусматривает «горячее» подключение и отключение устройств в процессе работы системы;
  • встроенный в микросхемы, реализующие интерфейс фильтр подавляет всплески, обеспечивая целостность данных.

Недостатки интерфейса I2C

  • ограничение на ёмкость линии — 400 пФ;
  • несмотря на простоту протокола, программирование контроллера I2C затруднено из-за изобилия возможных нештатных ситуаций на шине. По этой причине большинство систем используют I²C c единственным ведущим (master) устройством и распространённые драйверы поддерживают только монопольный режим обмена по I2C;
  • Трудность локализации неисправности, если одно из подключенных устройств ошибочно устанавливает на шине состояние низкого уровня.

Источник: http://robotosha.ru/electronics/interface-i2c.html

Подробное описание интерфейса I2C

Интерфейс I2C (или по другому IIC) — это достаточно широко распространённый сетевой последовательный интерфейс, придуманный фирмой Philips и завоевавший популярность относительно высокой скоростью передачи данных (обычно до 100 кбит/с, в современных микросхемах до 400 кбит/с), дешевизной и простотой реализации.

1) Физика.

Физически сеть представляет собой двухпроводную шину, линии которой называются DATA и CLOCK (необходим ещё и третий провод — земля, но интерфейс принято называть двухпроводным по количеству сигнальных проводов).

Соответственно, по линии DATA передаются данные, линия CLOCK служит для тактирования. К шине может быть подключено до 128 абонентов, каждый со своим уникальным номером.

В каждый момент времени информация передаётся только одним абонентом и только в одну сторону.

Устройства I2C имеют выход с “открытым коллектором”. Когда выходной транзистор закрыт — на соответствующей линии через внешний подтягивающий резистор устанавливается высокий уровень, когда выходной транзистор открыт — он притягивает соответствующую линию к земле и на ней устанавливается низкий уровень (смотрите рисунок).

Резисторы имеют номинал от нескольких килоОм до нескольких десятков килоОм (чем выше скорость — тем меньше номинал резисторов, но больше энергопотребление). На рисунке треугольниками на входе показано, что входы высокоомные и, соответственно, влияния на уровни сигналов на линиях они не оказывают, а только “считывают” эти уровни.

Обычно используются уровни 5В или 3,3В.

2) Логика.

Любое устройство на шине I2C может быть одного из двух типов: Master (ведущий) или Slave (ведомый). Обмен данными происходит сеансами. “Мастер”-устройство полностью управляет сеансом: инициирует сеанс обмена данными, управляет передачей, подавая тактовые импульсы на линию Clock, и завершает сеанс.

Кроме этого, в зависимости от направления передачи данных и “Мастер” и “Слэйв”-устройства могут быть “Приёмниками” или “Передатчиками”. Когда “Мастер” принимает данные от “Слэйва” — он является “Приёмником”, а “Слэйв” — “Передатчиком”. Когда же “Слэйв” принимает данные от “Мастера”, то он уже является “Приёмником”, а “Мастер” в этом случае является “Передатчиком”.

Не надо путать тип устройства “Мастер” со статусом “Передатчика”.

Несмотря на то, что при чтении “Мастером” информации из “Слэйва”, последний выставляет данные на шину Data, делает он это только тогда, когда “Мастер” ему это разрешит, установкой соответствующего уровня на линии Clock. Так что, хотя “Слэйв” в этом случае и управляет шиной Data, — самим обменом всё равно управляет “Мастер”.

В режиме ожидания (когда не идёт сеанс обмена данными) обе сигнальные линии (Data и Clock) находятся в состоянии высокого уровня (притянуты к питанию).

Каждый сеанс обмена начинается с подачи “Мастером” так называемого Start-условия. “Старт-условие” — это изменение уровня на линии Data с высокого на низкий при наличии высокого уровня на линии Clock.

После подачи “Старт-условия” первым делом “Мастер” должен сказать с кем он хочет пообщаться и указать, что именно он хочет — передавать данные в устройство или читать их из него.

Для этого он выдаёт на шину 7-ми битный адрес “Слэйв” устройства (по другому говорят: “адресует “Слэйв” устройство”), с которым хочет общаться, и один бит, указывающий направление передачи данных (0 — если от “Мастера” к “Слэйву” и 1 — если от “Слэйва” к “Мастеру”).

Первый байт после подачи “Старт”-условия всегда всеми “Слэйвами” воспринимается как адресация.

Поскольку направление передачи данных указывается при открытии сеанса вместе с адресацией устройства, то для того, чтобы изменить это направление, необходимо открывать ещё один сеанс (снова подавать “Старт”-условие, адресовать это же устройство и указывать новое направление передачи).

После того, как “Мастер” скажет, к кому именно он обращается и укажет направление передачи данных, — начинается собственно передача: “Мастер” выдаёт на шину данные для “Слэйва” или получает их от него. Эта часть обмена (какие именно данные и в каком порядке “Мастер” должен выдавать на шину, чтобы устройство его поняло и сделало то, что ему нужно) уже определяется каждым конкретным устройством.

Заканчивается каждый сеанс обмена подачей “Мастером” так называемого Stop-условия, которое заключается в изменении уровня на линии Data с низкого на высокий, опять же при наличии высокого уровня на линии Clock. Если на шине сформировано Stop-условие, то закрываются все открытые сеансы обмена.

Внутри сеанса любые изменения на линии Data при наличии высокого уровня на линии Clock запрещены, поскольку в это время происходит считывание данных “Приёмником”.

Если такие изменения произойдут, то они в любом случае будут восприняты либо как “Старт”-условие (что вызовет прекращение обмена данными), либо как “Стоп”-условие (что будет означать окончание текущего сеанса обмена).

Соответственно, во время сеанса обмена установка данных “Передатчиком” (выставление нужного уровня на линии Data) может происходить
только при низком уровне на линии Clock.

Несколько слов по поводу того, в чём в данном случае разница между “прекращением обмена данными” и “окончанием сеанса обмена”.

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

Управлять линией Data, для того, чтобы отвечать “Мастеру”, в этом случае будет разрешено тому устройству, к которому “Мастер” обратился последним, однако старый сеанс при этом нельзя считать законченным. И вот почему.

Многие устройства (например те же eeprom-ки 24Схх) для ускорения работы складывают данные, полученные от “Мастера” в буфер, а разбираться с этими полученными данными начинают только после получения сигнала об окончании сеанса обмена (то есть “Стоп-условия”).

То есть, например, если на шине висит 2 микросхемы eeprom 24Cxx и вы открыли сеанс записи в одну микросхему и передали ей данные для записи, а потом, не закрывая этот первый сеанс, открыли новый сеанс для записи в другую микросхему, то реальная запись и в первую и во вторую микросхему произойдёт только после формирования на шине “Стоп-условия”, которое закроет оба сеанса. После получения данных от “Мастера” eeprom-ка складывает их во внутренний буфер и ждёт окончания сеанса, для того, чтобы начать собственно процесс записи из своего внутреннего буфера непосредственно в eeprom. То есть, если вы после после передачи данных для записи в первую микруху не закрыли этот сеанс, открыли второй сеанс и отправили данные для записи во вторую микруху, а потом, не сформировав “Стоп-условие”, выключили питание, то реально данные не запишутся ни в первую микросхему, ни во вторую. Или, например, если вы пишете данные попеременно в две микрухи, то в принципе вы можете открыть один сеанс для записи в первую, потом другой сеанс для записи во вторую, потом третий сеанс для записи опять в первую и т.д., но если вы не будете закрывать эти сеансы, то в конце концов это приведёт к переполнению внутренних буферов и в итоге к потере данных.

Здесь можно привести такую аналогию: ученики в классе (“слэйвы”) и учитель (“мастер”). Допустим учитель вызвал какого-то ученика (пусть будет Вася) к доске и попросил его решить какой-то пример.

После того как Вася этот пример решил, учитель вызвал к доске Петю и начал спрашивать у него домашнее задание, но Васю на место не отпустил.

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

В случае, если “Слэйв” во время сеанса обмена не успевает обрабатывать данные, — он может растягивать процесс обмена, удерживая линию Clock в состоянии низкого уровня, поэтому “Мастер” должен проверять возврат линии Clock к высокому уровню после того, как он её отпустит.

Хотелось бы подчеркнуть, что не стоит путать состояние, когда “Слэйв” не успевает принимать или посылать данные, с состоянием, когда он просто занят обработкой данных, полученных в результате сеанса обмена.

В первом случае (во время обмена данными) он может растягивать обмен, удерживая линию Clock, а во втором случае (когда сеанс обмена с ним закончен) он никакие линии трогать не имеет права. В последнем случае он просто не будет отвечать на “обращение” к нему от “Мастера”.

Внутри сеанса передача состоит из пакетов по девять бит, передаваемых в обычной положительной логике (то есть высокий уровень — это 1, а низкий уровень — это 0). Из них 8 бит передаёт “Передатчик” “Приёмнику”, а последний девятый бит передаёт “Приёмник” “Передатчику”. Биты в пакете передаются старшим битом вперёд.

Последний, девятый бит называется битом подтверждения ACK (от английского слова acknowledge — подтверждение). Он передаётся в инвертированном виде, то есть 0 на линии соответствует наличию бита подтверждения, а 1 — его отсутствию.

Бит подтверждения может сигнализировать как об отсутствии или занятости устройства (если он не установился при адресации), так и о том, что “Приёмник” хочет закончить передачу или о том, что команда, посланная “Мастером”, не выполнена.

Каждый бит передаётся за один такт.

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

Читайте также:  Магниторезонансный источник энергии

Вот собственно и всё. На рисунках ниже всё это описание показано в графической форме.

3) Диаграммы и тайминги.

Параметр Обозн. Мин.знач. Комментарий
Свободная шина tBUF 4,7 мкс это минимальное время, в течении которого обе линии должны находиться в свободном состоянии перед подачей “Старт”-условия
Фиксация”Старт”- условия tHD;STA 4,0 мкс минимальное время от подачи “Старт”- условия до начала первого такта передачи
Готовность”Стоп”- условия tSU;STO 4,0 мкс минимальное время, через которое можно подавать “Стоп”- условие после освобождения шины Clock
Длительность LOW полупер. шины Clock tLOW 4,7 мкс минимальная длительность полупериода установки данных (когда на шине Clock низкий уровень)
Длительность HIGH полупер. шины Clock tHIGH 4,0 мкс минимальная длительность полупериода считывания данных (когда на шине Clock высокий уровень)
Удержание данных tHD;DAT то есть данные на шину Data можно выставлять сразу после спада на линии Clock
Готовность данных tSU;DAT 250 нс то есть поднимать уровень на шине Clock можно не ранее 250 нс после установки данных на шине Data

Минимальные значения времени в таблице указаны для максимальной скорости передачи 100 кбит/с.

Программная реализация мастер-абонента шины I2C в режиме single-master, библиотеки процедур: для PIC, для AVR

Программа для устройства копирования микросхем памяти 24Cxx (здесь можно посмотреть пример использования приведённых выше библиотек для реализации режима I2C-Master на PIC-контроллере)

Программа 2 для контроллера I2C-шлюза, режим Slave из терминалки ПК (а тут посмотреть пример того, как можно сделать I2C-Slave на контроллере AVR)

Источник: http://radiohlam.ru/?p=1024

Передача данных. Протокол I2C

?Valentin_Levchatkin (varyag_nord) wrote,
2016-08-19 17:57:00Valentin_Levchatkin
varyag_nord
2016-08-19 17:57:00I2C (Inter-Integrated Circuit) — последовательная шина данных для связи интегральных схем, использующая две двунаправленные линии связи (SDA и SCL).

Используется для соединения низкоскоростных периферийных компонентов с материнской платой, встраиваемыми системами и мобильными телефонами.Иногда эту шину называют “квадратичной” или “квадратной” или “Ай-Ту-Си”Микроконтроллер на рисунке это ведущий элемент (Master1) им может быть процессор.

На рисунке представлено 3 ведомых перефириных элемента Slave В качествеSlave могут быть память, ЦАП, АЦП и пр. К шине может быть подключено до 127 устройств.Процессор с памятью соединен в данном случае по двум шинам:

SDA (Serial DATA)- шина последовательной передачи данных.

Данные по этой шине могут передаваться в двух направлениях.

SCL (Serial Clock) – шина по которой идет тактирование шины данных. Шина синхронизации данных. Она также определяет в какой момент куда пойдут данные. В схеме Master-Master первым битом определяется, кто займет главную роль.
Скорость передачи данных. Так как  передаются по 1 биту за 1 такт, то скорость передачи данных составляет 1/8 от тактовой частоты.
Состояние СТАРТ и СТОППроцедура обмена начинается с того, что ведущий формирует состояние СТАРТ: генерирует переход сигнала линии SDA из ВЫСОКОГО состояния в НИЗКОЕ при ВЫСОКОМ уровне на линии SCL. Этот переход воспринимается всеми устройствами, подключенными к шине, как признак начала процедуры обмена. Генерация синхросигнала — это всегда обязанность ведущего; каждый ведущий генерирует свой собственный сигнал синхронизации при пересылке данных по шине. Процедура обмена завершается тем, что ведущий формирует состояние СТОП — переход состояния линии SDA из низкого состояния в ВЫСОКОЕ при ВЫСОКОМ состоянии линии SCL. Состояния СТАРТ и СТОП всегда вырабатываются ведущим.Считается, что шина занята после фиксации состояния СТАРТ. Шина считается освободившейся через некоторое время после фиксации состояния СТОП. При передаче посылок по шине I²C каждый ведущий генерирует свой синхросигнал на линии SCL. После формирования состояния СТАРТ ведущий опускает состояние линии SCL в НИЗКОЕ состояние и выставляет на линию SDA старший бит первого байта сообщения. Количество байт в сообщении не ограничено. Спецификация шины I²C разрешает изменения на линии SDA только при НИЗКОМ уровне сигнала на линии SCL. Данные действительны и должны оставаться стабильными только во время ВЫСОКОГО состояния синхроимпульса. Для подтверждения приёма байта от ведущего-передатчика ведомым-приёмником в спецификации протокола обмена по шине I²C вводится специальный бит подтверждения, выставляемый на шину SDA после приёма 8 бита данных.

Подтверждение

Таким образом передача 8 бит данных от передатчика к приёмнику завершаются дополнительным циклом (формированием 9-го тактового импульса линии SCL), при котором приёмник выставляет низкий уровень сигнала на линии SDA, как признак успешного приёма байта.

Подтверждение при передаче данных обязательно, кроме случаев окончания передачи ведомой стороной. Соответствующий импульс синхронизации генерируется ведущим. Передатчик отпускает (переводит в ВЫСОКОЕ состояние) линию SDA на время синхроимпульса подтверждения.

Приёмник должен удерживать линию SDA в течение ВЫСОКОГО состояния синхроимпульса подтверждения в стабильном НИЗКОМ состоянии.

В том случае, когда ведомый-приёмник не может подтвердить свой адрес (например, когда он выполняет в данный момент какие-либо функции реального времени), линия данных должна быть оставлена в ВЫСОКОМ состоянии. После этого ведущий может выдать состояние СТОП для прерывания пересылки данных.

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

Синхронизация

Синхронизация выполняется с использованием подключения к линии SCL по правилу монтажного И. Это означает, что ведущий не имеет монопольного права на управление переходом линии SCL из НИЗКОГО состояния в ВЫСОКОЕ.

В том случае, когда ведомому необходимо дополнительное время на обработку принятого бита, он имеет возможность удерживать линию SCL в низком состоянии до момента готовности к приёму следующего бита. Таким образом, линия SCL будет находиться в НИЗКОМ состоянии на протяжении самого длинного НИЗКОГО периода синхросигналов.

Устройства с более коротким НИЗКИМ периодом будут входить в состояние ожидания на время, пока не кончится длинный период. Когда у всех задействованных устройств кончится НИЗКИЙ период синхросигнала, линия SCL перейдет в ВЫСОКОЕ состояние. Все устройства начнут проходить ВЫСОКИЙ период своих синхросигналов.

Первое устройство, у которого кончится этот период, снова установит линию SCL в НИЗКОЕ состояние. Таким образом, НИЗКИЙ период синхролинии SCL определяется наидлиннейшим периодом синхронизации из всех задействованных устройств, а ВЫСОКИЙ период определяется самым коротким периодом синхронизации устройств.

Механизм синхронизации может быть использован приёмниками как средство управления пересылкой данных на байтовом и битовом уровнях.

На уровне байта, если устройство может принимать байты данных с большой скоростью, но требует определенное время для сохранения принятого байта или подготовки к приёму следующего, то оно может удерживать линию SCL в НИЗКОМ состоянии после приёма и подтверждения байта, переводя таким образом передатчик в состояние ожидания.На уровне битов устройство, такое, как микроконтроллер без встроенных аппаратных цепей I²C или с ограниченными цепями, может замедлить частоту синхроимпульсов путём продления их НИЗКОГО периода. Таким образом скорость передачи любого ведущего адаптируется к скорости медленного устройства.

Адресация в шине I²C

Каждое устройство, подключённое к шине, может быть программно адресовано по уникальному адресу. Для выбора приёмника сообщения ведущий использует уникальную адресную компоненту в формате посылки.

При использовании однотипных устройств ИС часто имеют дополнительный селектор адреса, который может быть реализован как в виде дополнительных цифровых входов селектора адреса, так и в виде аналогового входа.При этом адреса таких однотипных устройств оказываются разнесены в адресном пространстве устройств, подключенных к шине.В обычном режиме используется 7-битная адресация.

Процедура адресации на шине I²C заключается в том, что первый байт после сигнала СТАРТ определяет, какой ведомый адресуется ведущим для проведения цикла обмена. Исключение составляет адрес «Общего вызова», который адресует все устройства на шине. Когда используется этот адрес, все устройства в теории должны послать сигнал подтверждения.

Однако устройства, которые могут обрабатывать «общий вызов», на практике встречаются редко.Первые семь битов первого байта образуют адрес ведомого. Восьмой, младший бит, определяет направление пересылки данных. «Ноль» означает, что ведущий будет записывать информацию в выбранного ведомого. «Единица» означает, что ведущий будет считывать информацию из ведомого.

После того, как адрес послан, каждое устройство в системе сравнивает первые семь бит после сигнала СТАРТ со своим адресом. При совпадении устройство полагает себя выбранным как ведомый-приёмник или как ведомый-передатчик, в зависимости от бита направления.Адрес ведомого может состоять из фиксированной и программируемой части.

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

Иногда используется один вывод с аналоговой установкой программируемого диапазона адресов[1]. При этом в зависимости от потенциала на этом адресном выводе ИМС, возможно смещение адресного пространства драйвера так, чтобы однотипные ИМС не конфликтовали между собой на общей шине.

Все специализированные ИМС, поддерживающие работу в стандарте шины I²C, имеют набор фиксированных адресов, перечень которых указан производителем в описаниях контроллеров.Комбинация бит 11110ХХ адреса зарезервирована для 10-битной адресации.

Как следует из спецификации шины, допускаются как простые форматы обмена, так и комбинированные, когда в промежутке от состояния СТАРТ до состояния СТОП ведущий и ведомый могут выступать и как приёмник, и как передатчик данных. Комбинированные форматы могут быть использованы, например, для управления последовательной памятью.

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

Поэтому в любом случае лучший способ избежать неконтролируемой ситуации на шине перед использованием новой (или ранее не используемой) ИМС — следует тщательно изучить её описание (datasheet или reference manual), получив его с сайта производителя. Более того, производители часто размещают рядом более подробные инструкции по применению.В любом случае по спецификации шины все разрабатываемые устройства должны сбрасывать логику шины при получении сигнала СТАРТ или повторный СТАРТ и подготавливаться к приёму адреса.

Тем не менее, основные проблемы с использованием I²C шины возникают именно из-за того, что разработчики, «начинающие» работать с I²C шиной, не учитывают того факта, что ведущий (часто — микропроцессор) не имеет монопольного права ни на одну из линий шины.

Первый стандарт работал на частоте 100 КГц (Standart) Скорость – 100 Кбит/с или 12,5 КБ/с
Затем частота увеличилась до 400 КГц (Fast) Скорость – 400 Кбит/с или 50 КБ/с
Следующий стандарт ввел новые скорости и частоты 1,7 или 3,4 МГц (High) Скорость – (1,7 Мбит/с или 3,4 Мбит/с) 500 КБ/с или 1000 КБ/с
В случаях когда этих скоростей недостаточно используется более быстрый интерфейс SPI- В покое На шине постоянно положительный потенциал (~3В или 5В но могут быть и другие). А процессор понижая потенциал дает команду на переход к готовности . Для поддержания положительного потенциала возле шины ставяться подтягивающие резистоы (Vdd см. рисунок) на плюсовое питание по обеим линиям. Обчно ставять резисторы на 10 КОм на +3,3 В1. Связь процессора с памятью (чаще EEPROM)    2. HDMI и DVI интерфейсы (для передачи служебной информации от телевизора к устройству которое воспроизводит видеоконтент, либо для передачи информации от монитора к компьютеру для передачи информации, что за монитор подключили с какими характеристикаи, передача информации от термостата ЦП или информация о скорости вращения кулера и т.д.)    3. Микросхемы и карты памяти (EEPROM, RAM, FERAM, Flash);    4. Доступ к низкоскоростным ЦАП/АЦП;    5. Регулировка контрастности, насыщенности и цветового баланса мониторов;    6. Регулировка звука в динамиках;    7. Управление светодиодами, в том числе в мобильных телефонах;    8. Чтение информации с часов реального времени (кварцевых генераторов);    9. Управление включением/выключением питания системных компонент;    10. Клавиатуры    11. Информационный обмен между микроконтроллерами;

Пример системы с шиной I²C:

На рисунке (Кликабельно):

(a) Высокоинтегрированный телевизор

    Микроконтроллер    ФАПЧ-синтезатор    Флеш-память    Мультисистемный декодер сигналов цветности    Стереодекодер звука    Улучшитель сигнала картинки    Hi-Fi аудиопроцессор    Аналоговый видеопроцессор    Декодер телетекста    ИМС сигналов OSD

(b) базовая станция радиотелефона стандарта DECT

    Генератор DTMF    Интерфейс телефонной линии    Кодек АДИКМ    Пакетный контроллер    МикроконтроллерЧастые проблемы на шине и их диагностика:Первое что надо проверить после БП и тактирования на кварце

Источник: https://varyag-nord.livejournal.com/64186.html

Интерфейс I2C

Наконец, подобрались к I2C. Давно хотелось, но всё никак. Тема интересная, а возможности периферии общающейся по этому протоколу могут существенно расширить возможности микроконтроллерной системы.

I2C, в отличии от , позволяет наращивать функционал, добавлять новые блоки без изменения в схеме и не задействуя новые выводы МК — настоящий конструктор — стыкуй что и сколько надо =)

I2C (Inter-Integrated Circuit — примерно «Схема внутренней связи» =), читается “и-два-цэ” — последовательная шина выдуманная в недрах Philips ещё в 80-х годах прошлого века. Задумывалась, как простая шина для связи блоков внутри устройства — получилось, и на удивление удачно=)

Сегодня, каждый производитель выпускающий МК уровнем чуть выше нулевого суёт туда аппаратный I2C, правда Philips запатентавал название и до 2007 года все выдумывали своим велосипедам имена кто во что горазд: у ATmega, например, этот модуль завётся 2-wire Serial Interface. Производители законченных блоков и модулей, зачастую, используют именно I2C для общения с внешним миром (блоки телевизоров, магнитол, дисплеи, некоторые камеры в мобильных телефонах и т.п.), а микросхем периферии вообще на любой вкус: АЦП/ЦАП памяти разнообразные, часы реального времени, расширители вводо-выводов, гироскопы, акселерометры, компасы, драйверы светодиодов и матриц, ШИМ-контроллеры, синтезаторы частот и вообще, по-моему, всё что душе угодно. Затыков у этой чудо шины два: скорость работы и ограничение на число адресов в сети. Классически это 100 кбит/с и 128 устройств. Но стандарт 1992 года предусматривает скорости как 100 кбит/с (low-speed), так и 400 кбит/с (fast-speed) и уже 10-битную адресацию т.е. максимум — 1203 адреса. А стандартом от 1998, раскрутили аж до 3.4 Мбит/с (Hs-mode). Но производители живут в прошлом веке и заглянув в датащит на атмеги увидим, что модуль 2-wire Serial Interface может раскочегарится до 400 кГц и адресовать только 127 устройств = Ну и хрен с ними, мне лично — за глаза, да и мороки с этим Hs-mode значительно. Адреса, обычно, жёстко “прошиты” в микросхему (см. датащиты), но частенько несколько бит адреса “выводят” на ножки — перемычками (на питание или землю) можно задать эти биты и подключить несколько одинаковых микросхем на одну шину. Физически, шина I2C представляет собой два провода (не считая земли и питания =), притянутые к плюсу резисторами 1-10к (так и только так!).

Один провод — шина данных(SDA — Serial DAta), второй — тактирование(SCS — Serial CLock).

И всё! Работает тоже почти бесхитростно:

На линии обычно есть один Мастер (Master) — МК и некоторое количество Слейвов (Slave) — периферийных устройств (возможна и многомастерная “архитектура”, но об этом позже).

Так как линии у нас подтянуты к питанию, то устройствам остаётся только прижимать их к земле, когда хочется передать нолик и просто отпустить — чтоб единицу.

Отсюда важный вывод о совместной работе устройств с таким включением (называется — монтажное “И”) — если кто-то выставил ноль — остальным придётся с этим смириться =)

Итак, тактирование (дрыганье SCL) всегда осуществляет мастер, передачу начинает тоже всегда он, предварительно уточнив, что линия свободна (единички на SDA и SCL), формирует СТАРТ-условие (S) — прижимает линию SDA (1->0), при еденице на SCL,Потом, надо передать адрес того устройства к которому мы хотим обратиться.

При передаче по I2C есть два правила: Во-первых, данные считываются только при единичном состоянии SCL, а меняться могут, только при нулевом состоянии SCL (выставили-держим-протолкнули-выставили следующий-держим-…).

Во-вторых, данные идут головой вперёд — начиная со старшего бита(MSB)7 битов адреса, восьмой — признак R/W — если хотим читать 1, записать 0. Прожевав восьмой бит, ведомая микросхема должна сказать уверенное “Ага”, если всё понятно — послать сигнал подтверждения (ack, acknowledge) — прижав линию SDA (отпущенную ведущим) на время 9-го такта на SCL.

Мастер с интересом это дело выслушает (и тактично подождёт если туговатая микросхема не сразу отпустит SDA) Если ack нет (называется nack) — значит ведомому что-то не понятно, тогда нужно(можно) сформировать СТОП и повторить передачу.

Затем, мастер либо посылает байт данных слейву, и снова дожидается подтверждения, либо принимает от него байт и уже сам выдаёт подтверждение. Байт данных может быть несколько, но все они когда-нибудь закончатся, и мастер должен будет сформировать СТОП-условие(P). Для этого надо отпустить линию SDA (0->1), не трогая SCL.

полный “текст” обращения (кликабельно):Всё просто=) СТАРТ-адрес(запись/чтение)-подтверждение-данные-подтверждение-СТОП
А если мастер читал данные, то, прочитав последний интересующий байт должен вместо последнего asc передать nack. Только такое вот, невежливое, завершение диалога понимает многие (или все? — см.

датащиты) периферийные микросхемы.
Так же, туговатая микросхема может придерживать линию SCL, демонстрируя, что не успевает глотать недожёванное, так что, перед подачей очередного такта, мастер должен проверить свободно ли, и если нет — подождать.

Есть ещё такой режим — комбинированный.

Это когда мастер, прочитав что-нибудь, не освобождая линию,(не формируя СТОП) генерит прям сразу ещё один СТАРТ и лезет писать. Такой хамский старт называется повторным — ПОВСТАРТ (repeated Start, Sr). Делается это, обычно, для указания «внутреннего» адреса периферийной микросхемы — например: послали адрес EEPROM-ины, сказали что намерены читать, потом ПОВСТАРТ и адрес ячейки откуда хотим считать

Есть ещё режим много-мастерной(multi-master) работы — тут сильно выручает соединение “монтажное И”.

А для реализации, непосредственно демократии, на шине действуют ещё и правила джунглей синхронизации и арбитража. Эти правила построены на непрерывном самоконтроле мастерами результатов своей деятельности — отпустит линию — и тут же смотрит — отпустилась? Если — отпустилась, то всё хорошо и он тут пока главный, если нет (кто-то держит линию) — есть мастера потолще, надо свалить. Естественно, каждый мастер перед началом бурной деятельности по раздаче команд и чтению данных проверяет не занимает ли линию кто-нибудь столь же мастеровитый, и если занимает то тактично ждёт просветов. А если одновременно, сразу несколько, посмотрели — свободно — воздуха побольше набрали и давай… вещать? Тут они начинают мериться=) Во-первых, тактирование. Естественно, все мастера ломанутся дёргать SCL самостоятельно, они ж мастера=) Вот только пока самые резвые (начавшие первыми) сгенерировав первый такт, отпустят линию — более тормозные и неторопливые будут её держать, отпуская по одному, пока не найдётся самый главный тормоз — начавший вещать последним, он то и продолжит, а остальные останутся нервно ждать. Но, может так случится, что два особо однояйцевых мастера синхронно сгенерят СТАРТ условие. Тогда опять начнётся затяжной заплыв с мериньем. Будут гнать в линию SDA свои нолики и единицы синхронно, пока не обнаружится разница в задуманном — тот кто захочет выставить единицу будет традиционно обломан тем, кто решил в этот момент послать нолик. Обламавшийся перейдёт в ожидание, а тот кто сказал 0 первым — продолжит. В общем, “0” в I2C решает, на этом всё и держится =) Дополнительно, для погружения в тему, рекомендую книжку:

Семёнов Б.Ю. «Шина I2C в радиотехнических конструкциях»

А также, перевод

Далее:

Ccылки

По теме

Источник: http://robocraft.ru/blog/communication/780.html

Интерфейс I2C и Arduino

В этой статье мы рассмотрим, что такое интерфейс I2C (ай-ту-си, и-два-цэ), в чём его особенности и как с ним работать.

  • Arduino;
  • цифровой потенциометр AD5171;
  • светодиод;
  • резистор на 220 Ом;
  • 2 резистора по 4,7 кОм;
  • соединительные провода.

Последовательный протокол обмена данными IIC (также называемый I2C – Inter-Integrated Circuits, межмикросхемное соединение) использует для передачи данных две двунаправленные линии связи, которые называются шина последовательных данных SDA (Serial Data) и шина тактирования SCL (Serial Clock). Также имеются две линии для питания. Шины SDA и SCL подтягиваются к шине питания через резисторы.

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

У каждого ведомого устройства есть уникальный адрес, по которому ведущий и обращается к нему. Адрес устройства указывается в паспорте (datasheet). К одной шине I2C может быть подключено до 127 устройств, в том числе несколько ведущих. К шине можно подключать устройства в процессе работы, т.е.

она поддерживает «горячее подключение».

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

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

Мастер инициирует обмен. Для этого он начинает генерировать тактовые импульсы и посылает их по линии SCL пачкой из 9-ти штук.

Одновременно на линии данных SDA он выставляет адрес устройства, с которым необходимо установить связь, которые тактируются первыми 7-ми тактовыми импульсами (отсюда ограничение на диапазон адресов: 27 = 128 минус нулевой адрес).

Следующий бит посылки – это код операции (чтение или запись) и ещё один бит – бит подтверждения (ACK), что ведомое устройство приняло запрос. Если бит подтверждения не пришёл, на этом обмен заканчивается. Или мастер продолжает посылать повторные запросы.

Это проиллюстрировано на рисунке ниже. Задача такая: подключиться к ведомому устройству с адресом 0x27 и передать ему строку “SOLTAU.RU”. В первом случае, для примера, отключим ведомое устройство от шины. Видно, что мастер пытается установить связь с устройством с адресом 0x27, но не получает подтверждения (NAK). Обмен заканчивается.

Попытка мастера установить соединение с ведомым по I2C

Теперь подключим к шине I2C ведомое устройство и повторим операцию. Ситуация изменилась. На первый пакет с адресом пришло подтверждение (ACK) от ведомого. Обмен продолжился.

Информация передаётся также 9-битовыми посылками, но теперь 8 битов занимают данные и 1 бит – бит подтверждения получения ведомым каждого байта данных.

Если в какой-то момент связь оборвётся и бит подтверждения не придёт, мастер прекратит передачу.

Временная диаграмма обмена по протоколу I2C

2Реализация I2Cв Arduino

Arduino использует для работы по интерфейсу I2C два порта. Например, в Arduino UNO и Arduino Nano аналоговый порт A4 соответствует SDA, аналоговый порт A5 соответствует SCL.

Реализация I2C в Arduino UNO и Nano

Для других моделей плат соответствие выводов такое:

ПлатаПин SDAПин SCL
Arduino Uno, Nano, Pro и Pro Mini A4 A5
Arduino Mega 20 21
Arduino Leonardo 2 3
Arduino Due 20, SDA1 21, SCL1

3Библиотека “Wire” для работы с IIC

Для облегчения обмена данными с устройствами по шине I2C для Arduino написана стандартная библиотека Wire. Она имеет следующие функции:

ФункцияНазначение
begin(address) инициализация библиотеки и подключение к шине I2C; если не указан адрес, то присоединённое устройство считается ведущим; используется 7-битная адресация;
requestFrom() используется ведущим устройством для запроса определённого количества байтов от ведомого;
beginTransmission(address) начало передачи данных к ведомому устройству по определённому адресу;
endTransmission() прекращение передачи данных ведомому;
write() запись данных от ведомого в ответ на запрос;
available() возвращает количество байт информации, доступных для приёма от ведомого;
read() чтение байта, переданного от ведомого ведущему или от ведущего ведомому;
onReceive() указывает на функцию, которая должна быть вызвана, когда ведомое устройство получит передачу от ведущего;
onRequest() указывает на функцию, которая должна быть вызвана, когда ведущее устройство получит передачу от ведомого.

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

Давайте посмотрим, как работать с шиной I2C с помощью Arduino.

Сначала соберём схему, как на рисунке. Будем управлять яркостью светодиода, используя цифровой 64-позиционный потенциометр AD5171, который подключается к шине I2C. Адрес, по которому мы будем обращаться к потенциометру – 0x2c (44 в десятичной системе).

Подключение цифрового потенциометра к Arduino по шине I2C

5Управление устройством по шине IIC

Теперь откроем из примеров библиотеки “Wire” скетч: Файл Образцы Wire digital_potentiometer. Загрузим его в память Arduino.

#include // подключаем библиотеку “Wire” void setup() { Wire.begin(); // подключаемся к шине I2C как мастер } byte val = 0; // значение для передачи потенциометру void loop() { Wire.beginTransmission(44); // начало передачи устройству с адресом “44” (0x2c) Wire.write(byte(0x00)); // посылаем байт инструкции Wire.write(val); // посылаем потенциометру значение Wire.endTransmission(); // конец передачи val++; // инкрементируем val на 1 if (val == 64) { // по достижении максимума потенциометра val = 0; // сбрасываем val до нуля } delay(500); }

После включения вы видите, как яркость светодиода циклически нарастает, а потом гаснет. При этом мы управляем потенциометром с помощью Arduino по шине I2C.

6Дополнительно о шине I2C

Доступно и интересно рассказывает о шине I2C Джереми Блюм в своём видео:

Источник: https://soltau.ru/index.php/en/arduino/item/371-interfejs-i2c-i-arduino

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}