Electronic – counter giving erratic results for frequency measurement using Atmega32

atmegacfrequency-measurementmicrocontroller

I am using a photosensor which gives output as a square wave. The frequency of this square wave is being measured using Atmega32A with 1MHz clock. The full scale output of sensor is 500kHz.

The output of the photosensor is connected to pin T1 and I'm using timer1 clock as a reference to determine the frequency. I have a 100 ms delay using software loop after which I read the timer value and multiply by 10 to get the photosensor output frequency.

The frequency values being obtained using oscilloscope are around 50-100kHz. However the frequency values being returned by this code are around 80Hz greater than value measured with an ocilloscope in one setting .If I change the location of the whole setup this constant extra value is changing to another constant . What am I doing wrong?

uint32_t MeasureFrequency()
{
uint32_t freq=0;
DDRB &= ~(1<<PINB1);uint32_t count=0;

TCCR1B |=(1<<CS12);
TCCR1B |=(1<<CS11);
TCCR1B &=~(1<<CS10);            //0.Initalize



TCNT1=0x0000;               //1.Clear timer 0 contents

TIFR &=~(1<<TOV1);          //2.Clear timer 0 flag

//count=TCNT1;
while(TCNT1<1)
{;}//count=TCNT1;}  


if(TCNT1>=1)                //3.Check if timer has incremented once
{_delay_ms(100);}           //4.100ms delay



TCCR1B &=~(1<<CS12);
TCCR1B &=~(1<<CS11);
TCCR1B &=~(1<<CS10);        //5.Disconnect timer clock from input

uint8_t i=TIFR;
i = i&(0b00000100);


if(i==4)
{Send_A_Character('v');}

count=TCNT1;            //6.Read Timer

return freq=count*10;   //7.Freq=timer*10

     }

Best Answer

_delay_ms() is a very unprecise function, besides it takes precessor time to call it and return back.

There are many ways you could use atmega's peripherals to measure frequency, if you want to go by feeding input frequency to T1, I would suggest using another timer to measure time. You could set up and start both timers simultaneously, then catch overflow interrupt of "time" timer which will happen exactly after 256*prescaler system clock ticks, then do your math.

On another note, I would suggest you to increase your processor clock frequency as 500KHz is only 2 times less than 1MHz (Nyquist theorem), that is enough, but you will not get much accuracy at the high end.