Сообщение от vovaf
|
Использовав прерывание по переполнению и записью в счетчик начального значения Вы никогда не получите точного хода часов, смотрите даташит по вопросу вхождения в прерывания
|
Счетчик в таймере и вхождение в прерывание - разные вещи и работают они
ассинхронно. Поэтому время входа, если оно достаточно маленькое - не играет роли. Конечно если не делать глупостей по установке регистров таймера в самом обработчике прерывания. begun сделал это неправильно.
begun, не могу на лету разобрать ваш код инициализации таймера "магическими" числами.
Вот смотрите, как должно быть (пример для 4 МГц, WinAVR):
#include ‹avr/io.h›
#include ‹stdint.h›
int main()
{
// 4000000 Гц / 64 / 50 = 1250 Гц
TCCR0 =
_BV(CS01) | _BV(CS00) | // / 64
_BV(WGM01);
const uint8_t k = 50;
OCR0 = k - 1;
// Enable timer 0 output compare interrupt.
TIMSK |= _BV(OCIE0);
sei();
for ( ; ; ) ;
return 0;
}
void Tick1Hz()
{
// Вызывается ровно 1 раз в секунду.
// Считаем время
...
}
static short _Counter;
ISR(TIMER0_COMP_vect)
{
// Вызывается ровно 1250 раз в секунду.
++_Counter;
if (_Counter == 1250)
{
// Попадаем сюда каждый 1250 раз, т.е. 1 раз в секунду.
_Counter = 0;
Tick1Hz();
}
}
Таймер 0 генерирует прерывание
сравнения (TIMER0_COMP_vect) с частотой ровно 1250 Гц. Обратите внимание, что значение второго делителя (50) записывается в OCR0 на единицу меньше. Никаких обращений к регистрам таймера в обработчике прерывания нет, соответственно время вхождения в прерывание не играет никакой роли. Код проверенный, работает как часы.