Timer and Counter Interrupts
From Nutwiki
Revision as of 12:50, 11 September 2009 by AdrianPyka (Talk) (→AVR - How to Configure a Timer Compare Interrupt)
AVR - How to Configure a Timer Compare Interrupt
Macros to define a time period, feel free to change 1ms to e.g. 4 etc.
#define SAMPLE_PERIOD 1 //[ms] #define TIMER1_DIVISOR 14745600/(1000/SAMPLE_PERIOD) //NUT_CPU_FREQ/...
This routine is periodically called. Note: In case IRQSTACK_SIZE is not defined, you run within an unpredictable context.
void Timer1Process(void *arg)
{
arg = arg; //requires gcc compiler (when called from thread)
//NutRegisterIrqHandler callback fn has void* argument
//your fn goes here
}
Following initialization (called only once) generates Timer1Process() interrupt calls every 1ms (0.999959 ms).
16 bit timer is used for accuracy. If timer2 (8bit) is used, you can reach 1,11111 ms (prescaler 128, OCR=128)
void Timer1Init(void)
{
#ifdef MCU_ATMEGA_2561
NutIrqDisable(&sig_OUTPUT_COMPARE1A);
#endif
//COM1A, B, C = 0 (Compare Output Mode) = normal (output pin disconnected)
//WGM = 4 (CTC - Clear Timer on Compare match)
//CS = 1 (prescaler = 1)
#ifdef MCU_ATMEGA_2561
outb(TCCR1A, 0);
#endif
outb(TCCR1B, BV(WGM12) | BV(CS10)); //0x09
#ifdef MCU_ATMEGA_2561
cbi(TCCR1C, FOC1A);
#endif
//assume timer is disabled after power up
//outb(TCNT1H, 0);
//outb(TCNT1L, 0);
//divisor
outb(OCR1AH, TIMER1_DIVISOR >> 8); //0x39
outb(OCR1AL, TIMER1_DIVISOR & 0xFF); //0x99
NutRegisterIrqHandler(&sig_OUTPUT_COMPARE1A, Timer1Process, 0);
#ifdef MCU_ATMEGA_2561
NutIrqEnable(&sig_OUTPUT_COMPARE1A);
#elif defined MCU_ATMEGA_128
sbi(TIMSK, OCIE1A);
#endif
}
See also
- More Nut/OS Examples