arduino timer - el-pths/w GitHub Wiki
#Ардуино - часть 4
###Таймеры
Контроллеры AtMega имеют в составе себя 3 таймера - устройства, которые могут постоянно и равномерно увеличивать значение специальных регистров независимо от работы программы. Кроме того, если таймер переключить так, чтобы он считал не тики внутреннего генератора, а импульсы на одной из ног - то он становится "счетчиком". Типичные примеры когда это может потребоваться:
- необходимо измерять сигнал, например, 500 раз в секунду с равной периодичностью;
- измерение длительности какого-то сигнала (например, от датчика расстояния);
- подсчет импульсов за единицу времени (например, от счетчика радиоактивного излучения).
Таймеры 0 и 2 работают с 8-разрядными регистрами (т.е. могут считать не больше чем до 255, после чего начинают с 0). Таймер 1 является 16-разрядным. Таймеры можно запускать непосредственно от тиков тактового генератора (на ардуино он работает с частотой 16 МГц) или от делителя частоты (например, с делителем на 64 частота будет 250 кГц, т.е. один тик в 4 микросекунды). Кроме того у таймеров много разных режимов - они могут считать в сторону увеличения и уменьшения, могут в обе попеременно. Могут сбрасываться доходя до нужного числа и т.п.
###Прерывания
Прерываниями называется возможность по сигналу от какого-то из устройств (например, таймера или АЦП) прервать выполнение основной программы и выполнить отдельную маленькую функцию назначенную для обработки этого прерывания (ISR - Interrupt Service Routine - подпрограмма обработки прерывания).
###Использование прерываний от таймера
Попробуем создать несколько наивный пример. Возьмем программу мигающую светодиодом, и добавим к ней обработку прерывания от таймера, так чтобы она периодически выписывала в UART в каком состоянии сейчас светодиод:
void setup() {
pinMode(13, OUTPUT);
// ... setup timer 0 here for overflow interrupt
}
void loop() {
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
ISR(TIMER1_OVF_vect) {
// ...
Serial.println(digitalRead(13)); // print the state of LED
}
Осталось только сконфигурировать (внутри setup
) таймер таким образом чтобы эта функция вызывалась, например несколько раз в секунду и мы могли наблюдать в Serial Monitor что она прилежно выписывает изменяющееся состояние светодиода.
Можно также добавить в эту программу изменение частоты мигания, если с компьютера по UART поступил какой-нибудь управляющий символ (например от 1 до 9).
В качестве дополнительных источников две статьи с примерами: короткая и подлиннее
Полезно также почитать и понять смысл значений записываемых в регистры таймера (по документации на AtMega32U4).