Well, I'm back with a slightly more simple (I hope) problem this time.
I needed a timer on which to base certain events in my software. I found Melanie's Olympic Timer and used it as the basis for my timer.
In order to capture a PWM signal with a period of 2ms, my goal was to increment the timer once every 50us to get the resolution I wanted. As it turns out, I can't make this happen.
In the code example below, I set the interrupt timer to give me a 5.5ms interrupt cycle. (In this case, 65535-5500 = 60035 or $EA83 is the "start" time for the interrupt). Each cycle of the interrupt I toggle an output port, which gives me a square wave with each square width equaling the interrupt cycle length. This I can see and measure on my o-scope.
Now the interesting part. I can't seem to get non-whole interrupt intervals. In the example below (which should yield a 5.5ms cycle) I get a perfect signal that's 6ms long. A 1100us entry in the program yields a 2ms cycle. An 1800us entry also yields a 2ms cycle.
Bottom line, I can't hit my 50us cycle because the smallest I can get is 1ms.
Can anyone explain this? I'm sure it's something simple, but it's driving me crazy.
Also, if this is some sort of limitation, is it at all possible to achieve my goal of a 50us interrupt cycle?
Thanks!
-Jeff
Code:
@ DEVICE INTRC_OSC, LVP_OFF, WDT_OFF, MCLR_OFF
define OSC 4
LED7 var PORTB.6
'------------------------------
' Main program starts here
'------------------------------
Gosub ResetTimer
On Interrupt goto HandleInterrupt
PIE1.0=1 ' Enable TMR1 interrupts
INTCON.6=1 ' Enable all unmasked Interrupts
INTCON.7=1 ' Enable Global Interrupts
MAIN:
enable
pause 1
goto MAIN 'endless loop
disable
ResetTimer:
T1CON.0=0 ' Stop the clock
TMR1H=$EA
TMR1L=$83
T1CON.0=1 ' Restart the clock
PIR1.0=0 ' Reset TMR1's interrupt flag (TMR1IF)
Return
HandleInterrupt:
toggle led7
Gosub ResetTimer ' Set the timer for the next 50us interval
Resume
END
Bookmarks