[fpc-devel] AVR embedded Atmega 328p interrupts
jeppe at j-software.dk
Mon Nov 30 00:54:42 CET 2015
On 11/29/2015 11:35 PM, Andrew Haines wrote:
> On 11/29/2015 02:13 PM, Jeppe Johansen wrote:
>> Not sure the timer initialization is right, but it looks ok.
>> One thing you need is the interrupt procedure directive:
>> procedure TIMER0_overflow; interrupt; public name 'TIMER0_COMPA_ISR';
>> Otherwise it'll probably reset at some point.
> Ok I got it to work. I have an interrupt:
> procedure TIMER0_COMPA; noreturn; public name 'TIMER0_COMPA_ISR';
> and the timer is setup with:
> procedure TimerInit;
> TCCR0A := TCCR0A or (1 shl WGM01);
> OCR0A := $F9;
> TIMSK0 := TIMSK0 or (1 shl OCIE0A);
> TCCR0B := TCCR0B or 5;//scale 5 = Clock / 1024
> The keywords "interrupt" or "noreturn" seem to have the same effect
> but are mutually exclusive.
> Without the interrupt or noreturn keyword, TIMER0_COMPA is only called
> once and presumably a crash or infinite loop starts somewhere. (
> return is causing an error?)
> With the interrupt or noreturn keyword and those timer settings, the
> led blinks at the edge of human detection. Success!
> Setting interrupts for TIMER0_COMPB and TIMER0_OVC have no effect;
> they are never called. I'm probably not understanding some of how to
> configure timers.
Don't use noreturn. It signals to the compiler that your function will
not return (i.e. do an infinite loop).
Use the interrupt directive for interrupt handlers. That makes them emit
the iret instruction instead of ret to return from the interrupt. If you
don't use that when you return from the ISR it will not have interrupts
enabled. That's why it only blinks once.
Only enable interrupts that you have written handlers for otherwise they
end up in the default handler which is an infinite loop as you saw.
TIMER0_COMPB and TIMER0_OVF are not called because you don't set OCIE0B
or OCIE0A in TIMSK0.
More information about the fpc-devel