Таймеры 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 разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
Разработка IoT устройств под ключ

Разработка IoT устройств под ключ

Разработка IoT устройств под ключ Вам нужно IoT устройство под ключ — от ..

Основы автоматики

Основы автоматики

Основы автоматикиДавайте поговорим об автоматике в контексте домашнего применения. Но только мы отой..

Автоматическое реверсивное управление двигателем с ATtiny85

Автоматическое реверсивное управление двигателем с ATtiny85

Постановка задачи проекта Ставим задачу автоматически таскать двигателем постоянного тока полезны..

Watchdog и таймеры ESP32

Watchdog и таймеры ESP32

Watchdog и таймеры ESP32 ESP32 оснащён встроенным Watchdog Timer (WDT), который используется для ..

Сколько стоит разработка печатной платы: факторы, примеры и реальные сроки

Сколько стоит разработка печатной платы: факторы, примеры и реальные сроки

Один из самых частых вопросов от заказчиков: сколько стоит разработка печатной платы и от чего завис..