cembeddedavratmegaavr-gcc

How to verify the TIMER2 overflow frequency in atmega328p?


I have configured the timer2 of atmega328p in normal mode and overflow at 10000Hz. My code is given below. I was trying to verify the frequency. So I just toggle a pin PB5 on every overflow interrupt.Hence it will give the overflow frequency.

#define F_CPU 16000000
#define TIMER2_PRESCALAR 8                //RV8A12, Added 08-Nov-22
#define TIMER2_CLOCK (F_CPU / TIMER2_PRESCALAR)

uint8_t Timer2_count=0;     
unsigned int sample_freq;

ISR(TIMER2_OVF_vect)
{
 TCNT2=Timer2_count;
 PORTB ^= (1<<PORTB5);
}


void timer2_init()
{

 TCCR2A = 0x00;    // normal mode
 TCNT2=Timer2_count;
 TIMSK2=0x01;
 TCCR2B = 0x02;                //set prescaler 8 or devide by 8

}

void timer2_stop()
{
  TCCR2B=0x00;
}


void setup() {
  // put your setup code here, to run once:

sei();
Serial.begin(115200);
Serial.print("\nSTARTING...");
delay(5000);
DDRB |= (1<<PORTB5);

sample_freq=10000;
Timer2_count = 256 - (TIMER2_CLOCK / sample_freq);  

timer2_init();

}

void loop() {
  // put your main code here, to run repeatedly:
}

Then I connected a oscilloscope on PB5 pin and I observed wrong result. The frequency shows around 159Hz.

Edit : I have made the pin PB5 as output then checked the DSO. it was showing 4.9407Khz that is sampling frequency is 9.881Khz instead of expected freq 10Khz. Made control registers modification in one command.


Solution

  • The Issue was solved by reducing the Timer frequency. I have changed the prescalar of 8 to 64. The Issue was with the TCNT update command in the ISR. It was not updating before timer count to next tick. When Timer frequency is reduced, it get sufficient time to update the TCNT before it count to next tick.