Hello everyone,
I am currently using the atmega328P to sense the frequency of an incoming signal, I am using the incomign signal as an external clock to T1, being able to calculate over a period of a time how many pulses I have had by reading TCNT1, it is currently working however, I am sensing signals in the order of 100 Khz to 200 Khz, at the moment I am using timer 0 as my gating source, so PD6 is clearing on compare match at 1 Hz.
The Issue is that even thoug I am probing the incoming signal and the input frequency does not change at all, the value of TCNT1 is slightly drifting by a few units, but it should not do it, since I am using that value to calculate the frequency, basically the frequency is slowly drifting making my measurement inconsistent.
For example overnight I left the oscillator running and taking samples, from an incomign signal of 223.200 Khz ( Measured, Osciloscope ), and it drifted to 223.400. and this si caused by TCNT1 drifts.
Am I reading these values properly ? any reason why this value (TCNT1) may be drifting ?
Thanks
Cheers
//timer setup Function .... Called before every measurement.
cli();
TCCR0B |= _BV(WGM02) | _BV(CS02) | _BV(CS01); // Reserved , External clk on T0 pin falling edge
TCCR1B |= _BV(WGM13) | _BV(WGM12) | _BV(CS12) | _BV(CS11); // Fast PWM mode, External clk on T1 pin falling edge
TCCR2B |= _BV(WGM22) | _BV(CS22) | _BV(CS21); // Preescaler to 256,
TCCR0A |= _BV(WGM01) | _BV(WGM00) | _BV(COM0A0); // Toggle OCOA on Compare Match, TOP = OCR0A
TCCR1A |= _BV(WGM11) | _BV(WGM10); // PWM, phase correct, 10-bit, no output, TOP = OCR1A
TCCR2A |= _BV(WGM21) | _BV(WGM20) | _BV(COM2B1) | _BV(COM2B0); // Set OCR2B on Compare Match, clear ORCB2 at BOTTOM
OCR0A = 249; // 249 = 1 Hz - timer 0 ; alternatevaly -> 123 =
OCR1A = 32768; // 32768 timer 1 counter ;
OCR2A = 249; // 249
OCR2B = 125; // 50 % duty cycle
sei();
// FUNCTION TO CAPTURE THE FREQUENCY
volatile uint32_t frequency = 0;
volatile uint8_t overF = 0;
while (!(PIND & (1 << PD6))) {}
//start the count
cli();
OCR1A = 32768;
TCNT1 = 0;
overF = 0;
TIFR1 |= _BV(OCF1A);
while (PIND & (1 << PD6)) {
if (TIFR1 & (1 << OCF1A)) { // When Flag Set.
TCNT1 = 0;
++overF;
TIFR1 |= _BV(OCF1A);
}
}
//count end
frequency = ((((uint16_t)TCNT1)) + overF * 32768);
return frequency;