Таймеры Arduino UNO — Часть 1. Введение
Теория
Что такое таймер в микроконтроллере ATmega328P
Таймер — это встроенный аппаратный модуль микроконтроллера, который считает такты от внутреннего или внешнего источника тактовых импульсов. Таймеры используются для измерения времени, создания точных задержек, генерации сигналов ШИМ (PWM) и работы с прерываниями.
Аппаратные и программные таймеры
- Аппаратные таймеры — реализованы на уровне микросхемы. Работают независимо от основного кода и могут выполнять задачи в фоне. Обеспечивают высокую точность.
- Программные таймеры — реализованы в виде функций и библиотек (например, на основе
millis()). Менее точны, зависят от выполнения остального кода.
Отличие delay() / millis() от аппаратных таймеров
Функция delay() блокирует выполнение программы, останавливая её на заданное время. Это просто «пауза» в коде.
millis() и micros() используют аппаратный таймер (Timer0) для подсчёта времени, но не блокируют выполнение кода. С их помощью можно измерять интервалы времени и создавать неблокирующую логику.
Обзор трёх таймеров Arduino UNO
- Timer0 — 8-битный, используется для работы функций
millis(),micros(),delay(), а также ШИМ на пинах D5 и D6. - Timer1 — 16-битный, подходит для точных измерений времени, работы сервоприводов, генерации медленных ШИМ-сигналов.
- Timer2 — 8-битный, может работать от отдельного тактового источника, используется для генерации звуков и управления ШИМ на пинах D3 и D11.
Практика
Измерение времени с помощью millis() и micros()
// Пример измерения интервала в миллисекундах
unsigned long startTime;
void setup() {
Serial.begin(9600);
startTime = millis();
}
void loop() {
if (millis() - startTime >= 1000) { // Прошла 1 секунда
Serial.println("Прошла секунда");
startTime = millis(); // Сброс таймера
}
}
Простейший пример мигания светодиода без delay()
const int ledPin = 13;
unsigned long previousMillis = 0;
const long interval = 500; // Интервал мигания (мс)
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin)); // Переключаем состояние LED
}
}
Проект: Мигание LED с разными интервалами без задержек
В этом проекте мы сделаем мигание светодиода, при котором каждое следующее мигание будет происходить быстрее или медленнее, в зависимости от заданного алгоритма.
const int ledPin = 13;
unsigned long previousMillis = 0;
long interval = 1000; // Начальный интервал (мс)
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
digitalWrite(ledPin, !digitalRead(ledPin));
// Меняем интервал
interval -= 100;
if (interval < 100) interval = 1000; // Сброс к начальному значению
}
}
Таким образом, мы использовали millis() вместо delay(), чтобы избежать блокировки программы и получить гибкое управление временем.




