ESP32 Урок 47. ULP. 1-Wire. Инициализация



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

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

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

 

 

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

 

 

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

 

 

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

Проект был создан на основе проекта прошлого урока с именем ULP_FSM_BUTTON и получил новое имя ULP_FSM_ONEWIRE_INIT.

Откроем наш проект в Espressif IDE и для начала в функции init_ulp_program файла main.c мы изменим объявление ножек, вернее вместо объявления двух ножек у нас будет объявление одной

 

gpio_num_t gpio_one_wire_num = GPIO_NUM_4;

 

Определяем мы номер ножки RTC тоже только для одной ножки

 

int rtcio_one_wire_num = rtc_io_number_get(gpio_one_wire_num);
assert(rtc_gpio_is_valid_gpio(gpio_one_wire_num) && "GPIO must be an RTC IO");

 

Настраиваем ножку пока для начала на вход

 

rtc_gpio_init(gpio_one_wire_num);
rtc_gpio_set_direction(gpio_one_wire_num, RTC_GPIO_MODE_INPUT_ONLY);

 

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

 

rtc_gpio_init(gpio_button_num);
rtc_gpio_set_direction(gpio_button_num, RTC_GPIO_MODE_INPUT_ONLY);
rtc_gpio_pulldown_dis(gpio_button_num);
rtc_gpio_pullup_dis(gpio_button_num);
rtc_gpio_hold_en(gpio_button_num);

 

Далее также меняем имя переменной

 

uint32_t bit = rtcio_one_wire_num + 14;

 

Идём теперь в ассемблерный файл ulp_assembly_source_file.S и изменим там также имена команд в секции data

 

Команду для получения уровня ножки пока не добавляем. Будем работать с метками прямо в основном коде.

 

 

Также выше добавим ещё две команды, которые настраивают ножку на вход или выход (команда установки бита настраивает на выход, сброса — на вход)

 

 

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

 

ulp_set_led_pin&=0xf003ffff; // mask off bits 18-27
ulp_set_led_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read
ulp_clear_led_pin&=0xf003ffff; // mask off bits 18-27
ulp_clear_led_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read

bit = rtcio_button_num + 14;
ulp_get_button_pin&=0xf003ffff; // mask off bits 18-27
ulp_get_button_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read

 

вставим настройку наших всех команд по тому же принципу

 

ulp_set_out_one_wire_pin&=0xf003ffff; // mask off bits 18-27
ulp_set_out_one_wire_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read
ulp_set_in_one_wire_pin&=0xf003ffff; // mask off bits 18-27
ulp_set_in_one_wire_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read
ulp_set_one_wire_pin&=0xf003ffff; // mask off bits 18-27
ulp_set_one_wire_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read
ulp_clear_one_wire_pin&=0xf003ffff; // mask off bits 18-27
ulp_clear_one_wire_pin|=(bit<<18)|(bit<<23); // modify from and to bit to read

 

Идём опять в файл ulp_assembly_source_file.S и удалим данный код

 

//delay(10 msec)
move r0, 10
psr
jump delay_ms

psr
jump set_led_pin

read_button_loop:
//delay(10 ms)
move r0, 10
psr
jump delay_ms
psr
jump get_button_pin
jumpr read_button_loop, 1, eq

psr
jump clear_led_pin

//delay(1 sec)
move r0, 1000
psr
jump delay_ms

psr
jump set_led_pin

 

Останется у нас получение адреса стека, задержка на 4 секунды, выход из спящего режима и процедура задержки.

 

 

Также давайте добавим макросы для наших самодельных команд, чтобы наш дальнейший код стал ещё читабельней

 

 

Добавим метку для процедуры получения температуры с датчика с возвратом

 

 

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

 

 

Вызовем данную процедуру в процедуре get_temp

 

 

А процедуру get_temp вызовем в основном коде

 

 

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

 

 

И перейдём на данную метку в основном коде

 

 

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

 

 

И через примерно 500 микросекунд (не менее 480 микросекунд согласно документации, вычисляется по частоте работы сопроцессора) поднимем обратно

 

 

Давайте проверим, что у нас меняется уровень ножки в программе логического анализа. Тем самым мы определим, откликнулся ли наш датчик. Если датчик есть, то он прижмёт ножку к общей шине. Время ожидания датчика согласно технической документации — от 15 до 60 микросекунд. Поэтому после поднятия ножки настроим её на вход и подождём примерно 30 микросекунд

 

 

Настройку шины 1-wire производим так же, как во всех уроках по датчику DS18b20. Соберём наш код, прошьём контроллер и посмотрим результат

 

 

Всё отлично! Мало того, что мы видим наш импульс. Мы также видим и ответ нашего датчика.

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

После задержки отследим уровень нашей ножки

 

 

Метка добавлена для того, чтобы при настройке менять номер ножки аналогично тому, как мы делали в секции data.

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

 

 

Вернёмся в файл ulp_assembly_source_file.S и в секции bss добавим переменную для хранения значения регистра r0

 

 

Сохраним значение регистра r0 в данной переменной в процедуре rst_pulse

 

 

Подождём примерно 470 микросекунд. Это необходимое время, через которое мы уже можем полноправно работать с датчиком и можем считать, что инициализация завершена

 

 

В функции app_main файла main.c покажем значение нашей переменной в терминале

 

 

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

 

Результат — ноль, значит уровень низкий.

Отсоединим датчик от схемы, тем самым имитируя его неработоспособность или отсутствие

 

 

Регистр примет значение 1, значит уровень высокий, то есть от датчика ответа нет

 

 

Как только мы подключим обратно датчик, регистр примет нулевое значение

 

 

Итак, на данном уроке нам удалось научиться менять режим работы ножек GPIO во время глубокого сна при помощи сопроцессора ULP, что позволило нам отследить наличие датчика DS18B20 на ножке. Дальнейшая задача — отправить команду в датчик и получить от него значение температуры.

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

 

Данная статья в Дзен.

 

 

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

 

Исходный код

 

 

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

На AliExpress Недорогие отладочные платы ESP32

На Яндекс.Маркет Недорогие отладочные платы ESP32

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

На AliExpress DS18B20 в экране с проводом

На Яндекс.Маркет DS18B20 в экране с проводом

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

 

 

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

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

 

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

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

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

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

*