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

Универсальная монтажная плата на 400 отверстий

Макетная плата на 400 отверстий для макетирования любительских схемотехнических проектов. Имеет 4 ли..

85.85грн.

Arduino SIM800 исходящий звонок ATD

Arduino SIM800 исходящий звонок ATD

Привет друзья! Это продолжение серии статей о работе с SIM800. Всех их можно найти на этом канале.&n..

Символьный LCD индикатор 16х2 синий

Символьный LCD индикатор 16х2 синий

Символьный двухстрочный жидкокристаллический индикатор. 16 символов в одной строке.Синяя подсветкаСо..

83.25грн.

Двойная шестерня для зубчатого ремня на 20 зубьев под ось 5 мм

Двойная шестерня для зубчатого ремня на 20 зубьев под ось 5 мм

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

97.08грн.

Светодиод 5мм

Светодиод 5мм

Светодиод диаметром 5мм. LED Максимальный ток 20 мА ..

1.98грн.