Wednesday, 28 August 2019

timing - Arduino: better microsecond resolution than micros()?


The micros() documentation notes that the return value will always be a multiple of 4.



Is there any way to get a higher resolution microsecond click, preferably down to the 1 microsecond level?


Dropping down to the AVR level is acceptable.



Answer



Yes, depending your Arduino's basic clock rate. For example here are the counter-timer input frequencies and periods after pre-scaling, for an ATMega2560's counter-timer 2, and a basic clock rate of 16MHz. The timer has built in "prescaler" value options which determine frequency/period, shown in this table:


    TCCR2B bits 2-0    Prescaler    Freq [KHz], Period [usec] after prescale
0x0 (TC stopped) -- --
0x1 1 16000. 0.0625
0x2 8 2000. 0.500
0x3 32 500. 2.000
0x4 64 250. 4.000

0x5 128 125. 8.000
0x6 256 62.5 16.000
0x7 1024 15.625 64.000

For better timing resolution, you use a value called TCNT2. There is build in counter that goes from 0 to 255 because the timer is 8 bit. When the counter reaches the value assigned by TCNT2 it triggers an interrupt. This interrupt is called TIMER2_OVF_vect.


given this information, the resulting interrupt rate would be: 16MHz / (prescaler * (255 - TCNT2))


You could get the timer to run at the full 16MHz (62.5nSec) though that's way faster than you need; 2MHz with an initial count of (255-2) would give you 1MHz interrupt rate. Divide that by 2 in your ISR:


extern uint32_t MicroSecClock = 0;

ISR(TIMER2_OVF_vect) {// this is a built in function that gets called when the timer gets to the overflow counter number

static uint_8 count; // interrupt counter

if( (++count & 0x01) == 0 ) // bump the interrupt counter
++MicroSecClock; // & count uSec every other time.

digitalWrite(53,toggle);// pin 53 is arbitrary
TCNT2 = 253; // this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
TIFR2 = 0x00; // clear timer overflow flag
};


The data sheet for your MCU is the basic resource; this article will give you (and gave me!) a good head-start.


No comments:

Post a Comment

arduino - Can I use TI's cc2541 BLE as micro controller to perform operations/ processing instead of ATmega328P AU to save cost?

I am using arduino pro mini (which contains Atmega328p AU ) along with cc2541(HM-10) to process and transfer data over BLE to smartphone. I...