Урок 8
HAL I2C Подключаем часы реального времени DS3231
Сегодня мы попробуем с помощью библиотеки HAL поработать с шиной I2C.
Заранее определимся, что по данной шине мы подключим микросхему часов реального времени DS3231.
Сначала немного поговорим о самой шине I2C.
По данной шине я очень много рассказывал в серии частей урока 16 по МК AVR, поэтому здесь будем знакомиться более коротко, чтобы не повторяться.
Шина I2C — это шина, управляемая по двум проводам и по определённому протоколу.
Первый провод — SDA (Serial DAta)), а второй — SCL (Serial CLock). Данные в основном передаются по проводу SDA. Второй провод в основном для тактирования,
Передача всегда начинается с формирования ведущим устройством условия СТАРТ на данной шине. Оно формируется формированием отрицательного фронта на шине SDA, а затем отрицательного фронта на шине SCL
В конце любой полной посылки генерируеся условие СТОП, которое, наоборот, сначала требует положительного фронта на SCL, а затем на SDA.
На шину I2C можно теоретически навешать до 127 устойств за счёт того, что у каждого устройства существует свой 7-битный адрес, который после условия СТОП Мастер (ведущий) передает в шину. И на этот адрес уже откликается только то SLAVE (ведомое) устройство, адрес которого был передан. После адреса передаётся бит. определяющий каким именно образом мы собираемся общаться с ведомым устройством, то есть читать данные мы с него будем или в него писать. Дальше уже Мастер ждёт подтверждение от ведомого, ведомый должен опустить шину SDA на низкий уровень, и, если это передача, то начинает соответствующим образом данные передавать, а если приём, то принимать.
Как именно и в каком порядке побайтно и побитно осуществляется приём и передача, мы, как правило, смотрим уже в технической документации на устройство, которое мы подключаем. Там могут быть ещё адреса ячеек памяти и регистров, они могут быть 16 и 8 битные и много ещё чего.
Также стоит упомянуть о том, что провода данной шины, можно сказать, висят в воздухе, так как используется открытый коллектор, и их, поэтому, необходимо подтянуть к шине питания через резистор сопротивлением 4,7 — 10 килоом. Также можно это сделать и программно. Причем данного номинала мы должны придерживаться не на каждом устройстве, если их несколько, а на всей шине. То есть, если мы подключили 10 устройств с разными адресами, то подтягивающие резисторы мы оставим только на одном из них, а на остальных придётся их выпаять, чтобы они не параллелились.
Преждем чем перейти именно к разбору микросхемы 3231, мы ещё должны знать, как именно организована шина I2C на нашем контроллере.
Во первых, частота передачи данных или битрейт поддерживается контроллером 100 кГц и 400 кГц. Какую именно выбирать, мы уже решаем исходя из возможностей подключаемого девайза и из наших требований к передаче данных.
Ну и конечно же стоит подчеркнуть, что шина I2C организована само собой у нашего контроллера STM32F4 аппаратно, причём их там несколько.
Вот блок-схема
Здесь мы видим наши провода SDA и SCL, также существуют регистры, которые мы настраиваем для работы, регистр данных, адресный регистр, также регистр двойного адреса, который поддерживает уже 16-битный адрес, два управляющих регистра — CR1 и CR2, регистры статуса — SR1 и SR2, а также регистр, задающий частоту передачи данных или скорость.
Но, так как мы собрались использовать библиотеку HAL, то нам не придется париться по поводу программирования битов данных регистров и когда именно заносить в регистр адреса и данных те самые данные, и данное бремя библиотека HAL обещает взять на себя.
Поэтому нам необходимо и достаточно лишь только знать, какие именно функции нам и как использовать из этой самой библиотеки.
Поэтому откроем руководство пользователя именно библиотеки HAL и найдём необходимые нам функции, все они нам не нужны. Их ведь очень и очень много. Разберём только те, которые мы будем использовать в нашем заниятии. Остальные будем разбирать в других уроках, а может вообще не будем разбирать, а будем только пользоваться.
Тем более нам нет смысла рассматривать функции инициализации и деинициализации, так как этим всем занимается кодогенератор Cube MX и, как показала практика, вполне справляется.
А функции, которые нам потребуются в сегодняшнем занятии, мы разберём по мере их написания в коде.
Теперь, собственно, микросхема DS3231. Данная микросхема — это часы реального времени, разработанные компанией Dallas, как я считаю, являющейся самой распространённой у пользователей подобных микросхем.
Данные часы реального времени работают подобно предшественнику DS1307, только очень сильно усовершенствованы. Кварцевый резонатор уже находится внутри и поэтому мы уже его не припаиваем, также здесь реализована очень хорошая термокомпенсация, поэтому точность данных часов просто удивляет. Хотя и есть здесь ещё регистр для поправки хода, но я им никогда не пользовался, так как и без него микросхема обеспечивает прекрасную точность хода.
Питается данная микросхема с успехом как от 3 вольт, так и от 5 вольт, поэтому здесь бояться нечего.
Ну и так же как и все современные RTC, у данной микросхемы очень хорошо организована энергонезависимость от внешних источников. Для этого есть два контакта для подключения резервной литиевой батареи на 3,7 вольт, которая обеспечивает продолжение хода часов при отключении питания. Малое энергопотребление в режиме питания от баттареи обеспечивается тем, что почти весь фукнционал кроме хода часов не работает.
Скорость обмена данными поддерживается данной микросхемой и 100 кГц и 400 кГц.
Теперь про регистры микросхемы. Это о том, что именно может хранить в себе данная микросхема
Вот их сколько, этих регистров.
00h — секунды. Секунды хранятся в двоично-десятичном виде. То есть в младших 4 битах хранятся единицы секунд, а в более старших трёх — десятки.
01h — минуты. Хранятся аналогично.
02h — более универсальный регистр. Здесь хранятся часы. В четырех младших битах — единицы чаов, в следующих более старших двух — десятки, в следующем 6 бите — флаг того, после полудня сейчас время или до полудня, в 7 бите — режим хранения — 12- часовой или 24-часовой.
03h — день недели. Хранится в младших 3 битах, остальные биты не используются.
04h — здесь хранится день месяца, также в двоично-десятичном формате. В четыреё малдших битах — единицы, в двух следующих постарше — десятки, следующий бит не используется.
05h — номер месяца в году — хранится в двоично-десятичном формате точно также, как и часы. Самый последний бит автоматически установится, когда закончатся последние сутки века и начнётся следующий век. Смех да и только. Я думаю в нём можно хранить единицу, она будет говорить о том что у нас на дворе 21 век.
06h — номер года, причём не полный четырёхзначный, а только двузначный. В младших четырех битах — единицы, в старших — десятки. А какой век подразумевать, можно хранить в 7 бите месяца.
Вот этими семью регистрами мы и будем пользоваться. Дальше идут регистры будильников, а последние два регистра — это температура, измеряемая на термодатчике, который установлен в микросхему. По идее, можно данным регистром воспользоваться, чтобы выводить показания температуры, хотя это и температура микросхемы. Но термокомпенсация так устроена, что если вдруг микросхема начнет греться, то в ней начнут работать технологии, предотвращающие это, и она остынет. Я пробовал считывать данный регистр, и. в принципе это была температура окружающего воздуха.
Также существуют ещё два регистра управления и статусов. В рамках данного занятия мы ими пользоваться не будем, но техническую документацию на микросхему я прикреплю на странице внизу и вы, скачав её, можете почитать и воспользоваться битами данных регистров.
Теперь, собственно, передача данных:
Это передача данных.
Сначала СТАРТ, затем 7-битный адрес, затем 0, который означает, что мы будем писать в данную микросхему, затем бит подтверждение, затем адрес регистра, которые мы рассмотрели только что выше, опять подтверждение, зтем сами данные, причем можно передавать сразу несколько. Подтверждения ждём после каждого переданного байта, а в конце условие СТОП. Так что мы спокойно можем при установке времени, передать сразу байты всех семи регистров, передав перед этим байт самого первого из них, то есть 0x00.
Теперь чтение
Здесь также мы можем читать не по одному регистру в пакете, а также все 7 регистров.
Вообще, это документация для самого ведущего устройства, у ведомого немного не так.
Перед тем как воспользоваться этой диаграммой, мы сначала делаем СТАРТ, затем адрес устройства, затем бит записи, именно записи, затем адрес регистра, затем повторный СТАРТ, затем опять адрес устройсва, затем бит чтения или 1, затем уже ждём данные с подтверждениями, а чёрточка над буквой A после последнего принятого байта означает, что мы подтверждения не ждем или ждём условия «Нет подтверждения», то есть шина SDA установится в высокое состояние и в конце СТОП.
Вот так. Конечно библиотека HAL лишит нас удовольствия поиграться с данными алгоритмами приема и передачи, так как она это будет делать сама. Но, я думаю, мы уже наигрались с этим в уроках по AVR и с микросхемой EEPROM и с микросхемой DS1307.
Вот типовая схема подключения данной микросхемы к контроллеру
Здесь мы видим, что восемь ножем соединяются с корпусом, также есть ножки SDA и SCL, ножки питания VCC и GND, RST для перезагрузки микросхемы, мы данной ножкой не пользуемся. Ещё есть ножка для подключения батарейки VBAT, выход SQW для того, чтобы мы могли брать импульсы определенной частоты с данной микросхемы для какой-нибудь синхронизации, мы эту ножку как правила используем для мигания двоеточия. Также частотой на данной ножке можно управлять определенными битами в определенном регистре. А также ещё выход 32 кГц.
Чуть не забыли про адрес, по которому бы обязаны будем обращаться к устройству. Не зная его, мы не сможем общаться с микросхемой, так как она нам просто не ответит
Это выдержка из даташита, дальше нет смысла читать.
Адрес у нас получается 0b1101000. Соответственно, в функциях мы его будем использовать в сдвинутом на 1 бит влево состоянии, то есть сразу с прицепленным нулём. означающим запись, причем в функциях. предназначенных для чтения мы также будем использовать бит 0, а функция там сама всё как надо сдвинет, так уж они устроены, эти функции HAL. То есть адрес у нас будет 0xD0.
Показания часов из данной микросхеме мы будем смотреть на дисплее. который мы подключили на прошлом занятии.
Вот схема подключения (нажмите на картинку для увеличения изображения)
Здесь несколько другая микросхема, но подключение ничем не отличается. Просто не нашел я именно такую микросхему в программе-редакторе электронных схем.
Также ещё скажу, что у меня не просто микросхема, а именно готовый модуль, причем сразу с батарейкой и со всеми выведенными наружу контактами, ссылка на продавца есть под видеоверсией урока в описании.
Модуль выглядит вот так
Точно также как и раньше проект создаем из предыдущего. Новый проект называется MYDS3231
Запускаем его в Cube. Включаем там шину I2C1 вот таким вот образом
Мы также увидим справа в виртуальном контроллере. что у нас появились задействованные ножки портов
Вот к этим ножкам PB6 и PB7 мы и будем подключить соответствующие ножки модуля.
Настройки в Configuration будут такие
На будущее включим и прерывания
Генерим проект и переходим в кейл.
Подключим файл lcd.c в дерево проекта
Создаем файлы i2c.c и i2c.h
Попробуем собрать проект.
В i2c.h подключим библиотеки
#include «stm32f4xx_hal.h»
#include «lcd.h»
Подключаем файл и в i2c.c и в main.h
#include «i2c.h»
//——————————————
Также создаем и подключаем файлы RTC.h и RTC.c
В RTC.h подключим библиотеку
#include «stm32f4xx_hal.h»
После этого содержание файла main.h
#ifndef MAIN_H_
#define MAIN_H_
#include «lcd.h»
#include «i2c.h»
#include «RTC.h»
#endif /* MAIN_H_ */
В принципе. все ознакомительные и настроечные процедуры мы проделали.
Основной код начнём писать в следующем занятии.
Предыдущий урок Программирование МК STM32 Следующий урок
Техническая документация на микросхему RTC DS3231
Отладочную плату можно приобрести здесь STM32F4-DISCOVERY
Модуль RTC DS3231 с микросхемой памяти (2-5 шт)
Модуль RTC DS3231 с микросхемой памяти (1 шт) — так дороже
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Почему то проект не собирается. ../Inc/i2c.h(4): error: #5: cannot open source input file «stm32f4xx_hal.h»: No such file or directory
#include «stm32f4xx_hal.h» и таких ошибок 17. может вы знаете в чем дело?
На этом модуле Диод отпаять надо если батарейку используете, а не литиевый аккум, а то она вздуется. зарядка ей не нужна.
В STM32 вроде есть свой встроенный RTC ?
2 ошибки и 8 предупреждений
вот ошибки:
../Src/main.c(154): error: #65: expected a «;»
../Src/main.c(180): error: #20: identifier «RCC_ClkInitStruct» is undefined
и везде: function definition is not allowed here