В настоящее время я использую ATmega32, чтобы следить за временем, поэтому я внимательно прочитал техническое описание и настроил Таймер 1 для генерации прерывания каждую секунду.
Согласно следующей формуле в даташите, используя тактовую частоту 16 МГц, прескалер 256 и OCR1A = 31249, я должен получить частоту 1 Гц в режиме CTC:
Эта формула доступна на странице 99 таблицы данных ATmega32 .
Я настроил Таймер 1 следующим образом:
TCCR1A = 0;
TCCR1B = (1<<WGM12)|(1<<CS12);
OCR1A = 31249;
TIMSK = (1<<OCIE1A);
Вот код прерывания
ISR(TIMER1_COMPA_vect){
sec++;
}
Затем я использую ЖК-дисплей для непрерывной печати значения sec и получаю тайминг 0,5 секунды. Другими словами, за каждую прошедшую секунду таймер генерирует два прерывания.
Сначала я подумал, может быть, я ошибся с предохранителями, но, похоже, это не так, так как задержки работают нормально. Во всяком случае, вот как я настроил предохранители:
-U lfuse:w:0xff:m -U hfuse:w:0x99:m
Я совершенно не понимаю, что происходит, я все перепроверил, попробовал другой ATmega32, попробовал другой кварцевый генератор на 16 МГц, и все равно получаю тот же результат.
Даташит неправильный или я что-то пропустил?
Если системные часы 16 МГц , а прескалер 256 , ваш таймер будет работать на , так что будет приращение в каждом . Прерывание будет сгенерировано, когда значение счетчика станет равным 31249 . Если рассчитать это время: , что является точно таким же результатом, который у вас есть.
Уравнение в таблице данных предназначено для другой цели:
Для генерации выходного сигнала в режим, вывод можно настроить на переключение своего логического уровня при каждом совпадении сравнения, установив биты режима вывода сравнения в режим переключения. . значение не будет отображаться на выводе порта, если направление данных для вывода не установлено на вывод . Сгенерированный сигнал будет иметь максимальную частоту когда устанавливается равным нулю . Частота сигнала определяется следующим уравнением: (...)
Если бы вы измерили частоту конкретного вывода, я думаю, что это будет 1 Гц.
Чтобы достичь 1 с , генерации прерывания вам нужно 62500 тиков и так как счетчик начинается с 0, установите OCR1A на , а поскольку Timer1 является 16-битным таймером, это значение не слишком велико (< 65535, ).
Эта формула предназначена для выходной частоты вывода OCnA («Для генерации выходного сигнала в режиме CTC выход OC1A можно настроить на переключение своего логического уровня при каждом совпадении сравнения, установив биты режима вывода сравнения в режим переключения (COM1A1: 0 = 1). [...] Частота сигнала определяется следующим уравнением:"). Поскольку вместо этого вы используете прерывание, вы получите два сравнения за период. Отбросьте 2 из знаменателя, чтобы вычислить частоту прерывания.
DrFriedParts