ESP32 Урок 49. ULP. 1-Wire. Прием данных



Продолжаем работу с сопроцессором ULP, также мы продолжаем работу с устройством, взаимодействующим с контроллером по шине 1-Wire, а именно с датчиком температуры DS18B20. Передавать данные в шину мы уже умеем, а на данном уроке мы попытаемся принять данные из устройства в контроллер и записать их в память контроллера.

Схема наша осталась та же, что и в прошлом уроке — отладочная плата с контроллером esp32, подключенный к ней датчик температуры DS18B20, а также логический анализатор, подключенный к сигнальной ножке датчика для анализа обмена данными по шине

 

 

Проект за основу мы также возьмём из прошлого урока с именем ULP_FSM_ONEWIRE_SEND и дадим ему новое имя ULP_FSM_ONEWIRE_READ.

Откроем наш проект в Espressif IDE, перейдём в файл ulp_assembly_source_file.S и ниже выхода из процедуры get_temp добавим ещё одну процедуру, которая будет читать байт из устройства и сохранять его в регистре R2

 

 

Пока мы обнулили значения регистров R2 и R0.

Добавим метку, так как байт будет читаться побитно

 

 

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

 

 

Узнаем уровень на ножке

 

 

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

 

 

Поэтому теперь идём в функцию init_ulp_program файла main.c и установим нужный бит для нужной нам ножки

 

 

Вернёмся в файл ulp_assembly_source_file.S и в процедуре read_byte вызовем процедуру чтения бита, сохранив перед этим в стек значение регистра R0

 

 

Скопируем значение регистра R0, в котором и хранится считанный бит, в регистр R1 и вернём из стека сохранённое перед вызовом процедуры значение регистра R0

 

 

Сдвинем влево значение регистра R1 в позицию, которую мы достигли в цикле, хранящуюся в регистре R0, и запишем результат обратно в регистр R1

 

 

Инструкция сдвига влево подобна инструкции сдвига вправо

 

Инструкция LSH выполняет логический сдвиг влево от исходного регистра на количество битов из другого исходного регистра или 16-битного знакового значения и сохраняет результат в регистре назначения.

Затем мы при помощи логической операции ИЛИ добавляем значение бита в значение регистра R2, в котором постепенно набираются биты всего читаемого байта

 

 

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

 

 

 

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

 

 

Подготовим в секции bss место для хранения считанных байтов скратчпада

 

 

Вернёмся в процедуру get_temp и сохраним в регистр R0 адрес начала памяти, отведённой под скратчпад

 

 

Перед сохранением адреса памяти мы использовали новую для нас команду stage_rst, которая сбрасывает в 0 значение регистра-счётчика, который будет нам в дальнейшем необходим для условного перехода

 

 

Добавим метку, так как читать мы будем 9 байт

 

 

Сохраним в стеке значение регистра R0, прочитаем байт и вернём из стека значение регистра

 

 

 Сохраним в память значение байта и прибавим счётчик байтов, хранящийся в регистре R0

 

 

При помощи следующей инструкции сопроцессора инкрементируем значение регистра-счётчика

 

 

Вот описание данной инструкции

 

 

Перейдём на нашу метку, если мы ещё не достигли значения 9 в регистре-счётчике

 

 

Инструкция JUMPS, подобно инструкции JUMPR, также осуществляет переход по условию, только пользуется она в условиях уже значением регистра-счётчика stage_cnt

 

 

Условия в JUMPS те же самые, что и в JUMPR.

Пошлём в шину команду перезагрузки

 

 

В основном коде после вызова процедуры get_temp сохраним значение адреса памяти со считанным скартчпадом в регистр R1

 

 

Далее при помощи серии инструкций сохраним значение самой первой ячейки скратчпада в переменную

 

 

Это будет у нас младший байт значения температуры.

Перейдём в файл main.c и в функции app_main отобразим в терминале значение нашего байта

 

 

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

 

 

Посмотрим значение в терминале

 

 

Отлично! Показания сходятся. Только надо анализировать и смотреть в терминале одновременно, так как младший байт с изменением температуры воздуха может меняться.

0xBE — это команда чтения скратчпада, поэтому её не учитываем.

Прочитаем ещё какой-нибудь байт, например четвёртый (мы читали нулевой). Для это вернёмся в файл ulp_assembly_source_file.S и прибавим четыре к значению регистра, тем самым сдвинемся в памяти на 4 ячейки

 

 

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

 

 

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

Итак, на данном уроке мы научились считывать байты из устройства, подключенного к контроллеру ESP32 по шине 1-Wire, при помощи ассемблерного кода, работающего под управлением сопроцессора ULP. Также в процессе работы мы изучили ещё несколько ассемблерных инструкций сопроцессора ULP.

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

 

 

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

 

Исходный код

 

 

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

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

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

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

 

 

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

ESP32 ULP. 1-Wire. Прием данных

 

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

ESP32 ULP. 1-Wire. Прием данных

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

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

*