I2C отладчик – Proteus8.x + MSP430x2xx: программная реализация I2C интерфейса, подключение устройств: RTC DS1307/DS3231, EEPROM AT24C512/AT24C32

Отладчик i2c SPI 1-wire :AVR devices

После того как NXP прислали мне кучу всяких микросхем с интерфейсом i2c, я начал их раскуривать некоторые из них. Как известно работа с i2c устройствами сводится к тому, чтоб записать или считать значения хранящиеся в определённых регистрах микросхемы. Обычно на время изучения какой либо микрухи я городил на своей отладочной плате небольшой макет из контроллера, программатора, RS232<-> UART преобразователя и непосредственно самой микросхемы. Через компьютер посылаются команды и контроллер что-то передаёт по шине i2c или наоборот читает, отправляет стартовые и стоповые посылки итд. Примерно таким же образом у меня происходит процесс изучение микросхем с интерфейсами SPI и 1-wire. Чтоб не городить каждый раз тестовый макет было принято решение собрать универсальный отладчик с поддержкой протоколов i2c SPI и 1-wire.

Сердцем девайса является микроконтроллер атмега8 в дип корпусе. Почему в дип? Потому что я давно мечтал его куда-то пристроить т.к. выводные детали мной уже почти не используются. Контроллер работает на частоте 8 МГц, этой частоты вполне достаточно да и при пониженном напряжении питания он должен работать вполне стабильно если верить даташиту. У отладчика существуют два рабочих напряжения: 3.3 вольта и 5 вольт. Сделано это для того чтоб не мучиться с согласованием логических уровней у микросхем которые питаются от 3.3 вольт.  Пониженное напряжение создаётся low drop стабилизатором и включается тумблером на плате. Вторая немаловажная микросхема это преобразователь интерфейса USB — UART на новой для меня микросхеме CP2102. Микросхема хорошо себя зарекомендовала: Ком порт не отваливается, скорость передачи данных высокая. И конечно цена тоже вполне адекватная (~2.5$).  Короче вполне достойная альтернатива FT232. Если нет свободного USB порта но есть лишний ком порт, то вполне запросто можно выкинуть эту микросхему и сделать преобразователь уровней на MAX232. Сойдет даже вот такой самодельный преобразователь интерфейсов о котором я писал ранее. Скажу сразу что микросхема очень мелкая:

Запаять такое с феном не проблема, на счёт паяльника ничего сказать не могу. Запаивать её нужно так: На контактные площадки равномерно наносятся крошечные шарики припоя. Потом всё это дело щедро смазывается флюсом (я юзал обычный СКФ). После этого надо чтоб флюс немного подсох для загустения. Теперь самое важное — аккуратно поставить микросхему. За счёт флюса она прилипнет и никуда теперь не денется. После этого берем фен и греем до полного припаивания. Греть надо осторожно, следить чтоб флюс не закипал и не брызгался, в противном случае микросхему просто может сместить с её места брызгами. Кстати в процессе работы микросхема тёплая самую малость (едва уловимо если трогать рукой). Кроме этих двух микросхем почти ничего интересного больше в схеме нет:

Для шины i2c и 1-wire нужна подтяжка. В данном устройстве она программно отключаемая, т.к. это весьма удобном потому что иногда эти резисторы уже могут быть впаяны в плату с какой либо i2c или 1-wire микросхемой. Так же есть возможность программно управлять питанием подключенного устройства. Для этого служит транзистор T1. Ставить можно любой p-n-p лишь бы тянул через себя нужный ток.  Так же в устройстве есть три светодиода: Зеленый — индикатор питания, Желтый — индикатор активности и Красный индикатор питания подключаемого устройства. В устройстве предусмотрена простенькая защита от короткого замыкания в виде токоограничивающих резисторов на тех линиях микроконтроллера которые являются выходами. Кроме линий входящих в интерфейсы i2c SPI и 1-wire так же присутствует линия f1. Её состояние может управляться программно. Пока не знаю для чего её использовать, просто сделал на будущее. Поскольку корпуса у меня пока нет, (он в пути) то пока юзаю голую платку. Все детали кроме контроллера в SMD исполнении:

Самое сложное в этом устройстве это софт. Поскольку в процессе написания прошивки приходилось часто перепрошивать контроллер, то я впервые решил воспользоваться загрузчиком который совместим с программой прошивальщиком AVRPROG которая входит в состав AVR студии. Для того чтоб прошить контроллер в устройстве нужно подсоединить его к порту USB и в течении семи секунд пока горят все три светодиода, запустить прошивальщик. Если всё ок то выскочит окно с интуитивно понятным интерфейсом где нужно выбрать прошивку и нажать кнопку «прошить». Если прошивальщик не видит устройства то нужно поменять номер ком пора у вашего устройства. Желательно установить его в первом десятке ком портов. У меня например он висит на COM5 и всё отлично работает. Если программа для управления отладчиком не хочется конектиться к устройство, то причины и средства устранения те же — сменить номер порта в диспетчере устройств. Прошивка самого устройства не сильно замысловатая: Её задача просто напросто принимать байт по UART и определённым образом дрыгать ногами микроконтроллера. Написана она на микропаскале и подробно рассматриваться тут не будет. Исходник доступен — можете посмотреть сами что там и как. (Больше не доступен. Если очень надо — пишите на почту.) А вот про управляющую программу для компа стоит рассказать подробнее. Существуют три режима работы, по одному на каждый интерфейс: i2c, 1-wire и SPI. О каждом режиме по порядку:

I2C

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

  • i2c_start — отправляет стартовую посылку
  • i2c_stop — отправляет стоповую посылку
  • i2c_write — отправляет байт в шину i2c
  • i2c_read — читает байт из шины i2c
  • i2c_read_last — читает последний байт из шины i2c

Кроме стандартных, было реализованы две дополнительные команды облегчающих работу с шиной:

  • i2c_write_reg — записать определённые данные в определённый регистр
  • i2c_read_reg  — прочитать данные из определённого регистра

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

  • i2c_pullup_on — включить подтяжку
  • i2c_pullup_off  — выключить подтяжку

Для любого из трёх режимов существуют три одинаковые команды:

  • delay — задерживает выполнение следующей команды на заданное время
  • power_on — включает питание подключенного устройства
  • power_off — отключает питание

Сейчас к отладчику подключена платка часов реального времени. На часах 15:47:33.

1-wire

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

  • 1-wire_read — читаем байт из шины
  • 1-wire_write — пишем байт
  • 1-wire_reset — подаем в шину импульс сброса
  • 1-wire_pullup_on — подтянуть шину
  • 1-wire_pullup_off — выключить встроенную подтяжку

Поскольку ничего с данным интерфейсом кроме датчика DS18B20 у меня не было то подключил его:

Сейчас датчик показывает температуру 26 градусов выше ноля.

SPI

Команды вполне очевидные:

  • spi_read — читаем байт из SPI
  • spi_write — пишем байт
  • spi_set_cs_1 — устанавливаем ChipSelect в единицу
  • spi_set_cs_0 устанавливаем ChipSelect в ноль

Ни какого девайса со SPI интерфейсом под руку не попалось, но судя по показаниям осциллографа всё работает адекватно.  Поэтому картинки тут не будет 🙂

Чтоб всё заработало, нужно установить фьюзы.  Есть два варианта настройки фьюзов:  С использованием загрузчика  и без его использования. Пока я отлаживал весь этот софт, контроллер прошивался бесчисленное количество раз и постоянно подключать программатор мне надоело и я залил загрузчик. Это позволило прошивать контроллер прямо через USB порт. Загрузчик совместимый с AvrProg (есть в папке с AVR студией). Рекомендую сделать так же. Для того чтоб юзать загрузчик нужно прошить фьюзы так:

После включения устройства с прошитым загрузчиком все три светодиода будут гореть около 7 секунд. За это время нужно успеть запустить AvrProg.  Если прошивальщик обнаружил загрузчик то откроется окно в котором нужно просто выбрать файл прошивки и нажать запись.

Если возможность прошивки через USB вам не нужна, то фьюзы можно ставить так:

Ни каких других настроек не требуется. Ну разве что указать номер порта в настройках программы.

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

Скачать файлы проекта

avrdevices.ru

AVR: Передача данных по шине I²C (I2C, IIC, TWI)

Налаживаем обмен данными между двумя контроллерами по шине I²C

С вашего разрешения я не буду вас томить всякими теоретическими копипастами и сразу перейдем к практической части.

Не, серьезно, почти каждый сайт об электронике содержит статью по этому протоколу, причем одну и ту же :).

Шина I²C состоит из двух линий:

  • SCL — линия последовательной передачи синхроимпульсов («при передаче посылок по шине I2C каждый ведущий генерирует свой синхросигнал на линии SCL» — http://ru.wikipedia.org/wiki/I%C2%B2C)
  • SDA — линия последовательной передачи данных

Эти линии обозначены на схемах выводов контроллера (pinout-схемы) в скобочках. К примеру, на mega16: PC1(SDA), PC0(SCL).

ATMEGA16-pinout

Если таких выводов на схеме не наблюдается, то скорее всего, в кристалл этот самый интерфейс шины I²C (точнее, модуль TWI — более подробно о I2C и TWI читайте в статье про 24CXX_EEPROM, см. в конце статьи) не интегрирован, т.е. аппаратной поддержки этого интерфейса нету и такой контроллер не способен обмениваться данными по этой шине.

Для статьи я выбрал два наиболее распространненных контроллера, имеющие этот интерфейс — ATMEGA16(пусть он будет у нас ведущим устройством) и ATMEGA8(а он будет ведомым).

Бибилиотека avr-libc, входящая в состав WinAVR, не содержит каких-либо готовых сорцев для работы с I²C (кстати там есть демонстрационный исходник для работы с «24Cxx I²C EEPROM» — /avr-libc/examples/twitest/twitest.c).

На вооружение я брал 2 различных исходника:

  • один предлагают специалисты компании Atmel в апноутах (AVR315 Использование модуля TWI в качестве ведущего интерфейса I2C и AVR311 Использование модуля TWI в качестве подчиненного интерфейса I2C)
  • другой принадлежит мистеру Pascal Stang, автору известного набора джентльмена Procyon AVRlib.

Более удобным оказался исходник из библиотеки Procyon AVRlib — в одном файле реализована поддержка и Master, и Slave устройств (в отличие от двух различных файлов в апноутах Atmel), а также подкупила простая и удобная процедура приема данных у slave-устройства. Извините, я уже забежал вперед.

  • i2c.c и i2c.h — главное, что нам надо, однако в этих файлах есть ссылки на другие заголовочные файлы из библиотеки:
  • i2cconf.h — так-то в нем ваще ничо нет :), кроме двух define-ов
  • global.h — в нем определены F_CPU и CYCLES_PER_US + еще 2 заголовочных файла:
  • avrlibdefs.h — часто всеми используемые упрощения clearbit, setbit и тому подобное
  • avrlibtypes.h — здесь переопределены типы, например «typedef unsigned char  u08;» и т.д.

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

Всего нам понадобятся две прошивки — для ведомого устройства ATMEGA16 и для подчиненного ATMEGA8.

nagits.wordpress.com

I2C интерфейс: описание на русском

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

  • определенный «умный» узел управления, который в преимущественном большинстве случаев представляет собой однокристалльную микроЭВМ;
  • узлы общего назначения наподобие буферов ЖК, ОЗУ, портов ввода/вывода, ЭСПЗУ или же специализированные преобразователи данных;
  • специфические узлы, включающие в себя схемы цифровой настройки и обрабатывания сигналов для видео- и радиосистем.

Как оптимизировать их применение?

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

На сегодняшний день ассортимент указанного производителя включает в себя более 150 КМОП, а также биполярных устройств, совместимых с I2C и предназначенных для ведения работы в любых перечисленных категориях. При этом стоит отметить, что интерфейс I2C является изначально встроенным во все совместимые устройства, за счет чего они и могут безо всяких сложностей поддерживать связь между собой при использовании специальной шины. За счет применения такого конструкторского решения получилось решить достаточно большое количество проблем сопряжения различного оборудования, что является довольно характерным для сферы разработки цифровых систем.

Основные преимущества

Даже если посмотреть кратко описание интерфейсов UART, SPI, I2C, можно выделить следующие преимущества последнего:

  • Для работы нужно всего две линии – синхронизации и данных. Любое устройство, которое подключается к такой шине, в дальнейшем может программно адресоваться по абсолютно уникальному адресу. В любой момент существует простое отношение, позволяющее ведущим работать в качестве ведущего-передатчика или ведущего-приемника.
  • Данная шина предусматривает возможность иметь сразу несколько ведущих, предоставляя все необходимые средства для определения коллизий, а также арбитраж, позволяющий предотвратить повреждение данных в том случае, если два или большее количество ведущих начинает одновременно передавать информацию. В стандартном режиме предусматривается только передача последовательных восьмибитных данных при скорости не более 100 кбит/с, а в быстром режиме этот порог может быть увеличен в четыре раза.
  • В микросхемах используется специальный встроенный фильтр, который достаточно эффективно подавляет всплески и обеспечивает максимальную целостность данных.
  • Предельно возможное количество микросхем, которые могут быть подсоединены к одной шине, ограничивается только ее предельно возможной емкостью, составляющей 400 пФ.

Преимущества для конструкторов

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

Есть масса преимуществ, которые выделяют интерфейс I2C. Описание, в частности, позволяет увидеть следующие достоинства для конструкторов:

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

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

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

Преимущества для технологов

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

  • Стандартная двухпроводная последовательная шина с таким интерфейсом позволяет минимизировать соединения между микросхемами, то есть в них присутствует меньше контактов и требуется меньшее количество дорожек, благодаря чему печатные платы становятся не такими дорогими и имеют гораздо меньшие габариты.
  • Полностью интегрированный I2C интерфейс LCD1602 или какой-то другой вариант полностью устраняет необходимость в использовании дешифраторов адреса, а также другой внешней мелкой логике.
  • Предусматривается возможность использования одновременно нескольких ведущих на такой шине, благодаря чему существенно ускоряется тестирование и последующая настройка оборудования, так как шина может быть подключена к компьютеру сборочной линии.
  • Доступность совместимых с этим интерфейсом микросхем в VSO, SO и специализированном DIL-корпусе позволяет существенно снизить требования к размеру устройства.

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

Дальнейшая модернизация оборудования и расширение его функций могут осуществляться посредством стандартного подключения к шине соответствующей микросхемы, использующей 2C интерфейс Arduino или какой-нибудь другой из доступного перечня. Если требуется обеспечение большей ПЗУ, то в таком случае достаточно будет только выбрать другой микроконтроллер, имеющий увеличенный объем ПЗУ. Так как обновленные микросхемы при необходимости способны полностью заместить старые, можно запросто добавлять новые свойства в оборудование или повышать его общую производительность посредством обычного отсоединения уже устаревших микросхем и дальнейшей замены их на более новое оборудование.

ACCESS.bus

За счет того, что шина имеет двухпроводную природу, а также возможность программной адресации, для ACCESS.bus одной из наиболее идеальных платформ является именно I2C интерфейс. Спецификация (описание на русском представлено в статье) данного устройства делает его гораздо более дешевой альтернативой активно использующемуся ранее интерфейсу RS-232C для подсоединения различной периферии к компьютерам, используя стандартный четырехконтактный коннектор.

Введение в спецификацию

Для современных приложений 8-битного управления, в которых используются микроконтроллеры, предусматривается возможность установки некоторых конструкторских критериев:

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

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

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

Основная концепция

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

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

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

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

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

Общие параметры

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

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

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

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

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

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

Чтобы проверить работоспособность оборудования, можно попробовать ввести стандартные примеры скетчей для интерфейса I2C в Arduino, как на фото выше.

Арбитраж

Ведущим может начинаться пересылка информации только после полного освобождения шины, но при этом два и более ведущих могут провести генерирование сигнала о старте при времени минимального удерживания. Это в конечном итоге приводит к определенному сигналу «Старт» на шине.

Работа арбитража осуществляется на шине SDA в те моменты, пока SCL-шина пребывает в высоком состоянии. Если один из ведущих начинает передавать на линию данных низкий уровень, но при этом другой – высокий, то последний полностью отключается от нее, потому что состояние SDL является не соответствующим высокому состоянию его внутренней линии.

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

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

fb.ru

STM32. Использование I2C. | MicroTechnics

Довольно часто возникает необходимость связать микроконтроллер STM32 c другим микроконтроллером или с другим девайсом, например, внешней памятью. И тут на помощь приходит шина I2C, о которой до сих пор не было написано статьи на нашем сайте. Пора исправлять это недоразумение 😉

И снова для начала обсудим теоретические аспекты этой замечательной шины. Итак, I2C – последовательная шина данных, разработанная Philips около тридцати лет назад. Интерфейс I2С очень часто применяется в различных девайсах для реализации внутренней связи между устройствами. Возможные применения I2С включают, например:

• Обмен информацией между микроконтроллерами
• Доступ к модулям памяти
• Обмен данными с модулями АЦП
• Обмен данными с ЦАП

И это далеко не полный список. I2С гарантирует неплохую скорость работы при относительной простоте разработки и низкой себестоимости. К слову о скоростях:

• Обычный режим – до 100КГц
• Быстрый режим – до 400КГц

I2С использует две линии, которые подтянуты к напряжению питания. Одна линия – линия данных, другая – линия тактирования. Я не буду расписывать тут как работает I2С, потому что это уже много-много раз описано. Без труда можно найти в интернете материал на свой вкус =) А мы сразу перейдем к особенностям реализации I2С в STM32F.

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

• Каждое устройство может выступать как в роли Master, так и Slave
• В режиме Master реализуется:
o Генерация тактового сигнала
o Генерация старт-сигнала и стоп-сигнала
• В режиме Slave реализуется:
o Механизм подтверждения адреса
o Использование двух Slave адресов
o Обнаружение стоп-бита, выданного ведущим на линию
• Генерация и определение 7/10 битных адресов
• Поддержка разных скоростей передачи данных
• Наличие множества флагов, сигнализирующих о событиях, а также об ошибках на линии

Возможна работа в одном из следующих режимов:

• Slave приемник
• Slave передатчик
• Master приемник
• Master передатчик

По умолчанию установлен режим Slave, но как только устройство генерирует старт-бит оно сразу же превращается из подчиненного в ведущего.

Блок-схема модуля I2С:

Само собой на каждое событие I2С можно повесить прерывание, смотрите сами:

Для работы с I2С в STM32 выделено 9 регистров. Не будем на этом останавливаться сейчас подробно, но в даташит обязательно загляните )

А мы двинемся дальше и перейдем к практическому использованию интерфейса. Посмотрим, как реализована работа с I2С в Standard Peripheral Library. Как и для другой периферии, все настройки режима, скорости и всего остального находятся в заголовочном файле. Давайте смотреть. Находим там объявление структуры I2C_InitTypeDef:

typedef struct
{
  uint32_t I2C_ClockSpeed;          
 
  uint16_t I2C_Mode;                
 
  uint16_t I2C_DutyCycle;           
 
  uint16_t I2C_OwnAddress1;         
 
  uint16_t I2C_Ack;                 
 
  uint16_t I2C_AcknowledgedAddress; 
}I2C_InitTypeDef;

Вот с этими полями нам и придется играться, чтобы настроить интерфейс I2C так, как мы хотим:

uint32_t I2C_ClockSpeed – частота тактового сигнала, максимум – 400 КГц,

uint16_t I2C_Mode – тут все понятно, режим работы,

uint16_t I2C_DutyCycle – настройки для работы в быстром режиме,

uint16_t I2C_OwnAddress – собственный адрес устройства,

uint16_t I2C_Ack – включено или нет использование бита подтверждения Ack,

uint16_t I2C_AcknowledgedAddress – выбор формата адреса, 7 бит или 10 бит.

В принципе тут все очевидно 😉

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

/*******************************************************************/
GPIO_InitTypeDef gpio;
I2C_InitTypeDef i2c;
 
 
 
/*******************************************************************/
void init_I2C1(void)
{
    // Включаем тактирование нужных модулей
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 
    // А вот и настройка I2C
    i2c.I2C_ClockSpeed = 100000; 
    i2c.I2C_Mode = I2C_Mode_I2C;
    i2c.I2C_DutyCycle = I2C_DutyCycle_2;
    // Адрес я тут взял первый пришедший в голову 
    i2c.I2C_OwnAddress1 = 0x15;
    i2c.I2C_Ack = I2C_Ack_Disable;
    i2c.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C1, &i2c);
 
    // I2C использует две ноги микроконтроллера, их тоже нужно настроить
    gpio.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    gpio.GPIO_Mode = GPIO_Mode_AF;			
    gpio.GPIO_Speed = GPIO_Speed_50MHz;
    gpio.GPIO_OType = GPIO_OType_OD;
    gpio.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &gpio);
 
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);
 
    // Ну и включаем, собственно, модуль I2C1
    I2C_Cmd(I2C1, ENABLE);
}
 
 
 
/*******************************************************************/

С инициализацией разобрались, что же дальше? Давайте напишем функцию для начала общения по I2C. Хотелось бы сделать что-нибудь универсальное, поэтому в эту функцию мы будем передавать три параметра – номер используемого модуля I2C, направление передачи данных и адрес подчиненного устройства.

/*******************************************************************/
void I2C_StartTransmission(I2C_TypeDef* I2Cx, uint8_t transmissionDirection,  uint8_t slaveAddress)
{
    // На всякий слуыай ждем, пока шина осовободится
    while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
 
    // Генерируем старт - тут все понятно )
    I2C_GenerateSTART(I2Cx, ENABLE);
 
    // Ждем пока взлетит нужный флаг
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
 
    // Посылаем адрес подчиненному
    I2C_Send7bitAddress(I2Cx, slaveAddress, transmissionDirection);
 
    // А теперь у нас два варианта развития событий - в зависимости от выбранного направления обмена данными
    if(transmissionDirection== I2C_Direction_Transmitter)
    {
    	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    }
 
    if(transmissionDirection== I2C_Direction_Receiver)
    {
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    }
}
 
 
 
/*******************************************************************/

С этим разобрались, осталось написать главные функции – для приема и передачи данных!

/*******************************************************************/
void I2C_WriteData(I2C_TypeDef* I2Cx, uint8_t data)
{
    // Просто вызываем готоваую функцию из SPL и ждем, пока данные улетят
    I2C_SendData(I2Cx, data);
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
 
 
 
/*******************************************************************/
uint8_t I2C_ReadData(I2C_TypeDef* I2Cx)
{
    uint8_t data;
    // Тут картина похожа, как только данные пришли быстренько считываем их и возвращаем
    while( !I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    data = I2C_ReceiveData(I2Cx);
    return data;
}
 
 
 
/*******************************************************************/

Чуть не забыли важную часть! Закончив обмен данными по I2C, необходимо вызвать функцию I2C_GenerateSTOP(I2Cx, ENABLE). Не забываем про этот момент 😉

Вот так вот получилось. При использовании I2C для передачи данных, например, последовательность действий должна быть такой:
1. Инициализируем модуль I2C, нужные ножки контроллера, ну и все остальное
2. Посылаем “старт”
3. Шлем данные
4. Генерируем “стоп”
Как видите для всех этих пунктов мы уже подготовили специальные функции ) Поэтому на этом и остановимся на сегодня, до скорых встреч на сайте!

microtechnics.ru

AVR: РАБОТАЕМ С ВНЕШНЕЙ ПАМЯТЬЮ I2C EEPROM типа 24CXX

Для того чтобы полностью разобраться с Two-Wire Interface (TWI) , пишем с нуля в AVR STUDIO процедуры инициализации, чтения и записи. Подробно останавливаемся на каждом шаге и разбираемся. Затем промоделируем все в Proteus.

I. Кратко теория

Аппаратный модуль TWI и протокол I2C

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

 

Структура модуля TWI в микроконтроллерах AVR

Шина I2C состоит из двух проводов:

  • SCL (Serial Clock Line) – линия последовательной передачи тактовых импульсов.
  • SDA (Serial Data Line) – линия последовательной передачи данных.

К этой шине мы можем одновременно подключить до 128 микросхем.

 

Подключения к шине TWI

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

Как видно на блок-схеме, TWI условно состоит из четырех блоков. Вначале нам нужно будет настроить Генератор скорости связи, и мы сразу забудем про него. Основная работа – с Блоком управления.

Блок шинного интерфейса управляется Блоком управления, т.е. непосредственно с ним мы контактировать не будем. А Блок сравнения адреса нужен, чтобы задать адрес на шине I2C, если тока наш контроллер будет подчиненным устройством(ведомым) от другого какого-то контроллера или будет приемником от другого ведущего (как в статье Налаживаем обмен данными между двумя контроллерами по шине I²C на моем блоге). В этой статье он нам не нужен. Если хотите, почитайте про него в любом даташите контроллера серии MEGA.

Итак, наша задача сейчас разобраться с регистрами, входящими в Генератор скорости связи и Блок управления:

 Регистр скорости связи TWBR

 Регистр управления TWCR

 Регистр статуса(состояния) TWSR

 Регистр данных TWDR

И все, разобравшись всего лишь с 4-мя регистрами, мы сможем полноценно работать с внешней памятью EEPROM и вообще, обмениваться данными по I2C с любым другим устройством.

Генератор скор

nagits.wordpress.com

Отправить ответ

avatar
  Подписаться  
Уведомление о