Классический вариант прерывания - по переполнению счётного регистра вызывается при переходе значения счётного регистра из максимального (0xFFFF) в нулевое. При этом устанавливается флаг TOV1 регистра TIFR или TOV3 регистра ETIFR, которые сбрасываются аппаратно при входе в обработчик прерывания:
Разрешается прерывание установкой бита TOIEn, для таймеров T1 - TOIE1 в регистре TIMSK, для T3 - TOIE3 в ETIMSK.
Пример для ATmega 16, основной генератор 8 МГц, прерывания по переполнению T1 каждые 10мс:
TCCR1B|=(1<<CS11); // Коэффициент деления предделителя - 8.
SREG|=(1<<7); // Глобальное разрешение прерываний.
TIMSK|=(1<<TOIE1); // Разрешить прерывание по переполнению Т1.
// Число тактов таймера до переполнения = 0x2710
TCNT1H=0xFF-0x27; TCNT1L=0xFF-0x10;
// Обработчик прерывания по переполнению Т1.
#pragma vector=TIMER1_OVF_vect
__interrupt void T1_OVER()
{
TCNT1H=0xFF-0x27; TCNT1L=0xFF-0x10+3; // Периодическая инициализация счётчика.
}
Прерывание по совпадению с регистром сравнения
В состав таймеров T1/T3 входят шестнадцатиразрядные регистры сравнения OCRnA/OCRnB/OCRnC содержимое которых в каждом машинном цикле сравнивается с текущим значением счётного регистра TCNTn. В случае их совпадения устанавливаются флаги OCFnA/OCFnB/OCFnC и если соответствующее прерывание разрешено установкой битов OCIE1A/OCIE1B регистра TIMSK или OCIE3A/OCIE3B/OCIE3С в ETIMSK происходит вызов обработчика прерывания от регистра сравнения. Флаги совпадения, как и флаги переполнения, при входе в обработчик сбрасываются аппаратно.
Пример. Ежесекундные прерывания от таймера T3. ATmega 128, 14.7456 МГц.
// При частоте генератора 14.7456 МГц и делителе 1024, 1000ms - 14400 тактов.
OCR3AH=56; OCR3AL=63;
TCCR3B|=(1<<CS30)|(1<<CS32); // Делить частоту на 1024.
SREG|=(1<<7); // Разрешить прерывания.
ETIMSK|=(1<<OCIE3A); // Разрешить прерывание по совпадению.
// Обработчик прерывания по совпадению с OCR3A.
#pragma vector=TIMER3_COMPA_vect
__interrupt void T3_COMPARE_A()
{ OCR3AH=0; OCR3AL=0;} Режим CTC (сброс при совпадении)
Шестнадцатиразрядные таймеры T1/T3 имеют возможность самостоятельно сбрасывать счётный регистр сразу после его совпадения с регистром сравнения, после чего счёт автоматически продолжается с нулевого значения. Такой режим называется режимом сброса при совпадении (CTC) и может быть использован в частности для генерации сигналов фиксированной частоты. Для перевода таймера в данный режим необходимо установить биты WGMn2 и WGMn3 регистра TCCRnB. В моделях ATmega161x/63x/323x этот режим отсутствует.
Изменение состояния вывода OCnA при совпадении с регистром сравнения
Во всех микроконтроллерах ATmega имеется вывод с альтернативной функцией OC1A или OC3A. Настроенный на выход, он может изменять своё состояние в момент совпадения значений счётного регистра и регистра сравнения. Характер этих изменений пределяется комбинацией битов COMnA0 и COMnA1 в регистре TCCRnA, например:
COMnA1=0, COMnA0=0 - таймер отключен от вывода OCnA;
COMnA1=0, COMnA0=1 - состояние вывода меняется на противоположное;
COMnA1=1, COMnA0=0 - OCnA сбрасывается в ноль;
COMnA1=1, COMnA0=1 - OCnA устанавливается в единицу.
Разрешается управление выводом установкой бита FOC1A/FOC3A в TCCRnC, однако при этом блокируется вызов прерывания по совпадению.
Пример: генерировать меандр 100 кГц на выводе OC1A ATmega64 с кварцем 12 МГц.
OCR1AH=0; OCR1AL=(120-1); // При частоте 12 МГц без предделителя 10 мкс - 120 тактов таймера.
DDRB|=(1<<5);// Установить вывод OC1A (PortB.5) на выход
TCCR1C|=(1<<FOC1A); // Разрешить изменение вывода OC1A.
TCCR1A|=(1<<COM1A0);// Менять состояние вывода на противоположное.
TCCR1B|=(1<<WGM12)|(1<<WGM13)|(1<<CS10); // Режим CTC. Тактировать без деления.
Асинхронный режим тактирования
Для реализации функции реального времени часто используется асинхронный режим тактирования таймеров, при котором в качестве источника тактовых импульсов используется отдельный встроенный генератор и внешний часовой кварцевый резонатор. Такой возможностью в моделях ATmega обладают только воcьмиразрядные таймеры-счётчики. Подробнее смотрите раздел Atmega. Восьмиразрядные таймеры T0/T2.
Примечания:
1. Для обеспечения одновременной записи обоих байтов в шетснадцатиразрядные регистры AVR, старший байт предварительно помещается во временный регистр TEMP. Затем при записи младшего байта происходит их одновременное перемещение в шетснадцатиразрядный регистр. Для того чтобы исключить запись в старший байт случайного значения, хранящегося в буфере TEMP, запись младшего байта необходимо производить после записи старшего.
2. Не следует забывать, что инициализационные значения, например для регистра сравнения, должны быть на единицу меньше числа тактов в заданном интервале времени - плюс один такт для перехода от максимального значения к нулевому.