Использование таймеров и прерываний от них в модуле ESP32


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

Внешний вид проекта использования таймеров в модуле ESP32

В данной статье мы рассмотрим использование таймеров и прерываний от них в модуле ESP32. Данный модуль содержит две аппаратных группы таймеров, каждая из которых содержит два таймера общего назначения. Данные таймеры являются 64-битными с 16-битным предделителем, с возможностью автоматической перезагрузки.

Таймеры в модуле ESP32

Также на нашем сайте мы рассматривали использование таймеров в других микроконтроллерах (платах):

Прерывания от таймеров

Прерывания от таймеров являются эффективным средством обеспечения точных временных задержек, что востребовано, к примеру, в операциях формирования сигналов ШИМ (широтно-импульсной модуляции). Эти прерывания являются программными и позволяют отмерять заданные временные интервалы вне зависимости от того, какими другими задачами в это время занят микроконтроллер. Они во многом похожи на внешние аппаратные прерывания, но они срабатывают не от какого то внешнего события, а от события переполнения таймера. При срабатывании они ждут пока завершится текущая выполняемая инструкция, после этого прерывают выполнение основной программы при помощи вызова функции обработки прерывания (ISR) и после ее выполнения возвращают исполнение основной программы к следующей инструкции. Принцип формирования прерываний от таймеров показан на следующем рисунке.

Принцип формирования прерываний от таймеров

Таймеры являются аппаратно-зависимыми, а скорость их счета (скорость таймера) можно определить по следующей формуле:

К примеру, если мы в модуле ESP32, работающим на тактовой частоте 80MHz, установим коэффициент деления предделителя (prescaler value) равный 1, то мы получим скорость счета таймера равную 80MHz, а если мы установим коэффициент деления предделителя равный 80, то мы получим скорость счета таймера равную 1MHz или 1000000Hz.

Процесс обработки прерывания от таймера по отношению к исполнению основной программы показан на следующем рисунке.

Процесс обработки прерывания от таймера по отношению к исполнению основной программы

Также, как и в случае с аппаратными прерываниями, прерывания от таймеров являются самым лучшим способом запуска не блокируемых ничем функций через заданные интервалы времени. Для этого в функции setup программы мы настраиваем и прикрепляем прерывание от конкретного таймера к определенной функции обработки прерывания (ISR). Далее микроконтроллер будет последовательно исполнять команды в основной функции программы main. И при срабатывании прерывания от таймера микроконтроллер будет останавливать выполнение основной программы и начинать выполнение функции обработки прерывания (Interrupt Service Routine, ISR). После того как микроконтроллер завершит выполнение функции ISR, он продолжит выполнение основной программы с того места, на котором ее выполнение прервало прерывание. Данные процессы будут происходить при каждом срабатывании прерывания от таймера.

Более подробно об использовании прерываний в модуле ESP32 вы можете прочитать в этой статье.

Наиболее часто задаваемые вопросы про прерывания от таймеров в ESP32

Как много таймеров содержит модуль ESP32?
Он содержит четыре 64-битных таймера.

Как использовать прерывания от таймеров в модуле ESP32?
Необходимо прикрепить конкретный таймер к прерыванию и назначить ему функцию обработки (ISR).

Как работают таймеры в модуле ESP32?
Таймеры используют счетчик, который считает со скоростью, зависящей от тактовой частоты микроконтроллера и коэффициента деления предделителя. Таймер сбрасывается когда его счетчик достигает заданного значения и запускает срабатывание прерывания. Мы можем изменить периодичность срабатывания интервала от таймера изменяя это значение, до которого считает таймер.

Схема проекта

В нашей статье мы рассмотрим пример использования прерывания от таймера в модуле ESP32 на примере со светодиодом. Для этого мы будем использовать схему проекта, приведенную на следующем рисунке.

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

Внешний вид собранной на макетной плате конструкции проекта показан на следующем рисунке.

Внешний вид собранной на макетной плате конструкции проекта

Объяснение кода программы для модуля ESP32

Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты. В нашем примере светодиод будет мигать с частотой 1 Гц.

Вначале программы дадим осмысленное наименование контакту, к которому подключен светодиод (GPIO21). Затем создадим указатель на переменную с именем My_timer и типом type hw_timer_t для того чтобы в последующем производить настройку таймера.

Далее запрограммируем функцию обработки прерывания от таймера (ISR). В ней мы будем инвертировать состояние контакта GPIO21, к которому подключен светодиод. Данная функция ISR будет вызываться каждый раз при срабатывании прерывания от таймера.

Затем в функции void setup() мы зададим режим работы контакта, к которому подключен светодиод, на вывод данных.

Для инициализации таймера мы будем использовать функцию timerbegin с необходимыми параметрами. Первым из них будет номер таймера, который мы будем использовать (их номера от 0 до 3 поскольку у нас 4 таймера в модуле ESP32). Второй – это коэффициент деления предделителя и последний – это флаг, показывающий должен ли счетчик таймера считать вверх (true) или вниз (false). В нашем проекте мы используем timer 0 с коэффициентом деления предделителя 80 и счетчиком, считающим вверх.

Перед тем как задействовать таймер, мы должны прикрепить (attach) к нему функцию обработки прерывания (ISR), которая будет исполняться при срабатывании прерывания. Делать мы это будем с помощью функции timerAttachInterrupt. В нашем примере мы прикрепим функцию обработки прерывания onTimer к нашему таймеру.

Далее мы будем использовать функцию timerAlarmWrite чтобы загрузить в таймер значение, при достижении которого счетчиком таймера должно срабатывать прерывание от таймера. В нашем примере нам необходимо формировать прерывание каждую секунду, поэтому мы загрузим в таймер значение 1000000 микросекунд, что равно 1 секунде. В качестве третьего параметра функции timerAlarmWrite мы используем значение true, что будет означать что счетчик таймера будет перезагружаться и, таким образом, прерывание будет срабатывать периодически.

И, наконец, нам необходимо включить использование прерывания от таймера с помощью функции timerAlarmEnable.

Исходный код программы

Все необходимые файлы для этого проекта можно скачать по следующей ссылке.

Источник статьи

(Проголосуй первым!)
Загрузка...
208 просмотров

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

Ваш адрес email не будет опубликован.