В блоге Ноа Шталя есть пример мигания светодиода с помощью Timer2 . Имея это и таблицу данных, вы должны быть в состоянии адаптировать ее к любому прерыванию, которое вы хотите использовать, то есть к прерыванию, обычная функция которого вы больше всего можете оставить или хотите изменить. Таймер 2 обычно используется для некоторых функций ШИМ.
Его пример цитирует ATmega2560; Я могу подтвердить, что он работает и с ATmega328p. Посмотрите на его сайте более полезные примеры прерываний Arduino.
Редактировать:
Вот моя слегка отредактированная - в основном в комментариях - версия кода Ноя. Вызовите Timer2init () из функции setup () Arduino после инициализации любых связанных структур данных или оборудования, потому что синхронизация - и прерывание - начнутся, как только вы это сделаете.
Например, я использовал его для мультиплексирования 3-значного 7-сегментного дисплея, поэтому перед инициализацией таймера я инициализировал регистры ввода-вывода дисплея и отключил данные дисплея в том месте, где его будет искать ISR.
В комментариях есть таблица некоторых полезных временных данных из таблицы данных и мои собственные расчеты для справки, чтобы установить другую временную схему.
Макрос ISR () заботится о создании кода входа и выхода прерывания для ISR вместо нормального входа и выхода функции и связывания его с соответствующим вектором прерывания. Остальная часть этой функции: 1) код, который будет запускаться при каждом прерывании, и 2) кодовый код для сброса таймера для следующего прерывания.
Как написано, это должно быть в виде эскиза .pde или .ino (или файла .cpp, если вы используете eclipse, f / ex). Эскиз должен #define LEDPIN, а setup () должен вызвать Timer2init (). Функция цикла может быть пустой или нет; светодиод должен начать мигать при загрузке (ну, буквально, после вызова Timer2init ()).
/*
* From sample interrupt code published by Noah Stahl on his blog, at:
* http://arduinomega.blogspot.com/p/arduino-code.html
*
*/
/*** FUNC
Name: Timer2init
Function: Init timer 2 to interrupt periodically. Call this from
the Arduino setup() function.
Description: The pre-scaler and the timer count divide the timer-counter
clock frequency to give a timer overflow interrupt rate:
Interrupt rate = 16MHz / (prescaler * (255 - TCNT2))
TCCR2B[b2:0] Prescaler Freq [KHz], Period [usec] after prescale
0x0 (TC stopped) 0 0
0x1 1 16000. 0.0625
0x2 8 2000. 0.500
0x3 32 500. 2.000
0x4 64 250. 4.000
0x5 128 125. 8.000
0x6 256 62.5 16.000
0x7 1024 15.625 64.000
Parameters: void
Returns: void
FUNC ***/
void Timer2init() {
// Setup Timer2 overflow to fire every 8ms (125Hz)
// period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
// (1/16000000) * 1024 * (255-130) = .008 sec
TCCR2B = 0x00; // Disable Timer2 while we set it up
TCNT2 = 130; // Reset Timer Count (255-130) = execute ev 125-th T/C clock
TIFR2 = 0x00; // Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01; // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
TCCR2A = 0x00; // Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = 0x07; // Timer2 Control Reg B: Timer Prescaler set to 1024
}
/*** FUNC
Name: Timer2 ISR
Function: Handles the Timer2-overflow interrupt
Description: Maintains the 7-segment display
Parameters: void
Returns: void
FUNC ***/
ISR(TIMER2_OVF_vect) {
static unsigned int led_state = 0; // LED state
led_state = !led_state; // toggles the LED state
digitalWrite(TOGGLE_PIN, led_state);
TCNT2 = 130; // reset timer ct to 130 out of 255
TIFR2 = 0x00; // timer2 int flag reg: clear timer overflow flag
};