STM32L0 — задержка в микросекундах

Я использую плату B-L072Z-LRWAN1 (с микроконтроллером STM32L072) и хочу получать данные с датчика DHT11. Для этого мне нужна задержка в микросекундах, которую я не могу получить.

Библиотеки, предоставляемые ST, имеют функцию задержки миллисекунд, но не функцию микросекунд.

Мне нужна помощь. Заранее спасибо!

UPS! Старый заголовок был сохранен из предыдущего поста. Мои извинения.
На этом сайте приведен пример использования STM32 с DHT11. Он включает в себя код, но я не могу заглянуть внутрь, чтобы увидеть, как он работает. Код предоставляется в сжатом файле, который мой телефон не может распаковать.
Вам нужно быть более конкретным, чтобы иметь вопрос, на который можно ответить. Сколько микросекунд? С каким минимумом после ошибки? А какой максимум?
Мне нужны задержки 40 мкс и 80 мкс, чтобы иметь возможность считывать данные с датчика.

Ответы (1)

Вам не нужна задержка в микросекундах, а счетчик таймера с точностью до микросекунд.

Глядя на таблицу данных, связанную с @JRE, это асинхронный протокол. Хост передает длинный низкий импульс (не менее 18 миллисекунд ), и это единственный момент, когда MCU должен что-либо задерживать. Но у вас уже есть функция задержки в миллисекундах (и в любом случае это было бы лучше сделать в прерывании в миллисекундах , которое, вероятно, уже запущено).

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

Если запущено прерывание миллисекунд, то уже есть что-то подсчитывающее циклы. Обычно это SysTickтаймер. Дождитесь переднего фронта на выводе, получите метку времени от SysTick->VAL, дождитесь заднего фронта, снова прочитайте показания счетчика и вычтите предыдущую метку времени. Следите за переполнением, добавляйте SysTick->LOAD+1к результату, если он отрицательный. Разделите результат на тактовую частоту (в МГц), чтобы получить значение в микросекундах.

Однако вы можете предпочесть, чтобы микроконтроллер делал что-то полезное или позволил ему спать, чтобы экономить энергию, пока поступают данные.

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

Прочтите описание функций TIM2/TIM3/ раздел «Режим захвата ввода» в Справочном руководстве.

Поскольку нижняя фаза сигнала всегда должна иметь длину 50 мкс, вы также можете измерить время между двумя последовательными спадающими фронтами. Пример в руководстве предназначен для нарастающих фронтов, но, конечно, его можно изменить для захвата спадающих фронтов, изменив биты CC1Pи CC1NPна шаге 3.

  • Выберите канал таймера и соответствующий канал DMA. Используйте таблицу под названием Сводка запросов DMA для каждого канала .
  • Настройте канал прямого доступа к памяти для передачи 41 (для 1 стартового импульса + ​​40 импульсов данных) полуслова (16 бит) из регистра CCRканала таймера в массив подходящего размера в памяти.
  • Вы можете включить прерывание завершения передачи DMA, чтобы запустить обработчик, когда передача данных будет завершена.
  • Настройте таймер с предварительным делителем, равным тактовой частоте вашей системы в МГц (напишите на единицу меньше в PSC, и не забудьте установить UGв EGR), чтобы удобно было получить метку времени в миллисекундах.
  • Выполните процедуру, описанную в разделе Режим захвата ввода . В приложении есть даже простой пример кода. Адаптируйте его для захвата спадающих фронтов и на последнем шаге включите DMA вместо прерывания канала в DIER.
  • В качестве подстраховки можно включить прерывание обновления таймера. Он сработает через 65535 микросекунд, сообщая программе, что время ожидания передачи истекло. Меньшее значение тайм-аута может быть установлено в ARR.