Найти в Дзене
narod stream

ESP32 Урок 7. I2C. Переходник для LCD 20×4

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

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

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

Соответственно, схема у нас получится следующая

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

Проект мы сделаем из проекта прошлого урока с именем I2C_EEPROM и назовём его I2C_LCD2004.

Из каталога main проекта удалим сразу же файлы at24c.c и at24c.h.

Откроем проект в Espressif IDE и, пока его не собирая, сразу создадим два модуля (четыре файла) со следующим содержимым

i2c_user.h

i2c_user.c

lcd2004.h

lcd2004.c

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

Откроем файл main.c и удалим оттуда подключения всех библиотек, так как они теперь у нас подключены в заголовочном файле, а вместо них подключи соответственно данный файл

#include "main.h"

Удалим следующий макрос

#define I2C_ADDRESS 0x50

Удалим также объявление массивов

uint8_t rd_value[20] = {0};
uint8_t wr_value[20] = {0x14,0x13,0x12,0x11,0x10,
    0x0F,0x0E,0x0D,0x0C,0x0B,
    0x0A,0x09,0x08,0x07,0x06,
    0x05,0x04,0x03,0x02,0x01};

А в функции app_main оставим только объявление переменной-итератора, объявление переменной кода ошибки, а также задержку в бесконечном цикле, заодно увеличив её. Содержимое функции будет теперь следующее

Не забываем также убрать подключение в файле CMakeLists.txt каталога main файла at24c.c и подключить туда наши два новые

set(COMPONENT_SRCS "main.c i2c_user.c lcd2004.c")

Теперь можно попробовать собрать наш проект.

Если всё нормально собралось, то движемся далее.

В файле i2c_user.c объявим макрос для бита  проверки отклика, переменную для хранения номера модуля, а также макрос с частотой шины

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

Инициализация, в принципе, та же самая, что и для at24c, никаких изменений.

Также выше добавим функцию отправки байта в шину

Добавим прототип в заголовочном файле на наши функции и вызовем функцию инициализации шины в функции app_main файла main.c, а также выведем значение кода ошибки в терминал

В файле lcd2004.h добавим макросы для различных команд

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

Ниже добавим функцию передачи байта в шину

Ниже также добавим функцию передачи полубайта

Останавливаться подробно на данных функциях мы не будем, так как они такие же как и в подобном уроке для ESP8266.

Ниже добавим функцию передачи байта при помощи переходника в дисплей

И также ниже добавим функции установки курсора и передачи в дисплей строки

Ну и в самом низу — функцию инициализации дисплея

В файле lcd2004.h добавим прототипы требуемых нам вне данного модуля функций

Вернёмся в файл main.c.

Мы будем использовать отдельную задачу для передачи в дисплей строк, так как мы работаем всё-таки с операционной системой, тем более мы так и делали ранее в случае использования контроллера esp8266 и нам это будет не в диковинку. Поэтому объявим структуру для передачи строки, а также очередь

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

В функции app_main создадим очередь и задачу

Приоритет нам большой не требуется, поэтому хватит и 2.

Объявим локальный символьный массив

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

Соберём код, прошьём контроллер и посмотрим результат на дисплее

-2

Также посмотрим возврат кода ошибки в терминале

-3

Можно было бы и не смотреть, у нас же дисплей работает как положено.

Затем посмотрим передачу данных в программе логического анализа

-4

Здесь также всё нормально и частота приличная, хотя меньше чем 400, почему-то частота устанавливается неточно, но для нас, в принципе, это некритично.

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

Затем в бесконечном цикле будем наращивать счётчик и передавать его значение в виде строки в дисплей

Соберём код, прошьём контроллер и посмотрим результат на дисплее

-5

Всё отлично! Счётчик считает.

Итак, на данном уроке нам удалось подключить к контроллеру символьный дисплей LCD2004 посредством переходника по шине I2C. Также мы немного поупражнялись с очередью.

Всем спасибо за внимание!

Оригинал статьи находится здесь.

<<Предыдущий урок | Следующий урок>>

Исходный код

Недорогие отладочные платы ESP32 можно купить здесь

Логический анализатор 16 каналов можно приобрести здесь

Дисплей LCD 20x4 можно приобрести тут

Дисплей LCD 16x2 можно приобрести тут

Переходник I2C to LCD1602 2004 можно приобрести здесь

Видео в RuTube

Программирование МК ESP32. Урок 7. I2C. Переходник для LCD 20×4

Видео в Дзен

Видео в Youtube