Расчет частоты таймера для UNO/Atmega328

Я, должно быть, переутомился или что-то в этом роде... Я просто не могу правильно рассчитать частоту таймера. У меня есть кристалл на 16 МГц на Atmega328. Мне нужна частота прерывания таймера 1 кГц. Поэтому я выбрал предделитель = 64 и счетчик = 249, то есть

fTimer = fCPU/prescaler/(top+1) = 16 МГц/64/250 = 1 кГц

Но мой осциллограф показывает 2 кГц... !? Почему?

Я прочитал Timer2 Compare Interrupt не работает как ожидалось, но принятый ответ не делает ситуацию лучше. Там частота вдвое выше, тогда как у меня она вдвое выше ожидаемой.

Код:

const int signalLED = 1; //14;

void setup() 
{
  pinMode(signalLED, OUTPUT);
  digitalWrite(signalLED, LOW);

  TCCR2A = 0; // устанавливаем регистр TCCR2A в 0
  TCCR2B = 0; // устанавливаем регистр TCCR2B в 0
  TCNT2  = 0; // сбросить счетчик
  OCR2A = 249; // верхнее значение в режиме CTC
  TCCR2A |= (1 << WGM21); // включить режим CTC таймера 2
  TCCR2B |= (1 << CS21) | (1 << CS20); // 1:64 предварительное масштабирование для таймера 2
  TIMSK2 |= (1 << OCIE2A); // включить прерывание сравнения таймера 2
  sei(); // разрешить прерывания
}

ISR(TIMER2_COMPA_vect) 
{
  // сгенерировать пик
  digitalWrite(signalLED, HIGH);
  digitalWrite(signalLED, LOW);
}

void loop() 
{
}

, 👍1


1 ответ


Лучший ответ:

1

Ваш комментарий:

TCCR2B |= (1 << CS21) | (1 << CS20); // 1:64 предварительное масштабирование для таймера 2

не соответствует фактической настройке (= 1/32)

Также есть некоторые проблемы с настройкой режима Timer2 CTC, лучше установить режим, затем OCR2A + TCNT2 + прерывания, а затем Prescaler для запуска таймера. Он ведет себя так, как будто OCR2A=0, поэтому частота намного выше ожидаемой.

,