# AVR Frequency measurement accuracy

I need to measure the switching frequency of an open collector output. The waveform will be square shaped and the frequency range is specified as 0 to 5kHz. First of all I don't want to count pulses because I want to determine the duty cycle as well. So here comes my problem:

For this task I explicitly need to use an ATMega16 without any external circuitry (except crystal)

I know there is a pretty simple way of determine frequency and duty cycle, and I already did use this technique: hook the signal to an interrupt, combine it with an asynchronous timer, do a little bit of math and done!

Now this works pretty well with the 16 Bit timer module but not so great with one of the 8 Bit timers since those overflow much faster.

Now I'm curious if I can determine the accuracy of this technique beforehand, e.g without testing it out.

I know the frequency reading will mostly depend on the timers frequency: the higher, the better. An 8 Bit timer running at @ 2MHz (prescaler 2 ; from 16MHz) should give me a basic 0.5us per LSB resolution which looks pretty good on paper. Combined with a 16 Bit overflow register I theoretically could measure up to one second time period. But I know this won't work: updating the 16 Bit overflow register would take too much instructions in the ISR and effectively wreck my accuracy. So is there any way of getting reasonable accuracy (+-5%) from a single 8 Bit timer module in the specified frequency range (0...5kHz)?

• Check the datasheet for Input Capture Pin. Together with smart interrupt usage you can extend the timer without the need for using the prescaler. Not entirely sure of mega16 has ICP, which brings me back to my first suggestion of checking the datasheet. – jippie Mar 31 '16 at 20:28
• I have heard of Input Capture Pins before, but totally forgot it! Thanks, this looks like a feasible solution, I'll have a look at it. – d3L Mar 31 '16 at 20:46

Updating a register or register set inside an interrupt before any other processing will be extremely deterministic. I don't know why that can't be accurate.

In fact, I dare say that accuracy can be significantly higher than the +/-10% RC oscillator accuracy in an old Atmel type as the ATMega16. Unless you mean "I do have a well tuned crystal with the proper loading capacitors" when you say NO external circuitry.

You can claim registers in Atmel Studio (AVR-GCC) by using the keywords, if I'm not mistaken;

volatile register MyRegister asm("R22"); // to claim R22 with name MyRegister

But claiming registers like that is risky business, and even the RAM overhead of just making a volatile global if that gets put into RAM is a static overhead, which becomes, again, fully deterministic at start of ISR.

• Yeah, the start of the ISR is deterministic, but the arrival of the signal edge isn't. I only have a clue on how to calculate accuracy for the worst case: assume the timer overflowed as much as it can in the given measurement span. – d3L Mar 31 '16 at 20:52
• Thanks for the tip with registers, I didn't realize I could use builtin registers for that! – d3L Mar 31 '16 at 20:52
• And yes.. I'm actually allowed to use an external crystal... oops – d3L Mar 31 '16 at 20:53
• @d3l if your timer is fed with the maximum clock, that still leaves you 25 clock cycles to handle stuff before you even reach 1% overflow inaccuracy with 256 count (8bit) timers. Again, the internal RC is much, much worse. – Asmyldof Mar 31 '16 at 20:54
• Even with a 'non-register' overflow counter variable in the ISR? – d3L Mar 31 '16 at 20:59