Interrupt RPM and Taylors Elapsed time on 18F4620


Closed Thread
Results 1 to 40 of 71

Hybrid View

  1. #1

    Default Interrupt RPM and Taylors Elapsed time on 18F4620

    I see the 18F4620 has a couple 16 bit timers. I have RPM going into C2/CCP1. So if I have the code set up right I should be getting RPM. I am not though. I did have this code working just fine on a 16F877A.

    I needed to modify Taylors ET code to use Timer3. This code works just fine using Timer1 but then when I change the code around for Timer3 its not working.
    Any ideas? I am hoping I just have a couple lines of code setting up flags incorrectly and I will be able to use the ET and RPM at the same time.

    Code:
    RPM 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     PIR2.0		      ' CCP1 capture flag
    Overflow        VAR     PIR2.1	    	' 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
    
    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=1     'Timer1 OSC enabled
    T1CON.2=0     'sychro clock
    T1CON.1=1     'external clock
    T1CON.0=0     'stop timer
    
    pause 100
    SEROUT2 LCD,84, [Prefix, LcdCls]
    
    Include "modedefs.bas"	' Mode definitions for Serout
    
    Loop:
    TMR1H = 0                              
    TMR1L = 0
    capture = 0
    
    Start:
          If Capture = 0 then
             Goto Start
          endif
          'code doesn't make it this far..assuming waiting for Cpature =1
          T1CON.0=1
          Capture = 0 
          
    CaptureLoop:
      If Capture = 0 then
        Goto CaptureLoop
      endif
      
    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 398 '400
    RPM = (RPM*5)
    pause 10
     SEROUT2 LCD,84, [Prefix,CursorPS,0,"RPM ",dec5 RPM, " ", #Period]
     T1Con.0=0
     
     Gosub ClearTimer1
     
     Goto Loop
     
     ClearTimer1:
     If Capture = 0 then
        goto ClearTimer1
     endif
     
     TMR1H = 00
     TMR1L = 0
     Capture = 0
     Overflow = 0 
     return
    Code:
    Taylors ET Code
    '****************************************************************
    '*  Name    : ELAPSED.PBP                                       *
    '*  Author  : Darrel Taylor                                     *
    '*  Notice  : Copyright (c) 2003                                *
    '*  Date    : 12/16/2003                                        *
    '*  Notes   :                                                   *
    '****************************************************************
    disable debug
    
    Define  INTHAND _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.0  = 0                   ; (TMR1IF) Clear Timer1 Interrupt Flag
        PIE2.0  = 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

  2. #2
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Looks like you forgot to write to CCP1CON to turn on capture.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  3. #3


    Did you find this post helpful? Yes | No

    Default rpm is getting really close

    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

  4. #4
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    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 01:04.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  5. #5


    Did you find this post helpful? Yes | No

    Default 877A to 4620 data

    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	36
    Code:
    '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
    return
    Code:
    '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

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    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]
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts