Таймеры Arduino UNO — Часть 6. Оптимизация и нестандартные применения

Теория

Совмещение работы нескольких таймеров

В микроконтроллере ATmega328P (Arduino UNO) есть три аппаратных таймера: Timer0, Timer1 и Timer2. Каждый из них может работать в своём режиме, что позволяет одновременно выполнять несколько задач:

  • Timer0 — обычно используется функциями millis() и delay(), но его можно перенастроить.
  • Timer1 — 16-битный, подходит для точных замеров времени, генерации сигналов низкой частоты, работы с сервоприводами.
  • Timer2 — 8-битный, может работать на другой частоте (асинхронно), полезен для звука и ШИМ.

Совмещение работы требует аккуратного управления регистрами, чтобы конфигурации одного таймера не мешали работе других.

Оптимизация под низкое энергопотребление

Таймеры могут быть источником лишнего потребления энергии в спящем режиме. Для снижения энергопотребления можно:

  • Отключать ненужные таймеры с помощью регистра PRR (Power Reduction Register).
  • Использовать режимы сна микроконтроллера (SLEEP_MODE_IDLE, SLEEP_MODE_PWR_DOWN).
  • Снижать частоту тактирования или увеличивать предделитель.

Подмена работы millis() и delay() своими таймерами

Функции millis() и delay() используют Timer0. Если этот таймер нужен для других задач, можно отключить стандартный обработчик и реализовать собственный счётчик времени на Timer1 или Timer2. Это позволяет полностью контролировать тайминг программы.

Практика

Секундомер с точностью 0.1 мс


volatile unsigned long ticks = 0;

ISR(TIMER1_COMPA_vect) {
  ticks++; // каждые 100 мкс
}

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

  TCCR1A = 0;
  TCCR1B = (1 << WGM12) | (1 << CS10); // CTC, делитель 1
  OCR1A = 1599; // 16 МГц / 1600 = 10 000 Гц (100 мкс)
  TIMSK1 = (1 << OCIE1A);
}

void loop() {
  Serial.print("Время: ");
  Serial.print(ticks / 10.0); // в миллисекундах с точностью 0.1 мс
  Serial.println(" мс");
  delay(500);
}
  

Звуковой генератор


void setup() {
  pinMode(3, OUTPUT); // OC2B

  TCCR2A = (1 << COM2B0) | (1 << WGM21); // Toggle OC2B, CTC
  TCCR2B = (1 << CS20); // Без делителя
  OCR2A = 113; // ~7 кГц
}

void loop() {
  // Генерация звука идёт автоматически
}
  

Проект: Музыкальный генератор на таймерах

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


struct Note {
  uint16_t ocr;
  uint16_t duration;
};

Note melody[] = {
  {113, 500}, // Ля
  {101, 500}, // Си
  {95,  500}, // До
  {85,  500}, // Ре
};

void setup() {
  pinMode(3, OUTPUT);
  TCCR2A = (1 << COM2B0) | (1 << WGM21); // Toggle OC2B, CTC
  TCCR2B = (1 << CS20);
}

void loop() {
  for (int i = 0; i < 4; i++) {
    OCR2A = melody[i].ocr;
    delay(melody[i].duration);
  }
  delay(1000);
}
  

Такой генератор можно использовать для создания простых звуковых сигналов, оповещений и даже музыкальных игрушек на Arduino UNO.

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

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

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

Какие виды дисплеев можно использовать с Arduino для отображения информации

Какие виды дисплеев можно использовать с Arduino для отображения информации Arduino — это п..

Циклы 7 — Циклы и задержки

Циклы 7 — Циклы и задержки

Циклы 7 — Циклы и задержки Введение В Arduino часто используется функция delay() для создания па..

Разъемный коннектор JST SM

Разъемный коннектор JST SM

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

31.09грн.

Шилд для Arduino Nano и GSM SIM800 с 2реле

Шилд для Arduino Nano и GSM SIM800 с 2реле

Шилд для проектов с использованием платы контроллера Arduino Nano и GSM модуля SIM800. Решает пробле..

479.09грн.

Arduino 4-20 мА подключение датчика уровня

Arduino 4-20 мА подключение датчика уровня

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