В данном уроке мы настроем прерывание от внутреннего таймера без использования arduino библиотек, но в среде программирования Arduino IDE.
Использовать мы будем плату Arduino Nano, данная плата плата на борту содержит микроконтроллер Atmega 328 , у которой в наличии три таймера: Timer0, Timer1 и Timer2.
Timer0 — 8 битный таймер, с максимальным числом счета до 255. Данный таймер используется стандартными временными функциями Arduino такими как delay() и millis(), поэтому при использовании arduino библиотек нужно быть с ним аккуратным.
Timer1 — 16 битный таймер, с максимальным числом счета 65535. Данный таймер использует библиотека Arduino Servo.
Timer2 — 8 битный таймер, с максимальным числом счета до 255. Он используется в Arduino функции tone().
Для настройки таймеров нам понадобятся следующие регистры:
TCCRxA и TCCRxB, где x — номер таймера
Регистр TCCR1A :
Регистр TCCR1В :
Рассмотрим настройки необходимых для нас бит:
Так как наш микроконтроллер работает на частоте 16 МГц, а мы хотим управлять светодиодом, для увеличения времени счета нашего таймера, мы поделим его тактовую частоту на 1024:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
Таким образом мы получаем скорость счета (тактирования) 15625 Гц или 64,0е-6 секунды. Нам нужно, что бы счетчик менял свое состояние раз в 0,5 секунду, разделив 0,5/64,0е-6 мы получаем 7812,5. Таким образом в регистр OCR1A нам необходимо записать 7813. Но с учетом того, что сброс счетчика в ноль занимает один такт, нам необходимо записать в регистр OCR1A — 7812.
#include <avr/io.h> #include <avr/interrupt.h> #define LED 13 void setup() { // инициализация Timer1 cli(); // отключить глобальные прерывания TCCR1A = 0; // установить регистры в 0 TCCR1B = 0; OCR1A = 7812; // установка регистра совпадения TCCR1B |= (1 << WGM12); // включить CTC режим TCCR1B |= (1 << CS10); // Установить биты на коэффициент деления 1024 TCCR1B |= (1 << CS12); TIMSK1 |= (1 << OCIE1A); // включить прерывание по совпадению таймера sei(); // включить глобальные прерывания pinMode(LED, OUTPUT); } ISR(TIMER1_COMPA_vect){ digitalWrite(LED, !digitalRead(LED)); } void loop() {}