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

Двухполярное питание из однополярного

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

Парсер температуры и влажности на WiFi-контроллереNodeMcu ESP8266

Парсер температуры и влажности на WiFi-контроллереNodeMcu ESP8266

У меня есть задумка сделать у себя дома возле входной двери индикатор внешней температуры, а так же ..

Блок питания 24В 1А 5,5х2,5мм

Блок питания 24В 1А 5,5х2,5мм

Блок питания 24В 1АПодходит для ультразвукового парогенератора 24ВРазъем 5,5 х 2,5мм..

205.07грн.

Как освободить память Arduino?

Как освободить память Arduino?

Программируя контроллеры Arduino мы часто попадаем в ситуацию, когда компилятор ругается на нехватку..

Умный дом 1. Постановка задачи.

Умный дом 1. Постановка задачи.

Умный дом 1. Постановка задачи. Каждый человек представляет себе свой умный дом в соответствии со с..