Проблема в том, что временное поведение полностью неверно (фактор 30).
У меня есть ATmega 644PA, который работает с частотой 8 МГц (предохранитель CKDIV8 не установлен).
Я хотел прерывание каждые 1 мс. Я использую Timer1 (16-битный таймер) в режиме сравнения.
Прескалер был выбран в зависимости от диапазона времени, который мне нужен.
Здесь от 1 мс до ~ 2 с. (ограничено 16-битным регистром таймера)
Расчет
ЦП: 8.000.000 Гц
Предделитель: 256
8.000.000 Гц / 256 = 31250 циклов / с (Гц)
1000 мс = 31250 циклов
1 мс = 30,25 цикла (31,25 - 1, запуск регистрации таймера с 0)
Отсюда я могу рассчитать это, например:
100 мс = 3025 циклов
2 с = 60500 циклов
Код
Запуск таймера
cli(); // disable global interrupts
TCCR1A = (1 << WGM01); // CTC ON
TCCR1B = 0x04; // Prescaler 256
OCR1A = 30; // set compare reg.
TIMSK1 = (1 << OCIE1A); // set interrupt mask
TCNT1 = 0x00; // set counter reg. to zero
sei(); // enable global interrupts
ISR:
ISR(TIMER1_COMPA_vect)
{
// start own code
...
// end own code
TCNT1 = 0x00; // reset counter reg. to zero after match (same which should CTC do)
}
Теперь у меня есть, например, изменчивая переменная, которая будет увеличиваться в функции ISR.
Я опрашиваю переменную и жду так долго, пока она не достигнет 60500, что равно 2 с.
После этого я просто зажег светодиод.
Я измерил это по телефону, и до того, как загорится светодиод, требуется 1 минута.
Это занимает слишком много времени с множителем 30 => 60 секунд, разделенных на 2, равны 30.
Я также пытался использовать внешнюю программу для вычисления этого, она пришла к тем же результатам. (0x1E = 30)
Кто-то знает, в чем моя ошибка?