Looks like you forgot to write to CCP1CON to turn on capture.
Looks like you forgot to write to CCP1CON to turn on capture.
Thanks for your help and also Taylors email. I inserted CCP1CON flags and also had a couple others wrong. I am learning alot about how to read the datasheets changing chips.
I am using an external 20 MHZ OSC
The code below works except it isn't as close as when I was using the 877A chip. I have an rpm frequency generator with a digital readout that I am using to check the rpm with the 4620 chip. Following is data
RPM with generator/RPM with 4620
4000/3975
5000/4965
6000/5960
7000/6955
8000/7950
9000/8945
10000/9935
All chip numbers are 99.35% appr from RPM generator. When I used the 877A all numbers matched up dead on.
Any ideas?
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 LCD VAR PortC.6 'LCD output 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 WOT var PortB.0 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 4th rising edge 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 pause 10 SEROUT2 LCD,84, [Prefix, LcdCls] Include "modedefs.bas" ' Mode definitions for Serout SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM test"] pause 500 Loop: TMR1H = 0 'Clear 8-bit register TMR1L = 0 'Clear 8-bit register capture = 0 'Clear Timer 'SEROUT2 LCD,84, [Prefix,CursorPS,0,"Capture ", dec Capture," ",DEC Period] Start: If Capture = 0 then Goto Start endif T1CON.0=1 Capture = 0 CaptureLoop: If Capture = 0 then 'SEROUT2 LCD,84, [Prefix,CursorPS,0,"Dont Capture ", dec Capture," ",DEC Period] Goto CaptureLoop endif T1Con.0=0 period.LowByte=CCPR1L period.HighByte=CCPR1H RPM = 10000 RPM = RPM * RPM ' 100,000,000 RPM = DIV32 period ' 100,000,000 / RevCount RPM = RPM * 60 ' Per minute RPM = DIV32 400 RPM = (RPM*5) SEROUT2 LCD,84, [Prefix,CursorPS,20,"RPM ",dec5 RPM, " ", DEC Period] Gosub ClearTimer1 Goto Loop ClearTimer1: If Capture = 0 then 'SEROUT2 LCD,84, [Prefix,CursorPS,40,"Don't Clear Timer ", DEC Period] goto ClearTimer1 endif ''SEROUT2 LCD,84, [Prefix,CursorPS,40,"Clear Timer ", DEC Period] TMR1H = 00 TMR1L = 0 Capture = 0 Overflow = 0 return
If you're using exactly the same setting for capture, timer1, etc, and it works 100%
on the 877A, but not on the 4620, then I would suspect a bug in the 4620, or something
has been changed somewhere between the 2 versions.
What values do you get if sending the raw value from period to your display immediately
after this?
period.LowByte=CCPR1L
period.HighByte=CCPR1H
Last edited by Bruce; - 28th January 2010 at 02:04.
Here are the numbers from an 877A and 4620 both configured to use HS 20 MHZ.
I will say I am not too sure with the T1Con flags if its set exactly as the 877A
Code:RPM 877A 4620 5000 Low Byte 202 243 High Byte 175 58 6000 Low Byte 125 31 High Byte 146 497 7000 Low Byte 141 26 High Byte 167 421 8000 Low Byte 125 215 High Byte 146 36Code:'877A 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 Overflow VAR PIR1.0 ' Timer1 overflow flag RPM var word period var Word TotalTime var word 'Holds seconds and tics LCD VAR PortC.6 'LCD output 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 WOT var PortB.0 ADCON0 =0 ADCON1.3=1 ADCON1.2=1 ADCON1.1=1 ADCON1.0=1 TRISE.0=1 TRISE.1=1 CCP1CON = %00000110 ' Enable the CCP1 capture, every 4th rising edge pause 100 SEROUT2 LCD,84, [Prefix, LcdCls] low Gate1 Low Gate2 Low Gate3 Low Gate4 Low Gate5 Low Gate6 Low Gate7 Low Gate8 Include "modedefs.bas" ' Mode definitions for Serout T1CON=%00100000 Loop: TMR1H = 0 TMR1L = 0 capture = 0 Start: IF capture = 0 Then goto Start ' Wait here for the first capture endif T1CON.0 = 1 ' Start the Timer capture = 0 ' Reset the capture flag CaptureLoop: IF capture = 0 Then goto CaptureLoop ' Wait here until captured endif period.lowbyte = CCPR1L ' Store the captured value in period.highbyte = CCPR1H ' period variable RPM = 10000 RPM = RPM * RPM ' 100,000,000 RPM = DIV32 period ' 100,000,000 / RevCount RPM = RPM * 60 ' Per minute RPM = DIV32 400 '400 RPM = (RPM*5) pause 10 SEROUT2 LCD,84, [Prefix,CursorPS,20,"RPM ",dec5 RPM, " ", DEC CCPR1L, " ", dec CCPR1H] T1CON.0=0 gosub cleartimer1 GoTo loop ' Do it forever ClearTimer1: IF (capture = 0) Then goto cleartimer1 ' Wait for beginning of next period endif TMR1L = 0 ' Clear Timer1 low register TMR1H = 0 ' Clear Timer1 high register capture = 0 ' Clear capture flag overflow = 0 ' Clear overflow flagReturn returnCode:'4620 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 LCD VAR PortC.6 'LCD output 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 WOT var PortB.0 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 4th rising edge 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 pause 10 SEROUT2 LCD,84, [Prefix, LcdCls] Include "modedefs.bas" ' Mode definitions for Serout SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM test"] pause 500 Loop: TMR1H = 0 'Clear 8-bit register TMR1L = 0 'Clear 8-bit register capture = 0 'Clear Timer Start: If Capture = 0 then Goto Start endif T1CON.0=1 Capture = 0 CaptureLoop: If Capture = 0 then Goto CaptureLoop endif T1Con.0=0 period.LowByte=CCPR1L period.HighByte=CCPR1H RPM = 10000 RPM = RPM * RPM ' 100,000,000 RPM = DIV32 period ' 100,000,000 / RevCount RPM = RPM * 60 ' Per minute RPM = DIV32 400 RPM = (RPM*5) SEROUT2 LCD,84, [Prefix,CursorPS,20,"RPM ",dec5 RPM, " ", DEC CCPR1L, " ", dec CCPR1H] Gosub ClearTimer1 Goto Loop ClearTimer1: If Capture = 0 then goto ClearTimer1 endif TMR1H = 00 TMR1L = 0 Capture = 0 Overflow = 0 return
Are your result figures correct? It shows the exact same result on the 877A for 6000
and 8000 RPM!
What do you get with something like this on both versions?
Code:period.lowbyte = CCPR1L ' Store the captured value in period.highbyte = CCPR1H ' period variable SEROUT2 LCD,84, [Prefix,CursorPS,20,dec5 period]
RPM and period numbers per chip
Rpm 4620 877a
5000 15090 14999
6000 12575 12499
7000 10777 10712
8000 9430 9373
9000 8383 8331
10000 7545 7499
Do you have another 18F type besides a 4620 you can test this on?
That would tell you if it's a hardware bug on the 4620. This part has
a massive list of errata & odd problems with ECCP, Timer1, Timer3,
and more.
I think you need to clear the timer sooner. (Immediately after capture).
The program goes through the whole conversion to RPM with multiplications and DIV32's before clearing the timer.
The 18F's multiply faster because they have a hardware multiplier.
So it clears the timer quicker and ends up with bigger numbers.
The 4620 numbers are closer to reality, but it's still wrong.
Clear the timer immediately after a capture and both chips should read the same numbers (or really close).
hth,
DT
Bookmarks