Шестнадцатиразрядные таймеры T1, T3
Шестнадцатиразрядный таймер-счётчик T1 входит в состав всех моделей микроконтроллеров серии Mega. Таймер T3 присутствует только в моделях ATmega 162x и ATmega 64x/128x. Счётные регистры таймеров - TCNTn = TCNTnH*256 + TCNTnL, где: TCNTnH - старший байт, TCNTnL - младший, n=1,3 - номер счётчика).
Тактирование таймеров
По умолчанию таймеры тактируются от основного генератора через предделитель, снижающий частоту изменения значений счётного регистра в 8, 64, 256 или 1024 раза, в зависимости от комбинации битов CSn0, CSn1 и CSn2 в регистре TCCRnB.
null
Примеры для различных коэффициентов деления предделителя:
TCCRnB |=(1<<CSn0); // Тактировать напрямую от основного генератора.
TCCRnB |=(1<<CSn1); // Тактировать с коэффициентом деления 8.
TCCRnB |=(1<<CSn0)|(1<<CSn1); // Тактировать с коэффициентом 64.
TCCRnB |=(1<<CSn2); // Тактировать с коэффициентом 256.
TCCRnB |=(1<<CSn0)|(1<<CSn2); // Тактировать с коэффициентом 1024.
TCCRnB &=˜(1<<CSn0|1<<CSn1|1<<CSn2); // Остановить счётчик.
Прерывание по переполнению
Классический вариант прерывания - по переполнению счётного регистра вызывается при переходе значения счётного регистра из максимального (0xFFFF) в нулевое. При этом устанавливается флаг TOV1 регистра TIFR или TOV3 регистра ETIFR, которые сбрасываются аппаратно при входе в обработчик прерывания:
Переполнение таймера 1
Разрешается прерывание установкой бита 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. Не следует забывать, что инициализационные значения, например для регистра сравнения, должны быть на единицу меньше числа тактов в заданном интервале времени - плюс один такт для перехода от максимального значения к нулевому.