Прерывания по таймеру на Ардуино

Таймер на плате

В AVR-микроконтроллерах, на которых частично основаны платы Arduino, есть встроенные таймеры-счетчики (далее — ТС), которые позволяют отсчитывать точные промежутки времени. По окончании этих периодов может потребоваться выполнить нужную задачу, которую лучше реализовать в подпрограмме ТС. Для этого необходимо разобраться, как программировать в «Ардуино» прерывания по таймеру.

Что такое таймер и принцип его работы

Таймер-счетчик — отдельный модуль внутри микроконтроллера, который состоит из:

  • системы управления (на основе различных регистров);
  • логических элементов;
  • предделителя (задает скорость работы ТС).

Принцип работы модуля прост: он постоянно считает значения и в нужный момент запускает собственную программу выполнения задачи. Программа запускается в специальном обработчике. Чтобы попасть в него, необходимо разрешить на Arduino прерывания общего типа (на языке C это позволяет сделать команда sei();).

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

Подключение библиотеки timer-api.h

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

Для этого нужно:

  1. Скачать архив с библиотекой.
  2. Открыть среду программирования (например, Arduino).
  3. Нажать «Скетч».
  4. Выбрать пункт «Подключить библиотеку».
  5. Установить архив с библиотекой.

Библиотека timer-api.h

Чтобы пользоваться функциями этой сборки в программе, нужно в начале скетча прописать строку: #include «timer-api.h».

Эту библиотеку целесообразно устанавливать в следующих случаях:

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

Варианты частот для timer_init_ISR_XYHz

Настройка ТС начинается с определения скорости его работы. В библиотеке для этого существует функция timer_init_ISR_XYHz. На месте XY следует указать частоту вызова программы обработчика прерывания (ISR — Interrupt Service Routine).

void loop()

{

timer_init_ISR_1Hz(*указывается нужный таймер*);

}

Все действия, которые должна выполнить подпрограмма, нужно указать в функции timer_handle_interrupts.

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

КГц Гц
500 500
200 200
100 100
50 50
20 20
10 10
5 5
2 2
1 1

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

Stm таймеры

Деление частоты

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

Алгоритм такой регулировки частоты следующий:

  1. Объявить переменную для счета (например, schet).
  2. Прописать в функции timer_handle_interrupts команду schet++.
  3. Как только переменная достигнет нужного значения, выполнить необходимые действия.

void timer_handle_interrupts(int timer)

{

uint8_t schet = 0;

schet++;

if (schet > 3)

{

*выполнение подпрограммы*;

schet = 0;

}

}

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

Библиотека позволяет активировать таймер на произвольной частоте.

Для этого нужно вызвать функцию timer_init_ISR(1-й указатель, 2-й указатель, 3-й указатель), где:

  • 1-й указатель — нужный ТС;
  • 2-й указатель — предделитель;
  • 3-й указатель — значение регистра счета.

Вместо 1-го указателя можно написать:

  1. TIMER_DEFAULT — указатель рабочего таймера по умолчанию.
  2. _TIMER1 или _TIMER1_8BIT — указатель нужного таймера.

Одним из вариантов prescaler может быть TIMER_PRESCALER_1_128, который означает, что частота работы таймера в 128 раз меньше частоты, на которой работает микроконтроллер.

Опции DEFAULT

Значение регистра счета задается в формате 40000-1. Вычитание единицы в данном случае необходимо, чтобы учесть, что счет ведется с нуля.

Запуск и остановка таймера в динамике

Чтобы запустить ТС, следует вызвать функцию настройки частоты его работы. Останавливается таймер вызовом команды timer_stop_ISR.

void loop()

{

*функция настройки частоты выхода в подпрограмму*;

*выполнение нужных действий и задач микроконтроллером*;

timer_stop_ISR(*указывается нужный ТС*); // остановка ТС

}

Старт и стоп

Особенности установки библиотеки

Есть быстрый метод загрузки библиотеки в программу, но он требует глубоких знаний работы операционных систем.

Этот метод заключается в клонировании репозитория в каталог с другими библиотеками с помощью следующей команды:

cd ~/*папка установки среды программирования*/*папка с библиотеками*/git clone *ссылка на библиотеку со стороннего сайта*

По завершении процедуры необходимо перезапустить среду программирования (в данном случае — Arduino).

После использования любого метода установки библиотеки в разделе File, пункте Examples появится шаблон с применением ее команд. Этот скетч демонстрирует работу заложенных функций. Также из него можно брать готовые части кода, чтобы не писать их самостоятельно и программировать быстрее.

Чипы и платформы

Данная библиотека, хотя и написана на C, поддерживает только 3 семейства микропроцессоров.

Чип Платформа Разрядность Частота Плата
Серия Mega AVR 16 bit 16 МГц Arduino
SAM ARM 32 bit 84 МГц Arduino Due
PIC32MX MIPS 32 bit 80 МГц ChipKIT

Частично поддерживает работу с этой библиотекой MIPS-микроконтроллер PIC32MZ на частоте 200 МГц.

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

Ссылка на основную публикацию