Atmega. Расчет таймера на 1 сек

Рассмотрим пример настройки прерывания таймера 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 будет выглядеть следующим образом:

// Инициализация прерывания
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;

   // Что-то делаем каждую секунду
   // ...
}