PDA

View Full Version : Darrel Taylor Interrupts and MultiCalc



AvionicsMaster1
- 7th February 2012, 01:09
Well, I'm trying to make a clock and I am trying to get exactly 100 pulses to use Darrell Taylors Instant Interrupt program. Which is pretty darn good by the way and I'm really a rookie.

Anyway, I have a 16F877A with a LED on Portb.1 that is supposed to blink at 100 hz. There is another LED on Portd.0. Other than those two LEDs, nothing else, other than power, is hooked up to the 16F877A. I'm looking at the LED on portb.1 pulses with an Oscope and I found that without preloading the timer it ran at about 950mHz. So, on a different post, I found the preload needed to get to 100 hz and with a little tweaking I get 100 hz. The issue I have is to get that 100 hz the preload numbers used I had to tell Multicalc I wanted to run the system at 200 hz in the Interrupt/Frequency window. What am I missing here?

Secondly, what is the Reload window for and how do you use it?

Please refer to the part where I said I was a rookie and be gentle. I've attached my code for even more scrutiny.

[CODE];This program will blink a light on portb.1 at a 1 hz rate --
'with another LED on portd.1 blinking at a different rate
'different TMR1 preloads to get desired frequencies
wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3
wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3
LED1 VAR PORTB.1
led2 VAR portd.0
INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
DEFINE osc20
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
T1CON =

Demon
- 7th February 2012, 01:14
Make sure to have your post window in SOURCE MODE so your CODE blocks don't get ruined.

Click the leftmost icon above your post window; SWITCH EDITOR TO SOURCE MODE. Then go to advanced mode (below post window at right) to get the CODE icon.

Robert

AvionicsMaster1
- 7th February 2012, 01:24
Well, it's refreshing to learn something new. Anyway, here's the code that didn't come through earlier.


;This program will blink a light on portb.1 at a 1 hz rate --
'with another LED on portd.1 blinking at a different rate
'different TMR1 preloads to get desired frequencies

wsave VAR BYTE $70 SYSTEM ' alternate save location for W
' if using $70, comment wsave1-3

wsave1 VAR BYTE $A0 SYSTEM ' location for W if in bank1
wsave2 VAR BYTE $120 SYSTEM ' location for W if in bank2
wsave3 VAR BYTE $1A0 SYSTEM ' location for W if in bank3

LED1 VAR PORTB.1
led2 VAR portd.0

INCLUDE "DT_INTS-14.bas" ' Base Interrupt System
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts
DEFINE osc20
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ToggleLED1, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

T1CON = %00000001 ; Prescaler = 1:1, TMR1ON
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts

preload VAR WORD

preload = 61476 '60543 by MultiCalc should yields about 200Hz but
'60643 yeilds exactly 100 Hz
' 48876 29.8cps
' 57209 yields 59.5cps
' 61376 yields

tmr1l = preload.LowByte
tmr1h = preload.HighByte

Main:
PAUSE 500
TOGGLE led2
PAUSE 500
TOGGLE led2

GOTO Main

'---[TMR1 - interrupt handler]------------------------------------
ToggleLED1:
t1con.0 = 0
tmr1l = preload.LowByte
tmr1h = preload.HighByte
t1con.0 = 1
TOGGLE LED1
@ INT_RETURN

Demon
- 7th February 2012, 01:30
I'm pretty sure PAUSE messes up the timer routines.

I think you're supposed to use FOR loops instead.

Robert


EDIT: Something like:


for loop = 1 to 500
pause 1
next loop

Darrel Taylor
- 7th February 2012, 02:18
He's not using ON INTERRUPT Robert.

Greg,

It takes 2 interrupts to turn an LED On and Off. So 200hz interrupts produces a 100 hz flashing led.
If you want to keep time from 100hz interrupts, that would be too fast.

Since you want accuracy, you shouldn't just load the timer with a value.
It takes time to get to the interrupt handler, and the timer has been counting during that time.
If you just load a value into the timer, that amount of time is lost.

If you ADD the reload value to the current timer value, it no longer matters how long it took to get to the handler.
It also takes a certain amount of time to ADD the value to the time, and that time must be accounted for as well.

Take a stab at the "Timer Template" http://www.darreltaylor.com/DT_INTS-14/TimerTemplate.html
It does all that stuff for you.

Use a prescaler of 1.

It should give exactly 100hz interrupts, down to the exact cpu cycle.
Close enough to be only a few seconds off after a month or two. Depending on your crystal.

AvionicsMaster1
- 14th February 2012, 02:10
Thank you. It's always nice getting a concise answer to a question. Especially when it is understandable and works.

Now if I could learn to be more concise asking the questions.

Regards.

Darrel Taylor
- 14th February 2012, 06:18
Sometimes, it's only after you've gone through the pain, that an answer makes sense.

Thanks for the original effort. :)