ESP32. Урок 37. RMT. 1-Wire. Инициализация. Часть 1



Продолжаем работать с модулем RMT (Remote Control) и с сегодняшнего урока мы попытаемся с использованием данного модуля поработать с однопроводной шиной, по которой будут передаваться данные по протоколу 1-Wire.

С данным протоколом мы уже неоднократно встречались, подключая датчик температуры DS18B20 с использованием других контроллеров. Например, с таким датчиком мы работали, подключая его к контроллеру AVR в уроке 20. Также такой датчик мы подключали и к контроллеру STM32 в уроке 92. А в уроке 94 мы подключали даже несколько таких датчиков, так как на одном проводе по протоколу 1-Wire можно работать и с несколькими устройствами.

Благодаря тому, что мы уже с протоколом 1-Wire столько много работали, нам не придётся изучать сам протокол, команды, а также впоследствии и принцип работы с датчиком температуры, так как это всё мы уже неплохо знаем. Останется лишь только адаптировать наши знания к работе с модулем RMT контроллера ESP32. Хотя не смотря на то, что у нас за плечами такой багаж знаний, работа эта будет очень непростая. Поэтому я решил разделить её на несколько этапов. И сегодня мы произведём только инициализацию протокола 1-Wire.

Схема урока будет состоять из отладочной платы с контроллером ESP32, к которой мы подключим датчик температуры DS18B20, а чуть позже три таких датчика. Также мы помним, что для корректной работы с шиной потребуется резистор на 4,7 килоома, подключенный между сигнальным проводом датчика и шиной питания 3,3 вольта. Сигнальный провод датчика мы подключим к ножке порта GPIO4. Резистор мы установим на макетной плате и для начала подключим макетную плату к отладочной

 

 

Подключим датчик к макетной плате. Датчик находится на проводе в металлическом корпусе. С таким датчиком мы уже работали

 

 

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

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

 

 

Теперь проект.

Проект урока был создан из проекта урока 4 с именем BUTTON01 и получил имя RMT_ONEWIRE_INIT.

Откроем наш проект в ESPRESSIF IDE и из файла Kconfig.projbuild удалим пункт меню по работе с ножкой, к которой была подключена кнопка (BUTTON_GPIO). Также в данном файле ножку порта по умолчанию для светодиода выберем вторую

 

default 48 if IDF_TARGET_ESP32S3
default 2

 

В самой первую строке для приличия переименуем пункт меню

 

menu "ONE WIRE Configuration"

 

Добавим пункт для ножки датчика

 

 

Запустим конфигуратор и выберем 4 мегабайта объёма памяти FLASH

 

 

В функции app_main файла main.c оставим только вот эти строки

 

 

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

 

 

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

 

 

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

Для начала создадим заголовочный файл с именем owb.h,  в котором подключим заголовочный файл для работы с модулем RMT

 

 

Также создадим файл owb.c следующего содержания

 

 

Имя owb для модуля выбиралось как аббревиатура от One Wire Bus (однопроводная шина).

Не забываем добавить модуль в файле CMakeLists.txt

 

set(COMPONENT_SRCS "main.c owb.c")

 

В файле main.c объявим и заполним строковый массив для работы с логами

 

 

 

В функции app_main подождём 2 секунды для первичной инициализации датчика

 

 

Затем в файле owb.h объявим тип структуры для хранения настроек шины

 

 

Ниже объявим структуру для хранения таймингов

 

 

В файле main.h подключим заголовочный файл owb.h

Вернёмся в функцию app_main файла main.c и объявим указатель на переменную только что объявленного нами типа

 

 

Опять перейдём в файл owb.h и объявим ещё один тип структуры, более расширенный, также для хранения настроек шины, но уже с использованием модуля RMT

 

 

Вернёмся в функцию app_main файла main.c и переменную этого типа

 

 

Перейдём в файл owb.c и добавим функцию инициализации нашей шины, в которой пока что только выведем в терминал в случае, если происходит отладка, информацию о входных параметрах, а также вернём указатель на переменную типа структуры конфигурации шины

 

 

К данной функции мы вернёмся позже.

А пока перейдём в заголовочный файл owb.h и объявим перечисляемый тип для состояния шины

 

 

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

 

 

 

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

 

 

В файле owb.h объявим структуру с указателем на символьный массив, а также с указателями на функции, подобные тем, которые мы только что добавили

 

 

Вернёмся в owb.c и выше функции _init объявим и сразу проинициализируем переменную типа только что объявленной структуры с символьным массивом, хранящим в себе имя шины, и указателями на добавленные выше функции

 

 

В функции _init проинициализируем поля переменной структуры настройки модуля RMT, указатель на которую находится во входном параметре

 

 

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

 

 

Только это не совсем режим отладки. Это только его эмуляция. Настоящий режим отладки запускается по интерфейсу JTAG. С отладкой мы работали в уроке 10. Вернёмся в функцию _init и отобразим в терминале информацию о каналах

 

 

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

Для функции owb_rmt_initialize создадим прототип в заголовочном файле, затем в функции app_main файла main.c вызовем её

 

 

Попробуем собрать код, прошить контроллер и посмотреть, что отображается в терминале

 

 

Всё правильно. Не надо пугаться ошибочного состояния, так как мы ещё не завершили функцию _init в файле owb.c, в которую мы сейчас вернёмся и объявим указатель на переменную структуры конфигурационных параметров RMT, а затем инициализируем её поля

 

 

Прошу обратить внимание на настройку делителя. Мы не случайно ему даём значение 80, так как у нас APB тактируется частотой 80 мегагерц и делитель 80 нам позволит считать, что каждый тик тактирования модуля RMT будет равен 1 микросекунде, что облегчит нам работу с таймингами уровней.

Применим наши конфигурационные параметры и зададим источник тактирования RMT

 

 

Объявим макрос для значения общей продолжительности слота, а также макрос для длительности порога бездействия, который должен быть больше времени слота

 

 

Вернёмся в функцию _init, применим флаги к настройке канала, и, если всё нормально, то произведём аналогичным образом настройку приёмника

 

 

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

Применим также флаги к настройке канала приёмника

 

 

Здесь мы уже назначаем кольцевой буфер.

 

В следующей части урока мы закончим функцию инициализации, отправим в шину команду RESET и отследим ответ устройства.

 

 

Предыдущий урок Программирование МК ESP32 Следующая часть

 

 

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

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

Датчик температуры DS18B20 в экране с проводом можно приобрести здесь DS18B20

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

 

 

Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)

ESP32 1-Wire. Инициализация

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

ESP32 1-Wire. Инициализация

 

Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)

ESP32 1-Wire. Инициализация

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*