Problem with timer interrupt accuracy

Hi!

Using a RCM3200 44MHz board, i am trying to create an interrupt that is triggered EXACTLY every 20uS for example.

I have been trying to use TimerB for this, but the stability isn’t even close to ok.
If i am letting the counter run free without any recalculations, the period time is appr. 45uS on this module.

It runs ok for a few seconds, then jumps over one period or more, or shows a pulse of 20uS followed by a pulse one of 200uS. Then it gets back on track. This happens every 3-10 secs or so.
The only thing the interrupt routine does (for now) is to toggle a pin on portB. I do this in asm. What am I doing wrong :confused:?

#asm
WS_shortb_isr::
push af
push hl
ld a,(tim_toggler)
inc a
and a,0x01;
ld (tim_toggler), a
ioi ld (PBDR),a

ioi ld a, (TBCSR)

ld a, 00h
ioi ld (TBM1R), a
ioi ld (TBL1R), a
pop hl
pop af

ipres
ret

#endasm

Hi there,

looking at the sample supplied for the 3000-series, I reckon you do the following:

#asm
WS_shortb_isr::
push af
push hl

ioi ld a, (TBCSR) ;must be done asap!

ld a,(tim_toggler)
inc a
and a,01h
ld (tim_toggler), a
ioi ld (PBDR),a

ld a, 00h
ioi ld (TBM1R), a
ioi ld (TBL1R), a
pop hl
pop af

ipres
ret
#endasm

Checco

Nice to see the Rabbit pros in here!

Checco

To get a precise interval try adding to the current match register value. For your 20uS pulse, you would need to set the add 440 or 0x1B8 on each interrupt. So your ISR becomes:

#asm
WS_shortb_isr::
push af
push hl
ioi ld a, (TBCSR)

ld a,(PBDRShadow)
xor a,1
ld (PBDRShadow), a
ioi ld (PBDR),a

ioi ld a,(TBM1R)
add a,40h
ioi ld (TBM1R),a
ioi ld a,(TBL1R)
add a,0b8h
ioi ld (TBL1R),a
ipres
ret
#endasm

This code also uses the port B shadow register to do the toggling, which allows you to use other pins on the port without having the bit you’re toggling getting corrupted. You also want to set the interrupt priority fairly high if you want this to run very precisely, just make sure you’re not doing too much inside the ISR as this is occuring 50,000 times per second. Also, make sure you have only enabled one of the match registers in TBCSR (set it to 3 initially).