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.
<br>
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.
<br>
DT
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>
DT
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;
I think you need to clear the timer sooner.
Last edited by Bruce; - 29th January 2010 at 08:17.
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... 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>
DT
I rive in China. The address in my bio is just to confuse people.
Charles Linquist
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
Last edited by Tobias; - 29th January 2010 at 15:53.
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?
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.
<br>
DT
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>
DT
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!)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.
All progress began with an idea
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.
All progress began with an idea
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.
Last edited by HenrikOlsson; - 2nd February 2010 at 13:06.
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.
Bookmarks