Interrupt RPM and Taylors Elapsed time on 18F4620


Closed Thread
Results 1 to 40 of 71

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    Default

    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.
    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
    [HTML][/HTML]

  2. #2
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

  3. #3


    Did you find this post helpful? Yes | No

    Default

    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.

  4. #4
    Join Date
    May 2007
    Posts
    604


    Did you find this post helpful? Yes | No

    Default

    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

  5. #5


    Did you find this post helpful? Yes | No

    Default

    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

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


    Did you find this post helpful? Yes | No

    Default

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

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

  7. #7
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default

    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!)

    There are other reserved words, we should avoid and not mentioned into the PBP manual?

    Al.
    All progress began with an idea

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