Шина I2C

Осваивать микроконтроллеры я начал в 2005 году, используя материалы публиковавшегося в 2004 году цикла статей «Микроконтроллеры. Шаг…» в журнале «Радиоаматор». В следующие года последовали циклы об AVR (2005), PIC (2006), шине USB в МК (2007), сетевых интерфейсах на МК (2008), GSM на базе модуля SIM300 (2009). Автором этих циклов является глубоко уважаемый мною Рюмик С.М. Материал изложен очень доходчиво и методически грамотно. Именно поэтому я отпечатал материал этих статей и оформил их для себя в виде брошюр, куда очень часто заглядываю.
В заключительных статьях первого цикла (2004) была рассмотрена конструкция температурного самописца в связке AT89C2051-DS1621-AT24C16. Эту конструкцию я повторил. Она же позволила мне разобраться с шиной I2C. В дальнейшем, перейдя на работу с AVR, я переписал под них библиотеку и работал со всеми встречающимися устройствами I2C вполне осознанно и успешно.
Логику работы шины I2C я описывать не буду — информации в сети просто валом. Не считаю нужным сотый раз перепечатывать одно и то же из сайта на сайт.
Теперь о реализации… Твёрдо убеждён в гораздо большей эффективности именно программной реализации этого протокола. Аппаратный модуль TWI микроконтроллеров AVR разработан имхо очень запутанно и не эффективно. Всё как-то усложнено и переплетено. В паре своих конструкций я его использовал, но потом плюнув, перешёл на свою старую добрую отработанную библиотеку I2C.
Итак сегодняшний проект. Вернее это не проект, а заготовка для: часов, календаря, термометра, термостата, самописца, устройства управления и пр. пр. Недаром в интернете шутят: «… делали новое устройство на МК, а получились очередные часы…» 🙂 Изначально я делал его для управления электрическим котлом отопления дома ( абонентам, цена электроэнергии для которых сильно зависит от времени суток — есть и такие тарифы).
Схему как таковую не привожу, т.к. все соединения приведены в заголовочных файлах проекта, и каждый может их изменить в соответствии со своими требованиями.
Для практической реализации из микроконтроллерного конструктора выберем любой микроконтроллерный модуль, модуль шины I2C, клавиатуру и LCD HD44780-совместимый. Соединяем их согласно разделам define заголовочных файлов проекта.  Для себя я выбрал ATmega128 kit, т.к. она уже имеет четыре пользовательских кнопки и специально для неё купленный и приспособленный ЖКИ. Вот что из этого вышло:
Отмечу, что на моём модуле I2C установлены: RTC DS1307, EEPROM AT24C16 и термометр DS1621. В данном примере работаем с часами  и термометром. После прошивки контроллера пробуем разобраться в меню. В принципе там и разбираться-то нечего — обычное древовидное меню. Это после включения:
После нажатия кнопки «Ввод»:
Кнопкой «->» перебирается и кнопкой «Ввод» выбирается требуемый параметр. Например текущая дата:
Или время:

Или температура:
Кнопкой » ^ » входим в режим установки параметров:
Этой же кнопкой параметр, на который указывает стрелка, изменяется не выходя за пределы. Кнопкой «->» перебирается изменяемый параметр:
А при нажатии кнопки «Ввод» в DS1307 запишется установленная информация. Назначение кнопки «Отмена» я думаю всем понятно.
В архиве папка с исходниками. Код я особо не вылизывал, т.к. он собран из кусков различных проектов. Поэтому камнями сильно не кидайтесь — делайте и оптимизируйте под свои нужды.
В заключение хочу сказать, что тестировал работу шины на частотах вплоть до 500 кГц — это изменяется паузой для импульсов SCL. Работа стабильна, хоть производитель  пишет верхнюю частоту 400 кГц. Но это в пределах соединителей, т.е. 15-20 см — дальше не мерял. Удачи Вам, друзья

Запись опубликована в рубрике Микроконтроллерный конструктор с метками , , . Добавьте в закладки постоянную ссылку.

35 комментариев: Шина I2C

  1. Alexander говорит:

    Попробовал просимулировать в Proteus и получил чистый экран.
    Есть ли у кого-нибудь опыт запуска данного проекта?
    Хочется понять, это проблемы протеуса или что-то с hex файлом.
    Самостоятельно скомпилировать пока не получилось.

  2. s_black говорит:

    Честно говоря я Протеусом не пользуюсь, т.к. не верю ему. Хотя на многих форумах встречал положительные отзывы и успешный опыт работы с ним. Пример, описанный в статье, равно как и все на этом сайте, я лично разрабатывал и внедрял в свои проекты — т.е они неоднократно опробированы. Ищите ошибку в монтаже, а если всё правильно — попробуйте укоротить линии шины, чтобы были не более 10-15 см.

  3. Alexander говорит:

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

    #include "lcd.h"
    #include "I2C.h"
    #include "Keyboard.h"
    #include "DS1307.h"
    #include "ds18b20.h"

    На

    #include "lcd.c"
    #include "I2C.c"
    #include "Keyboard.c"
    #include "DS1307.c"
    #include "ds18b20.c"

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

    PS понимаю, что первые шаги лучше делать с чем-нибудь попроще. Светодиодом, например, поморгать 🙂 Но с другой стороны, зачем мне моргающий светодиод?

  4. s_black говорит:

    Это неправильно…
    А в какой среде вы компилируете? Си-шные файлы подключаются в makefile (если Вы пользуетесь WinAvr).

  5. Alexander говорит:

    Я компилирую в AVRStudio 4, он использует компилятор WinAWR.
    Все указанные сишные файлы подключают заголовочные.
    Если сишные подключаются в makefile, зачем в основном файле полключать заголовочные?
    При использовании приложенного makefile проект собрался.
    С симуляцией пока не получается — проблемы обмена данными с дисплеем, на PORTA все время 80h, т.е. он как-бы занят.

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

  6. s_black говорит:

    Откомпилируйте просто в WinAVR и всё получится (статья как это сделать). Даже компилировать не нужно — залейте прошивку в макет. Хотя для освоения контроллеров нужно уметь это делать. При работе в Студии процесс несколько отличается от работы просто в ВинАвр-е. Вопросы задавайте любые — все свои работы я, как ни странно, помню ))) А если не помню — то вспомню)))

  7. Alexander говорит:

    Дело в том, что я начинал симуляцию с готовой прошивки. Ее поведение не отличается от скомпилированной. Макетки, к сожалению, пока нет. Приходится в симуляторе.
    Собственно, я этот проект взял в учебных целях. В статье написано, что он именно для этого. Хотел перекомпилить на ATMega8, но для начала запустить, как есть, чтобы потом не ломать голову в чем беда. В общем, висит он у меня глухо на while (PIN_lcd & 0x80). Скачал даташит на индикатор, читаю. На всякий случай попробовал оторвать «Enable». Теперь в PORTA 0h, а крутится тот же цикл. Не понимаю 🙁
    Правда, еще лапой PB4 дрыгает, что тоже не понятно.

  8. s_black говорит:

    Дело в том, что мы разговариваем немного на разных языках… Заявление, что прошивка негодная из-за того, что она не работает в симуляторе, несколько некорректно.
    while (PIN_lcd & 0×80) — это ожидание, пока ЖКИ выполнит предыдущую команду. Не уверен, что Протеус симулирует сброс бита занятости BUSY (хотя возможно) — вот программа и «висит» в ожидании.
    Заголовочные файлы подключаются во всех исходниках, где нужны, а уже препроцессор сам разберётся, откуда его (заголовочный файл) лучше подключить.

  9. Alexander говорит:

    Так я и не утверждал, что прошивка негодная. Я написал, что не могу ее запустить на симуляторе.

  10. s_black говорит:

    В функции void busy_LCD (void)//функция проверки занятости индикатора закомментируйте строку ожидания выполнения и увеличьте паузу вот так:
    …………………..
    _delay_us(100);
    //while (PIN_lcd & 0x80);//ждать выполнения предыдущей команды
    ……………………
    Перекомпилируйте всё и проверьте ещё раз в Протеусе, только внимательно посмотрите разводку линий в lcd.h

  11. Alexander говорит:

    Странно, тот-же эффект :O

  12. s_black говорит:

    Что, висит на той же строке?

  13. Alexander говорит:

    Да.

  14. s_black говорит:

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

  15. Alexander говорит:

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

  16. Alexander говорит:

    Что касается линий:
    D0…D7 -> PA0…PA7 соответственно;
    E -> PE2;
    R/W -> PC5;
    RS -> PC6.
    Там трудно что-то напутать.

  17. s_black говорит:

    Да, изучать электронику, всё-таки лучше на реальном «железе». Если самому не хочется паять — посмотрите статью про Деалэкстрим. Можно за чуть более 60 у.е. купить офигенный набор.

  18. s_black говорит:

    Проверьте частоту работы МК в Протеусе. Понажимайте кнопки и пр.

  19. Alexander говорит:

    Частота 1 МГц. Там еще задается частота для дисплея. Вот этого я не понял, что за частота такая? По-умолчанию стоит 250 кГц.

    Паять придется в любом случае. Я ориентировался на ATMega8 (если помещусь, и до 32 по необходимости, далее в DIP не делают) и LCD от Nokia 1100.

  20. s_black говорит:

    … далее в DIP не делают…
    ещё как делают — ATmega1284 -128к, 40 DIP

  21. Alexander говорит:

    Что-то с протеусом совсем беда 🙁
    С подключенным термометром на обоих линиях I2C имеются импульсы. При подключении часов на обоих линиях постоянно высокий уровень. Точнее, при подключении SDA линии часов.

    Появился вопрос. Я сначала невнимательно прочел статью, а в заголовочных файлах увидел DS18B20. В данном проекте он не используется? Температура берется с DS1621?

  22. Alexander говорит:

    Заработало.
    Оказывается, в свойствах индикатора нужно было поставить частоту 20 МГц.
    Вместе с этим
    …………………..
    _delay_us(100);
    //while (PIN_lcd & 0×80);//ждать выполнения предыдущей команды
    ……………………
    работает
    Нагуглил эту проблему. Не я первый столкнулся. Странная модель.

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

    PS Меня движок записал в спамеры 🙁

  23. s_black говорит:

    Температура берётся с DS1621, но можно и с DS18B20. В обработчике прерывания по совпадению таймера 1
    ISR (TIMER1_COMPA_vect)
    закомментированные строки относятся к DS18B20. В общем-то исходник ds18b20. можно отключить в мэйкфайле, а хидер ds18b20.h — в главном файле. Это ничего не изменит, только размер хекса меньшится, что в случае 128-й меги не существенно.

  24. Valeriy говорит:

    » Как минимум, исходники не компилируются без правки.
    Мелочь, но все же.
    После замены

    #include "lcd.h"
    #include "I2C.h"
    #include "Keyboard.h"
    #include "DS1307.h"
    #include "ds18b20.h"

    На

    #include "lcd.c"
    #include "I2C.c"
    #include "Keyboard.c"
    #include "DS1307.c"
    #include "ds18b20.c"

    Такая ситуация может возникать если не подключены Сишные файлы, в студии при новом проекте это надо делать ручками : AVR GCC ->правой кнопкой мыши на «Source Files» ->Add Existing Source File(s) — добавить сишные файлы.

  25. Alexander говорит:

    Спасибо, это я уже понял 🙂
    Пока отложил в сторону Си, т.к. пытаюсь втиснуться в ATTiny13.

  26. Valeriy говорит:

    Доброго времени, уважаемый s_black подскажите пож. в какой среде работать с проектом, вроде AVR Studio но попытка пересборки проекта дает «Build failed with 1 errors and 10 warnings…» , Warniigs на «PGM_P adr_data_set [] = {day_d,day_e,month_d,month_e,year_d,year_e,hour_d,hour_e,minute_d,minute_e};»,
    а в архивном исходнике нет файла проекта, подскажите пож. где могу косячить, заранее благодарен.

  27. s_black говорит:

    Исходник в проекте для WinAVR. Хотя можно перенести и в Студию, и, с небольшими изменениями в синтаксисе, и в Кодвижн.

  28. Valeriy говорит:

    да я начинал в АБ затем Кодвижн сейчас AVR Atudio с WinAVR не работал, нельзя обьять необьятное… 🙁

  29. Alexander говорит:

    AVR Atudio использует WinAVR для компиляции, если проект на Си.

  30. FreshMan говорит:

    Автор, вы вот говорите что програмный I2C более эффективен в отличие аппаратного. Какие весомые аргументы вы можете привести в защиту ваших слов ?

  31. s_black говорит:

    Программная реализация I2C:
    1. Занимает в памяти меньше объёма чем множественный перебор switch-case кодов статуса TWSR для всех ситуаций.
    2. На мой взгляд более понятные и очевидные действия операторов программы, реализующей I2C. (Имею в виду, что порядок действий по операторам чётко соответствует описанию протокола).
    3. Позволяет использовать любые выводы микроконтроллера для I2C, а не определённые аппаратно (для меня это главный аргумент).
    И, наконец, — банальная привычка, товарищи!!!

  32. FreshMan говорит:

    1) по поводу перебора всех ситуаций то тут еще посмотреть надо, если у меня МК работает мастером, а DS1307 выступает в роли slave то описывать все режимы бесмысленно, достаточно описать ошибки для данного режима.
    2)на мой взгляд, главное достоинство аппаратного TWI в том, что я не загружаю МК лишней работой, я ему дал команду и ушол по своим делам. Ну а по поводу выводов тут дело такое что надо смотреть как развести дорожки ну или если уже не получается то перемычки нынче тоже в моде )))

  33. s_black говорит:

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

  34. Николай говорит:

    Большое спасибо автору за простоту и понятность проекта и тех проектов «ШАГИ»
    которые были опубликованы я на них учился
    AVR ds18b20 ds1307 LCD 1wire I2S — разобрался теперь подрабатываю
    Буду в Чернигове поставлю автору коньяк!

  35. s_black говорит:

    Эти слова благодарности, если я правильно понял, адресованы Рюмику С.М. Полностью к ним присоединяюсь !

Добавить комментарий

Ваш e-mail не будет опубликован.