If Charles hadn't done it with DT_INTS, I might have been upset (longer).
But he did ...
More things to simulate.
I might have to send Charles a 6-pack too. :D
<br>
Printable View
If Charles hadn't done it with DT_INTS, I might have been upset (longer).
But he did ...
More things to simulate.
I might have to send Charles a 6-pack too. :D
<br>
You ain't getting off that easy bud .. you still have to prove me wrong, and show a solution to the problem....)
Agreed, and accepted.
But just so I'm clear, what I'm proving wrong is that it's a revision or errata sheet problem with the 18F4620 itself.
And that using an 18F4431 will solve it?
In other words, I gotta do it in hardware too?
<br>
You just have to prove that my recommendations throughout this thread (for this specific controller) were wrong, and show your solution to the problem - using the same controller.
My point thus far has been that this particular controller is doo-doo. Your entry point on this thread stated;
Quote:
I think you need to clear the timer sooner.
Darrel, help me understand here...
I thought that Proteus dealt with many versions of compilers except PBP.
Are you just running the already compiled program and reverse troubleshooting in your head? I imagine that watching the registers would let you know where you are at and if you could transpose between the two, it would work.
Care to elaborate on how you use it to help you?
Bo
I had missed post#22 while working with proteus, but it didn't matter ... it works too.
So, at the risk of loosing beer :eek: ... and buying chips ...
Other than the problems that were fixed earlier ... CCP1CON missing ... period instead if CCPR1L:H ...
This is the problem ....
The 4620's oscillator is running at 20.13 mhz
If it's a crystal, the caps are wrong or the crystal is off (or a radio crystal).
If it's a cheap resonator, then it's only to be expected.
That's my story ... and I'm sticking to it. :)
No way to prove it unless Toby checks it.
If I run the simulator at 20.13mhz, I get the exact same numbers across the board.
<br>
I rive in China. The address in my bio is just to confuse people.
Theoretically I should be able to swap oscillators and the problem will be on the 877A. Give me a bit and I will try that.
Here is a link to the one I have on the boards.
http://mouser.com/ProductDetail/Kyoc...XFVfiWpjmqo%3d
I think Darrel nailed it with the oscillator problem. Nice catch. I just assumed you were
testing different PICs on the same board.
its the osc. I had no idea there could be that much variance. Can you suggest a better part number?
Woohoo!
I can taste it already. :D
http://www.pbpgroup.com/files/180px-Guinness.jpg
Currently, you can only simulate the .hex files directly in Proteus.
No single stepping through the program.
But you can use it as a debugger in MPLAB where you can single step and watch variables in PBP.
It's too slow for me that way though. It simulates in "Real-Time" when not animating.
It's like real hardware is sitting in front of you, only you can't create Smoke or Fry your chips. :)
I'm getting hooked on it.
It's just so nice not to have to build a breadboard to test things.
20 minutes, and you can draw it on the computer.
Plus, with the Logic Analyzer, O-Scope, I2C debugger etc.
It saves thousands on test equipment.
And my cats can't play with the wires. :D
<br>
Darrel,
Are you using the free or full version?
Using the Full version.
The free version doesn't let you draw your own circuits.
<br>
Thanks for the help on getting the RPM working right.
Next question, when I want to incorporate this into other code how do I keep it from taking up as much time as just measuring the pulse width with Pulsin? I can't have it in the little CaptureLoop routine waiting for the next rpm pulse.
Looking through the spec sheet on the 4620, I see CCP1IE (PIE1.2). If I enable that bit, will I get an interrupt on each cylinder fire? I know there is a way to start and stop timer1 based on the cylinder firing and not just looping for the cylinder firing.
Here is what I am working on assuming that is the right path to take. I haven't worked with interrupts much so I am sure I need more work.[HTML][/HTML]Code:DEFINE OSC 20
Prefix con $FE ' needed before each command
LcdCls CON $51 ' clear LCD (use PAUSE 5 after)
CursorPS con $45 'Cursor Position
Capture VAR PIR1.2 ' CCP1 capture flag CCP1IF
Overflow VAR PIR1.0 ' Timer1 overflow flag TMR1IF:
RPM var word
period var Word
TotalTime var word 'Holds seconds and tics
Counter var word
Detect var bit
LCD VAR PortC.6 'LCD output
ADCON0 =0 'A/D Off
ADCON1.3=1 'All AN channels digital
ADCON1.2=1 '''
ADCON1.1=1 '''
ADCON1.0=1 '''
TRISE.0=1 'EO input
TRISE.1=1 'E1 input
CCP1CON = %00000110 ; Capture mode, every rising edge 0101 , Fourth 0110
T1CON.7=1 'enable timer 16 bit `
T1CON.6=1 'Timer1 OSC
T1CON.5=1 '1:4 prescaler
T1CON.4=0 '1:4 prescaler
T1CON.3=0 'Timer1 OSC off
T1CON.2=0 'sychro clock
T1CON.1=0 'internal clock
T1CON.0=0 'stop timer
PIE1.2=1 'Enables the CCP1 interrupt
pause 10
SEROUT2 LCD,84, [Prefix, LcdCls]
Include "modedefs.bas" ' Mode definitions for Serout
SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM test"]
pause 500
TMR1H = 0 'Clear 8-bit register
TMR1L = 0 'Clear 8-bit register
capture = 0 'Clear Timer
Detect = 0
ON Interrupt goto Measure_Time
Loop:
Counter = Counter + 1
SEROUT2 LCD,84, [Prefix,CursorPS,0,dec5 Counter]
SEROUT2 LCD,84, [Prefix,CursorPS,20,"RPM ",dec5 RPM, " ", #Detect]
goto loop
Disable
Measure_Time:
SEROUT2 LCD,84, [Prefix,CursorPS,40,"Int ",dec5 RPM]
If Detect = 0 then
T1CON.0=1
detect = 1
capture = 0
endif
If Detect = 1 then
T1CON.0=0
detect = 0
period.LowByte=CCPR1L
period.HighByte=CCPR1H
capture = 0
TMR1H = 0
TMR1L = 0
RPM = 10000
RPM = RPM * RPM ' 100,000,000
RPM = DIV32 period ' 100,000,000 / RevCount
RPM = RPM * 60 ' Per minute
RPM = DIV32 1600
RPM = (RPM*5)
endif
Enable
return
See here Using hardware capture
Thanks for the link. The thing is though I don't want to go into a loop waiting for the tach pulse. I want to be able to do it by interrupt so I can be doing other things in between pulses and on the pulse go start/stop the timer.
Look at post #9. This is its main loop:
Code:Main:
' do other stuff here as required
IF CF.0 THEN ' figure out & print result only after last capture
PW = PW-T1 ' High pulse width = PW-T1
CF.0 = 0 ' clear flag bit
HSEROUT [DEC PW,"uS High",13,10]
ENDIF
GOTO Main
Thanks, when I insert the RPM part of code I get an error. Except for when I comment out the DIV32.
Code:' Measuring signal pulse widths with capture module & interrupt
' Procedure for high-going pulse:
' 1. Configure CCP to capture on rising edge
' 2. Setup Timer1 so it will not overflow during max pulse width time
' 3. Enable ccp capture
' 4. Once capture flag bit is set, save captured value as T1
' 5. Reconfigure CCP to capture on falling edge
' 6. On 2nd capture, save 2nd value as PW
' 7. Subtract T1 from PW for the pulse width value
Prefix con $FE ' needed before each command
LcdCls CON $51 ' clear LCD (use PAUSE 5 after)
LcdLine1 CON $00 ' move cursor to line 1
LcdLine2 con $40 ' move curson to line 2
LcdLine3 con $14 ' move curson to line 3
lcdLine4 con $54 ' move curson to line 4
LcdCol1 con $00 ' move cursor to column 1
LcdCol2 con $07 ' move cursor to column 7
Backlight con $53 ' Backlighting 1-8
CursorPS con $45 'Cursor Position
CursorOn con $47 'Cursof On
CursorOff con $48 'Cursor Off
LCD VAR PortC.6 'LCD output
DEFINE OSC 20 ' 4MHz for 1uS resolution TMR1 counts
DEFINE INTHAND CCP_INT ' declare high-pri interrupt handler
Symbol Capture = PIR1.2 ' CCP1 capture flag
SYMBOL CapIE = PIE1.2 ' CCP1 interrupt enable bit
SYMBOL CapPriEn = IPR1.2 ' priority enable bit for CCP1 interrupt
SYMBOL PriEnable = RCON.7 ' set to enable priority levels on interrupts
T1 VAR WORD BANKA SYSTEM ' 1st capture value
PW VAR WORD BANKA SYSTEM ' 2nd capture value & ultimately final pulse width
CF VAR BYTE BANKA SYSTEM ' indicates when last capture is ready
RPM var word
Period var word
CLEAR ' clear RAM on POR
TRISC.2 = 1 ' CCP1 input pin (Capture input on 18F242)
INTCON = 0 ' Interrupts off for now
GOTO Init ' jump over interrupt handler
ASM
CCP_INT
BTFSS CCP1CON,0 ; capture from rising edge?
BRA Fall ; no .. goto falling edge
MOVFF CCPR1L, T1 ; get low capture byte into T1
MOVFF CCPR1H, T1+1 ; get high capture byte into T1
BRA IntExit ; outta here
Fall
MOVFF CCPR1L, PW ; get low capture byte into PW
MOVFF CCPR1H, PW+1 ; get high capture byte into PW
BSF CF,0 ; indicate last capture
IntExit
BTG CCP1CON,0 ; toggle between rising/falling edge captures
BCF PIR1,2 ; clear capture interrupt flag bit
RETFIE FAST ; return/restore W, STATUS and BSR
ENDASM
Init: ' initialize a few things first
CCP1CON = %00000110 ' Capture mode, capture on rising edge
'T1CON = 0 ' TMR1 prescale=1, clock=Fosc/4, TMR1=off
T1CON.7=1 'enable timer 16 bit `
T1CON.6=1 'Timer1 OSC
T1CON.5=1 '1:4 prescaler
T1CON.4=0 '1:4 prescaler
T1CON.3=0 'Timer1 OSC off
T1CON.2=0 'sychro clock
T1CON.1=0 'internal clock
TMR1H = 0 ' Clear high byte of TMR1 counter
TMR1L = 0 ' Clear low byte
PriEnable = 1 ' enable priority levels on interrupts
Capture = 0 ' clear capture flag bit
CapPriEn = 1 ' set CCP1 int to high priority
CapIE = 1 ' enable the CCP1 capture interrupt
INTCON = %11000000 ' global + peripheral ints enabled
T1CON.0 = 1 ' Turn TMR1 on here
Main:
' do other stuff here as required
IF CF.0 THEN ' figure out & print result only after last capture
PW = PW-T1 ' High pulse width = PW-T1
Period = PW
CF.0 = 0 ' clear flag bit
RPM = 10000
'RPM = RPM * RPM ' 100,000,000
'RPM = DIV32 period ' 100,000,000 / RevCount
RPM = RPM * 60 ' Per minute
'RPM = DIV32 1600
RPM = (RPM*5)
SEROUT2 LCD,84, [Prefix,CursorPS,0,#PW]
ENDIF
GOTO Main
END
Change T1 VAR WORD BANKA SYSTEM to something else. My example was a PBP
re-make from a Microchip app note using T1 as a variable, and didn't use DIV32.
PBP has an internal variable it uses named T1 for complex math equations. Just changing
the name of this variable should clear the problem.
Bruce, thank you for this information (there is no trace into the PBP manual!)Quote:
PBP has an internal variable it uses named T1 for complex math equations. Just changing
the name of this variable should clear the problem.
There are other reserved words, we should avoid and not mentioned into the PBP manual?
Al.
Hi Al,
PBP declares several internal variables as it needs them. Names are R0 - R8, T0 - T7, FLAGS, GOP, RM1, RM2, RR1, RR2, RS1, RS2, PRODL, TBLPTRU, TBLPTRH, TBLPTRL and perhaps some I've missed. Some get's declared in every program and some only depending on what your PBP code does.
This, of course, isn't something I've figured out myself - I've simply looked at Darrels Instant Interrupt code - specifically the ReEnterPBP18 file.
/Henrik.
Tobias, The RESERVED words are in the manual and are not to be used, they are on the last couple of pages or so...
Dave Purola,
N8NTA
Hi Henrik, thank you for your post. "Every day is a good to learn something knew, but again, let me stess my point "NO MENTION IN THE MANUAL" (at least mine) and this is pretty bad.
What now will make me worring for a while (till I will forget it) is your statement
"... and perhaps some I've missed". Is there a way to obtain the full list?
Al.
Hi Al,
I don't see anything about the system variables in the manual either but I don't think it's that big of a problem. If you're trying to declare T2 (or whatever) in your program but the compiler also declares T2 as it needs it for its library calls you'll get an error saying Redefinition of VAR - which I guess is the error Tobias got when he was using T1. So, it shouldn't cause any real trouble.
/Henrik.
What happens is something like this;
Declaring T1 VAR WORD BANKA SYSTEM creates a user VAR T1 without the underscore. Then you can use T1 in your assembler routine without the underscore like in my example.
T1 VAR BYTE BANKA removing the SYSTEM part would create the user variable with the underscore _T1, which wouldn't clash with the PBP temp system variable T1.
I.E. the user var would be _T1. PBPs system var would be T1.
A good rule-of-thumb would be to just never declare a system variable with any PBP system variable name. Totally my fault on this one. I did this for someone that asked me to translate a Microchip Tips & Tricks example to PBP, and just didn't consider T1, like used in the Microchip example.
Maybe it wouldn't be a bad idea for the PBP manual to include a complete list of all temp system variables?
Standard PBP system variables are listed in the reserved words section, but none of the temp variables, that may or may not even be used, for heavy number crunching are.
The RPM code works great. I changed a few things around like the scaler configs to work with a V-8. I incorporated it into the other code I have that also uses the elapsed time code. When I compile I got an error centered around DEFINE INTHAND CCP_INT. So I looked in the elapsed-18-t3con.bas file and it has Define INTHAND _ClockCount I did some research on the forums and found I can used INTLHAND. Apparently I am defining two high priority interrupt handlers and that is a no-no. So I changed the line to Define INTLHAND _ClockCount . From what I have learned the LHAnd is another interrupt handler with a lower priority.
I have changed the Elapsed code to use T3 and also go to the thousandths of a second. It worked fine separately too. The code is on the next post.
When I start the timer, apparently the code goes into a loop on the elasped time code. If I don't start the timer, the code progresses to the next line of code and beyond. I have tried changing around the INTLHAND and INTHAND but same result.
Code:Start var PortB.0
OnOff var PortB.1 'Input to start timers
Dig4 Var PortB.2
Reset var PortB.3
SOR VAR PortC.7 'Shift Over-Ride
Dig1 Var PortC.0
Dig2 var PortA.0
Dig3 var PortA.1
Up1 var PortA.3 'Up button to change seconds
Down1 var PortA.2 'Down button to change seconds.
Up001 var PortE.0 'Up button to change tenths of second.
Down001 var PortE.1 'Down button to change tenths of second.
Up01 var PortA.4 'Up button to change hundredths of a second
Down01 var PortA.5 'Down button to change hundredths of a second
Tool var PortB.4 'Button to change to diffent menu
UpStage var PortD.0 'Button to change stages
DownStage var PortC.3 'Button to change stages
LCD VAR PortC.6 'LCD output
RPMInput var PortC.2
Gate1 Var PortC.1
Gate2 var PortD.1
Gate3 var PortD.2
Gate4 var PortD.3
Gate5 var PortD.6
Gate6 var PortD.7
Gate7 var PortD.5
Gate8 var PortD.4
StageCounter var byte
OnOffType var Bit 'Toggles between On/Off part of a Stage
ETorRPM var Bit
EditStage var byte
TotalTime var word 'Holds seconds and tics
Active var bit
Prefix con $FE ' needed before each command
LcdCls CON $51 ' clear LCD (use PAUSE 5 after)
LcdLine1 CON $00 ' move cursor to line 1
LcdLine2 con $40 ' move curson to line 2
LcdLine3 con $14 ' move curson to line 3
lcdLine4 con $54 ' move curson to line 4
LcdCol1 con $00 ' move cursor to column 1
LcdCol2 con $07 ' move cursor to column 7
Backlight con $53 ' Backlighting 1-8
CursorPS con $45 'Cursor Position
CursorOn con $47 'Cursof On
CursorOff con $48 'Cursor Off
Symbol Capture = PIR1.2 ' CCP1 capture flag
SYMBOL CapIE = PIE1.2 ' CCP1 interrupt enable bit
SYMBOL CapPriEn = IPR1.2 ' priority enable bit for CCP1 interrupt
SYMBOL PriEnable = RCON.7 ' set to enable priority levels on interrupts
TS VAR WORD BANKA SYSTEM ' 1st capture value
PW VAR WORD BANKA SYSTEM ' 2nd capture value & ultimately final pulse width
CF VAR BYTE BANKA SYSTEM ' indicates when last capture is ready
RPM var word BANKA SYSTEM
Period var word BANKA SYSTEM
define CODE_SIZE 32
define osc 20
DEFINE INTHAND CCP_INT ' declare high-pri interrupt handler
Capture_Loop = 0
CLEAR ' clear RAM on POR
TRISC.2 = 1 ' CCP1 input pin (Capture input on 18F242)
INTCON = 0 ' Interrupts off for now
INTCON2.7 = 0 'Pull Ups enabled
ADCON0 =0
ADCON1.3=1
ADCON1.2=1
ADCON1.1=1
ADCON1.0=1
TRISE.0=1
TRISE.1=1
'---------Display Start-Up Info-------
Include "Elapsed-18-T3CON.bas"
Include "modedefs.bas" ' Mode definitions for Serout
Pause 200
gosub ClearScreen
pause 100
GOTO Init
ASM
CCP_INT
BTFSS CCP1CON,0 ; capture from rising edge?
BRA Fall ; no .. goto falling edge
MOVFF CCPR1L, TS ; get low capture byte into T1
MOVFF CCPR1H, TS+1 ; get high capture byte into T1
BRA IntExit ; outta here
Fall
MOVFF CCPR1L, PW ; get low capture byte into PW
MOVFF CCPR1H, PW+1 ; get high capture byte into PW
BSF CF,0 ; indicate last capture
IntExit
BTG CCP1CON,0 ; toggle between rising/falling edge captures
BCF PIR1,2 ; clear capture interrupt flag bit
RETFIE FAST ; return/restore W, STATUS and BSR
ENDASM
Init: ' initialize a few things first
CCP1CON = %00000110 ' Capture mode, capture on rising edge
T1CON.7=1 'enable timer 16 bit `
T1CON.6=1 'Timer1 OSC
T1CON.5=1 '1:4 prescaler
T1CON.4=0 '1:4 prescaler
T1CON.3=0 'Timer1 OSC off
T1CON.2=0 'sychro clock
T1CON.1=0 'internal clock
TMR1H = 0 ' Clear high byte of TMR1 counter
TMR1L = 0 ' Clear low byte
PriEnable = 1 ' enable priority levels on interrupts
Capture = 0 ' clear capture flag bit
CapPriEn = 1 ' set CCP1 int to high priority
CapIE = 1 ' enable the CCP1 capture interrupt
INTCON = %11000000 ' global + peripheral ints enabled
T1CON.0 = 1 ' Turn TMR1 on here
Gosub ResetTime
'---------Pre Run Routine------------------------------
PreRun:
Repeat
Serout2 LCD, 84, [Prefix,CursorPS,64,"Ready ", DEC5 RPM]
gosub Tach
Gosub Shift
Until Start = 0 and OnOff = 0
'-----------Run Routine--------------------------
While Start = 0 and OnOff = 0
PrvOnOffType=0
wend
Active = 1
Run: ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
While Start=0 and OnOff = 1 '''''!!!!!!!!!!!!!!!
If Active = 1 then
Gosub StartTimer
endif
Serout2 LCD,84,[Prefix,CursorPS,71,"test "]', #Stage3TOn]
''''Code doesn't make it this far. If I comment out 'gosub startimer' it makes it to this line.
Gosub Calc_TotalTime
Wend
gosub Tach
Here is the elasped timer code I modified to use T3 and go to the thousandths. Also I have the interrupt set up as INTLHAND
Code:'****************************************************************
'* Name : ELAPSED.PBP *
'* Author : Darrel Taylor *
'* Notice : Copyright (c) 2003 *
'* Date : 12/16/2003 *
'* Notes : *
'****************************************************************
disable debug
Define INTLHAND _ClockCount ' Tell PBP Where the code starts on an interrupt
Include "ASM_INTS-18.bas" ' ASM Interrupt Stubs
Ticks var Word ' 1/1000th of a second
Seconds var byte
Minutes var byte
Hours var byte
Days var word
R0save var word
R1save var word
R4save var word
SecondsChanged var bit
MinutesChanged var bit
HoursChanged var bit
DaysChanged var bit
SecondsChanged = 1
MinutesChanged = 1
Goto OverElapsed
' ------------------------------------------------------------------------------
Asm
IF OSC == 4 ; Constants for 100hz interrupt from Timer1
TimerConst = 0D8F7h ; Executed at compile time only
EndIF
If OSC == 8
TimerConst = 0B1E7h
EndIF
If OSC == 10
TimerConst = 09E5Fh
EndIF
If OSC == 20
TimerConst = 0EC80h
EndIF
If OSC == 40
TimerConst = 03CB7h
EndIF
; ----------------- ADD TimerConst to TMR1H:TMR1L
ADD2_TIMER macro
CHK?RP T3CON
BCF T3CON,TMR3ON ; Turn off timer
MOVLW LOW(TimerConst) ; 1
ADDWF TMR3L,F ; 1 ; reload timer with correct value
BTFSC STATUS,C ; 1/2
INCF TMR3H,F ; 1
MOVLW HIGH(TimerConst) ; 1
ADDWF TMR3H,F ; 1
endm
; ----------------- ADD TimerConst to TMR1H:TMR1L and restart TIMER1
RELOAD_TIMER macro
ADD2_TIMER
BSF T3CON,TMR3ON ; 1 ; Turn TIMER1 back on
CHK?RP PIR2
bcf PIR2, TMR3IF ; Clear Timer1 Interrupt Flag
endm
; ----------------- Load TimerConst into TMR1H:TMR1L
LOAD_TIMER macro
EndAsm
T3CON.0 = 0 ; Turn OFF Timer1
TMR3L = 0
TMR3H = 0
Asm
ADD2_TIMER
endm
EndAsm
' ------[ This is the Interrupt Handler ]---------------------------------------
ClockCount: ' Note: this is being handled as an ASM interrupt
@ INT_START
@ RELOAD_TIMER ; Reload TIMER1
R0save = R0 ; Save 2 PBP system vars that are used during
R1save = R1 ; the interrupt
R4save = R4
Ticks = Ticks + 1
if Ticks = 1000 then
Ticks = Ticks-1000
Seconds = Seconds + 1
SecondsChanged = 1
if Seconds = 60 then
Minutes = Minutes + 1
MinutesChanged = 1
Seconds = 0
endif
if Minutes = 60 then
Hours = Hours + 1
HoursChanged = 1
Minutes = 0
endif
if Hours = 24 then
Days = Days + 1
DaysChanged = 1
Hours = 0
endif
endif
R4 = R4save ; Restore the PBP system vars
R1 = R1save
R0 = R0save
@ INT_RETURN ; Restore context and return from interrupt
'-----====[ END OF TMR1 Interrupt Handler ]====---------------------------------
StartTimer:
T3CON.1 = 0 ; (TMR1CS) Select FOSC/4 Clock Source
T3CON.3 = 0 ; (T1OSCEN) Disable External Oscillator
PIR2.1 = 0 ; (TMR1IF) Clear Timer1 Interrupt Flag
PIE2.1 = 1 ; (TMR1IE) Enable TMR1 overflow interrupt
INTCON.6 = 1 ; (PEIE) Enable peripheral interrupts
INTCON.7 = 1 ; (GIE) Enable global interrupts
T3CON.0 = 1 ; (TMR1ON) Start TIMER1
@ if OSC == 40
T3CON.5 = 0 ; Prescaler = 1:2
T3CON.4 = 1
@ endif
return
; -----------------
StopTimer:
T3CON.0 = 0 ; Turn OFF Timer1
return
; -----------------
ResetTime:
R0save = T3CON.0 ; Save TMR1ON bit
T3CON.0 = 0 ; Turn OFF Timer1
TMR3L = 0
TMR3H = 0
@ LOAD_TIMER ; Load TimerConst
T3CON.0 = R0save ; Restore TMR1ON bit
Ticks = 0
Seconds = 0
Minutes = 0
Hours = 0
Days = 0
SecondsChanged = 1
return
OverElapsed:
enable debug
This appears to be working correctly. Are there any problems going this route?
Of course this isn't all the code, just the part that is relevant.
Code:DEFINE INTHAND Direction
ASM
Direction
ENDASM
If PIR1.2 = 1 then
goto RPMASM
endif
If PIR2.1 = 1 then
goto ClockCount
endif
return
RPMASM:
ASM
CCP_INT
BTFSS CCP1CON,0 ; capture from rising edge?
BRA Fall ; no .. goto falling edge
MOVFF CCPR1L, TS ; get low capture byte into T1
MOVFF CCPR1H, TS+1 ; get high capture byte into T1
BRA IntExit ; outta here
Fall
MOVFF CCPR1L, PW ; get low capture byte into PW
MOVFF CCPR1H, PW+1 ; get high capture byte into PW
BSF CF,0 ; indicate last capture
IntExit
BTG CCP1CON,0 ; toggle between rising/falling edge captures
BCF PIR1,2 ; clear capture interrupt flag bit
RETFIE FAST ; return/restore W, STATUS and BSR
ENDASM
ClockCount: ' Note: this is being handled as an ASM interrupt
@ INT_START
@ RELOAD_TIMER ; Reload TIMER1
R0save = R0 ; Save 2 PBP system vars that are used during
R1save = R1 ; the interrupt
R4save = R4
Ticks = Ticks + 1
if Ticks = 1000 then
Ticks = Ticks-1000
Seconds = Seconds + 1
SecondsChanged = 1
if Seconds = 60 then
Minutes = Minutes + 1
MinutesChanged = 1
Seconds = 0
endif
if Minutes = 60 then
Hours = Hours + 1
HoursChanged = 1
Minutes = 0
endif
if Hours = 24 then
Days = Days + 1
DaysChanged = 1
Hours = 0
endif
endif
R4 = R4save ; Restore the PBP system vars
R1 = R1save
R0 = R0save
@ INT_RETURN ; Restore context and return from interrupt
You don't need the bit tests in Direction since you have CCP_INT (or Direction) set as a high-priority interrupt, and you have ClockCount set as a low-priority interrupt.
Direction will be jumped to automatically when the CCP interrupt fires. ClockCount will be jumped to automatically when the TMR3 interrupt fires. Note that your low-priority interrupt can be interrupted by the high-priority one.