Продолжаем работу с сопроцессором ULP и на данном уроке мы продолжим работу с устройством, взаимодействующим с контроллером по шине 1-Wire, а именно с датчиком температуры DS18B20.
И на на данном уроке мы попытаемся передать данные из нашего контроллера в датчик. Это могут быть команды, а также любые данные.
Схема наша осталась та же, что и в прошлом уроке — отладочная плата с контроллером esp32, подключенный к ней датчик температуры DS18B20, а также логический анализатор, подключенный к сигнальной ножке датчика для анализа обмена данными по шине
Проект за основу мы также возьмём из прошлого урока с именем ULP_FSM_ONEWIRE_INIT и дадим ему новое имя ULP_FSM_ONEWIRE_SEND.
Откроем проект в Espressif IDE, откроем файл ulp_assembly_source_file.S и в процедуре rst_pulse удалим сохранение регистра в память
move r2, dataR0
st r0, r2, 0
Переменную для сохранения пока оставим, вдруг пригодится.
После процедуры get_temp добавим ещё одну для отправки байта в шину, в которой для начала скопируем значение регистра r2, в котором будет находиться байт, который мы будем отправлять в шину, в регистр r1, а затем обнулим значение регистра r0
1 2 3 4 |
send_byte: move r1, r2 move r0, 0 ret |
Добавим метку для цикла, так как нам надо будет передавать каждый бит отдельно и сдвинем значение регистра r1 вправо на значение, находящееся в регистре r0 (при первом входе в метку ничего не сдвинется, так как в r0 у нас 0) и запишем результат в регистр r2
1 2 3 |
move r0, 0 send_byte_loop: rsh r2, r1, r0 |
У нас новая команда
Инструкция RSH выполняет логический сдвиг вправо исходного регистра на количество битов из другого исходного регистра или 16-битного знакового значения и сохраняет результат в регистре назначения.
При помощи следующей команды мы в регистре r2 оставим только значение нулевого бита
1 2 |
rsh r2, r1, r0 and r2, r2, 0x01 |
Ниже процедуры send_byte добавим процедуру, которая будет отправлять в шину бит, значение которого будет находиться в регистре r2
1 2 3 4 |
send_bit: GPIO_OUT GPIO_LOW ret |
В данной процедуре мы настроили ножку на выход и установили на ней низкий уровень.
Подождём немного и вычтем ноль из регистра r2 и в него же запишем
1 2 3 |
GPIO_LOW wait(30) //5us sub r2, r2, 0 |
Здесь возникает вопрос, зачем мы вычли ноль из регистра и записали в него же. Вроде бы ничего не произошло, значение осталось. Но зато мы тем самым узнаем значение в регистре r2 и можем результат использовать в условии, которое будет ниже.
А ниже мы добавим две метки
1 2 3 4 5 6 |
sub r2, r2, 0 send_bit_high: GPIO_HIGH send_bit_low: wait(640) /* 80us */ GPIO_HIGH |
Если мы не перейдём во вторую метку, то мы сразу установим высокий уровень, а если перейдём, то только через примерно 80 микросекунд, тем самым обеспечим условие передачи бита (низкий уровень — ноль, высокий — единица).
Выше перейдём на вторую метку при условии, что у нас ноль
1 2 3 |
sub r2, r2, 0 jump send_bit_low, eq send_bit_high: |
Возвращаемся в процедуру send_byte и, сохранив регистры r0 и r1 в стеке, вызовем нашу процедуру передачи бита, после чего вернём значения регистров из стека
1 2 3 4 5 6 7 |
and r2, r2, 0x01 push r0 push r1 psr jump send_bit pop r1 pop r0 |
Инкрементируем значение r0, и если не достигли 8, то повторяем цикл
1 2 3 |
pop r0 add r0, r0, 1 jumpr send_byte_loop, 8, LT |
Подождём немного на случай, если вдруг придётся ещё что-то передавать, так как между переданными байтами должны быть паузы
1 2 |
jumpr send_byte_loop, 8, LT wait(800) //100us |
В процедуре get_temp передадим две команды
1 2 3 4 5 6 7 8 |
jump rst_pulse //send 0xCC and 0x44 command move r2, 0xCC psr jump send_byte move r2, 0x44 psr jump send_byte |
Команду 0xCC (SKIP ROM) мы передаём, чтобы сказать датчику, что мы пропусканием чтение ROM, а команду 44 (Convert T) — чтобы скомандовать датчику, чтобы он начал конвертацию значения температуры в цифровую последовательность (запустил АЦП).
В файле main.c в функции app_main удалим вывод значения регистра r0 в терминал
printf("R0: %5d\n", ulp_dataR0 & UINT16_MAX);
Попробуем собрать код и прошить контроллер.
Вот результат работы нашего кода
Отлично! Нам удалось отправить команды в датчик.
Всем спасибо за внимание!
Предыдущий урок Программирование МК ESP32 Следующий урок
Недорогие отладочные платы ESP32 можно купить здесь Недорогие отладочные платы ESP32
Недорогие отладочные платы ESP32/ESP32-C3/ESP32-S3 можно купить здесь Недорогие отладочные платы ESP32
Датчик температуры DS18B20 в экране с проводом можно приобрести здесь DS18B20
Логический анализатор 16 каналов можно приобрести здесь
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в Дзен (нажмите на картинку)
Добавить комментарий