Таймеры Arduino UNO — Часть 2. Работа с прерываниями таймеров

Теория

Что такое прерывание и зачем оно нужно

Прерывание — это специальный механизм микроконтроллера, позволяющий при возникновении определённого события мгновенно приостановить выполнение основного кода и выполнить специальную функцию — обработчик прерывания (ISR, Interrupt Service Routine).

Прерывания используются для задач, которые требуют высокой точности по времени, например, измерение интервалов, генерация сигналов, опрос датчиков, приём данных по UART.

Настройка аппаратного таймера на прерывания

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

  1. Выбрать режим работы таймера (например, CTC — сброс по совпадению).
  2. Установить значение сравнения в регистре OCRnA (Output Compare Register).
  3. Разрешить прерывание в регистре TIMSKn.
  4. Разрешить глобальные прерывания командой sei().

Регистр TIMSKx и векторы прерываний

  • TIMSK0, TIMSK1, TIMSK2 — регистры разрешения прерываний для соответствующих таймеров.
  • Вектор прерывания — это адрес функции, которую вызовет контроллер при срабатывании события. Например, для таймера 1 в режиме CTC это TIMER1_COMPA_vect.

Практика

Настройка Timer1 для вызова прерывания каждые 1 мс


#include <avr/interrupt.h>

volatile unsigned long counter = 0; // Счётчик миллисекунд

void setup() {
  pinMode(13, OUTPUT);

  // Настройка Timer1
  noInterrupts();           // Отключаем прерывания
  TCCR1A = 0;               // Регистр управления A
  TCCR1B = 0;               // Регистр управления B
  TCNT1  = 0;               // Сброс счётчика

  OCR1A = 15999;            // 16 МГц / 1000 Гц / 1 = 16000 - 1
  TCCR1B |= (1 << WGM12);   // Режим CTC
  TCCR1B |= (1 << CS10);    // Делитель 1 (prescaler 1)
  TIMSK1 |= (1 << OCIE1A);  // Разрешаем прерывание по совпадению

  interrupts();             // Включаем прерывания
}

ISR(TIMER1_COMPA_vect) {
  counter++;
  digitalWrite(13, !digitalRead(13)); // Мигаем светодиодом
}

void loop() {
  // Основной код может выполняться параллельно
}
  

Мерцание светодиода в обработчике прерывания

В приведённом примере встроенный светодиод на пине 13 мигает каждые 1 мс. Однако на практике так часто мигать не имеет смысла — человеческий глаз не заметит.

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

Создадим секундомер, который считает время с точностью до миллисекунды, используя прерывания Timer1.


#include <avr/interrupt.h>

volatile unsigned long millisCounter = 0;

void setup() {
  Serial.begin(9600);

  // Настройка Timer1
  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  OCR1A = 249;              // 16 МГц / 64 / 1000 Гц = 250 - 1
  TCCR1B |= (1 << WGM12);   // Режим CTC
  TCCR1B |= (1 << CS11) | (1 << CS10); // Делитель 64
  TIMSK1 |= (1 << OCIE1A);  // Разрешаем прерывание

  interrupts();
}

ISR(TIMER1_COMPA_vect) {
  millisCounter++;
}

void loop() {
  static unsigned long lastPrint = 0;
  if (millisCounter - lastPrint >= 1000) { // Каждую секунду
    lastPrint = millisCounter;
    Serial.print("Секунд прошло: ");
    Serial.println(millisCounter / 1000);
  }
}
  

Теперь секундомер работает независимо от основного кода, благодаря прерываниям, а точность не зависит от функций delay().

<< Проекты << Все товары >> Статьи, уроки >>

Написать отзыв

Примечание: HTML разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Модуль реле для Wemos D1 mini

Модуль реле для Wemos D1 mini

Модуль с электромагнитным реле для установки на плату контроллера Wemos D1 miniХарактеристики реле: ..

51.63грн.

Модуль реле 5В HIGH высокий уровень срабатывания

Модуль реле 5В HIGH высокий уровень срабатывания

Одноканальный модуль реле с питанием  катушки 5 В и прямой логикой срабатывания.Максимальная ко..

75.23грн.

Плата защиты балансировки 2-х литий-ионных аккумуляторов 7,4В

Плата защиты балансировки 2-х литий-ионных аккумуляторов 7,4В

Контроллер BMS защиты двух 18650 аккумуляторов с балансиром Защитная плата литиевой батареи, з..

112.18грн.

ATtiny обзор контроллеров

ATtiny обзор контроллеров

Обозначение Память программ (FLASH) [Kбайт] Память данных [байт] Kол-во линий ввода/..

Изготовление печатных плат при помощи лазерного принтера

Изготовление печатных плат при помощи лазерного принтера

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