Рассмотрим пример настройки прерывания таймера T1 с периодом 1 раз в 1 сек (1 Гц). на микроконтроллере Atmega8. Такая настройка может очень пригодиться при разработке девайсов отсчитывающих реальное время, например часов. Итак:
1. Выбраем и устанавливаем делитель в регистре TCCR1B (биты CS12,CS11,CS10). Делитель частоты следует выбирать таким образом, что бы частота кварца, на которой работает контроллер в Гц деленная на делитель было целым числом. Например для кварца 8мГц (8000000Гц) нужно выбрать делитель TCCR1B равный 256 (установиь биты CS12=1,CS11=0,CS10=0).
2. Делим основную частоту на делитель. Полученное значение нужно будет для корректировки регистра TCNT1 (см. п. 3): 8000000/256=31250.
3. Корректируем регистр TCNT1 для получения прерывания ровно 1 сек. T1 - 16 разрядный таймер - это 65535 тиков. Тогда регистр TCNT1 будет равен 65535-31250=34285
4. Незабываем корретировать TCNT1 в самом прерывании.
Код для WinAvr будет выглядеть следующим образом:
1. Выбраем и устанавливаем делитель в регистре TCCR1B (биты CS12,CS11,CS10). Делитель частоты следует выбирать таким образом, что бы частота кварца, на которой работает контроллер в Гц деленная на делитель было целым числом. Например для кварца 8мГц (8000000Гц) нужно выбрать делитель TCCR1B равный 256 (установиь биты CS12=1,CS11=0,CS10=0).
2. Делим основную частоту на делитель. Полученное значение нужно будет для корректировки регистра TCNT1 (см. п. 3): 8000000/256=31250.
3. Корректируем регистр TCNT1 для получения прерывания ровно 1 сек. T1 - 16 разрядный таймер - это 65535 тиков. Тогда регистр TCNT1 будет равен 65535-31250=34285
4. Незабываем корретировать TCNT1 в самом прерывании.
Код для WinAvr будет выглядеть следующим образом:
// Инициализация прерывания void t1_init() { // Настраиваем делитель TCCR1B = (1<<CS12)|(0<<CS11)|(0<<CS10); // Выставляем значение TCNT1 // для коррекции счетчика, чтобы время было ровно 1 секунда TCNT1 = 65535-31250; // Разрешаем прерывание по переполнению таймера TIMSK |= (1<<TOIE1); // Выставляем бит общего разрешения прерываний sei(); } // Прерывание ISR(TIMER1_OVF_vect) { // Выставляем значение TCNT1 // для коррекции счетчика, чтобы время было ровно 1 секунда TCNT1 = 65535-31250; // Что-то делаем каждую секунду // ... }