Menu

Reset CCP1 on the fly interrupts do not work

Help
Capaction
2011-02-16
2013-05-30
  • Capaction

    Capaction - 2011-02-16

    We have a latched Hall Sensor on CCP1 pin with 2 magnets on a wheel diameter.
    CCP1 pin is 5Volts for half a turn and 0Volt for the next half turn.
    We want to measure the pulse time on 5Volts between 2 captures (rising and falling)
    Then we want to have the LEDon for half a turn at any speed.
    GCBASIC compile with no error, but the code does not work.

    DO
    'Set up timer
    InitTimer1 Osc,PS1_1/8
    ClearTimer 1
    StartTimer 1

    If PilotFlag = 0 Then
    ' Set up CCP1 capture mode every 1 Cycle Rising Edge
    CCP1CON = b'00000101'
    On Interrupt CCP1 Call PulseReceived    ' will set PilotFlag = 1
    TimeCount1 = TimeCount
    ' Reset CCP1 module
    CCP1CON = b'00000000'
    End If

    If PilotFlag = 1 Then
    ' Set up CCP1 capture mode every 1 Cycle Falling Edge
    CCP1CON = b'00000100'
    On Interrupt CCP1 Call PulseReceived '  will set PilotFlag = 2
    SnapTiming =  TimeCount - TimeCount1  ' speed measure for 180°
    'Reset CCP1 module
    CCP1CON = b'00000000'
    End IF

    If PilotFlag = 2 Then
    LEDon
    ' Set up CCP1 compare mode
    CCP1CON = b'00001010'
    ClearTimer 1
    StartTimer 1
    CapturedTime = SnapTiming
    On Interrupt CCP1 Call PulseReceived 'will set PilotFlag = 3
    ' Reset CCP1 module
    CCP1CON = b'00000000'
    End If

    If PilotFlag = 3 Then
    LEDoff
    PilotFlag = 0
    End If
    Loop
    '===== HANDLER 
    '=========================================================
    Sub PulseReceived (TimeCount As word, CapturedTime As word)
    TimeCount = CapturedTime     '  Alias CCPR1H,CCPR1L
    PilotFlag + = 1
    End Sub

     
  • mmotte

    mmotte - 2011-02-16

    Your Do- loop is resetting the timer and re-initializing the ccp every loop.

    Move you intializations outside of the main loop.  Could put them into subs.

     
  • mmotte

    mmotte - 2011-02-17

    This does not fulfill your requirement of triggering on both rising and falling edge.  But i may give you a better understanding of the flow of the program.
    This code has not been tried on a board/hdwe

    ' Pulse timer
    ' Port RC2 is CCP1 input
    '  CapturedTime is period of pulse
    '  Led is on for 1/2 rotation
    ' 2/17/2011

    #chip 16F886, 8     'chip must have ccp  I don't know what osc you are using

    #define  LED PORTB.0
    dir PORTB.0 OUT
    InitTimer1 Osc,PS1_1/8
    ClearTimer 1
    initCCP1
    '===============================Main
    Main:
    pilotflag =0
    do
    If (pilotflag = 1) AND (LED = ON) Then
    set LED OFF
    pilotflag = 0
    end if
    If (pilotflag = 1) AND (LED = OFF) Then
    set LED ON
    pilotflag = 0
    end if
    loop

    '==================Initialization of interrupt and ccp
    'four capture modes:
    '0100 falling edge
    '0101 rising edge
    '0110 every 4th rising edge
    '0111 every 16th rising edge
    '
    sub initCCP1
    dir PortC.2 in  'pulse input Pin RC2/CCP1/P1A on the PIC16F886
    T1CON = b'00110001'
    CCP1CON = b'00000000'       'Switching from one capture prescaler to another does not
    'clear the prescaler and may generate a false interrupt.
    'must switched off and then set
    CCP1CON = b'00000101'  'start pulse capture on rising edge
    On Interrupt CCP1 call PulseReceived ' set up the interrupt to read the duration and reset the timer
    StartTimer 1
    end sub

    '===== Interrupt HANDLER 
    '=========================================================
    Sub PulseReceived
    ClearTimer 1 ' reset timer 1
    CapturedTime_H = CCPR1H 'read pulse width and store
    CapturedTime_L = CCPR1L
    CCP1IF = 0 'clear capture flag
    PilotFlag  = 1 'indicate to main you have capture period
    End Sub

    GL

     
  • Capaction

    Capaction - 2011-02-18

    mmotte   your Main Do  Loop code do not use the CCP1 pin signal and do not  fulfill the requirement of measuring a pulse period with the CCP1 Capture Mode and wait half a revolution with athe CCP1 Compare Mode.
    I modified the code with your idea  of re-initializing in the handler outside the loop. But the new code below does not   fulfill the requirement  of changing the CCP1 Mode on the Fly.

    PilotFlag = 0

    'Set up timer
    InitTimer1 Osc,PS1_1/8
    ClearTimer 1
    StartTimer 1

    DO

    If PilotFlag = 0 Then
    'Set up CCP1 capture mode every 1 Cycle Rising Edge
    CCP1CON = b'00000101'
    Set CCP1IF = 0
    On Interrupt CCP1 Call PulseReceived 'will set PilotFlag = 1
    End If

    If PilotFlag = 1 Then
    LEDoff
    Set COIL1 ON
    TimeCount1 = TimeCount
    'Set up CCP1 capture mode every 1 Cycle Falling Edge
    CCP1CON = b'00000100'
    Set CCP1IF = 0
    On Interrupt CCP1 Call PulseReceived ' will set PilotFlag = 2
    End If

    If PilotFlag = 2 Then
    SnapTiming2 =  TimeCount - TimeCount1 ' speed measure for 180°
    SnapTiming1 =  Snaptiming2 / 2 ' speed measure for 90°
    Timeoffset = SnapTiming1 / 7         ' maximum advance 26°
    'Set up CCP1 compare mode
    CCP1CON = b'00001010'
    Set CCP1IF = 0
    CapturedTime = SnapTiming1 - Timeoffset
    On Interrupt CCP1 Call PulseReceived    ' set PilotFlag = 3
    End If

    If PilotFlag = 3 Then
    Set COIL1 Off
    End If

    LOOP

    '==============================================================
    '===== HANDLER  
    '==============================================================
    Sub PulseReceived (TimeCount As word, CapturedTime As word)
    TimeCount = CapturedTime  'Alias CCPR1H,CCPR1L
    PilotFlag + = 1
    IF PilotFlag = 4 Then PilotFlag = 0
    LEDon
    Set CCP1IE = 0
    'Reset CCP1 module
    CCP1CON = b'00000000'
    ClearTimer 1
    StartTimer 1
    End Sub

     
  • mmotte

    mmotte - 2011-02-19

    capaction, 
    You only need to set up the interrupt once. It must be called outside the main loop once. It sets up the vector for the interrupt.

    Check out this explanation and see the example.

    http://gcbasic.sourceforge.net/newfiles/help/oninterrupt.htm

     
  • mmotte

    mmotte - 2011-02-19

    capaction,

    looks like you are using ccp1 for too many purposes

    which chip are you using?

    you should have other resources like ccp2,  interrupt on port B change, interrupt

     
  • Nobody/Anonymous

    mmotte I am using a MicroChip PIC 16F628 with a 20Mhz Cristal config is OSC = HS
    I have several good test codes on the PC board for  the CCP1 pin working in Capture Mode, and for the timer1.  .
    The GCBASIC   oninterrupt help says GCBASIC doesn't fully support all of the hardware which can generate interrupts ……
    This is why I am working with the Microchip PIC MCU  CCP and ECCP Tips and Tricks document

    http://ww1.microchip.com/downloads/en/DeviceDoc/41214B.pdf

    Tip#3 Measuring Pulse Width   page 8  ( half a revolution with my Hall Sensor hardware )

               COMPARE TIPS ' N TRICKS  page 16

              COMBINATION  CAPTURE  AND  COMPARE  TIPS  page 49

    Thank you for looking on the Reset on the Fly challenge.

     
  • mmotte

    mmotte - 2011-02-20

    capaction,
    GCBASIC may not have keyword for somethings but that does not prevent the programmer from using any features of the chip. GCBASIC allows integration of assembly directly intermixed with the basic, I find this an advantage.

    Here is my latest attempt to code your challenge.
    It sounds like a four stroke engine. How do you know if you are on the power stroke?

    'Select chip
    #chip 16F628, 20
    'Define ports
    #define LED    PORTA.1
    #define COIL1  PORTA.2
    #define LEDoff Set LED off
    #define LEDon  Set LED on
    'Set port directions
    dir LED     out
    dir COIL1   out
    dir PortB.3 in              'pulse input Pin RB3/CCP1 on the PIC16F628 
    DIM TimeCount As word
    DIM TimeCount1 As word
    DIM CapturedTime As word
    DIM SnapTiming1 As word
    DIM SnapTiming2 As word
    DIM Timeoffset As word
    PilotFlag = 0
    'Initialize Interrupt and Set up timer
        InitTimer1 Osc,PS1_1/8
        CCP1CON = b'00000000' 
        CCP1CON = b'00000101'       'start pulse capture on rising edge 
        On Interrupt CCP1 call PulseReceived    ' set up the interrupt to read the duration
        ClearTimer 1
        StartTimer 1
        CCP1IF = 0 
    DO
    wait 100 ms   'do nothing, interrupt is doing it all
    LOOP
    '==============================================================
    '===== HANDLER   
    '==============================================================
    Sub PulseReceived 
        ClearTimer 1                    ' reset timer 1
        CapturedTime_H = CCPR1H     'read pulse width and store 
        CapturedTime_L = CCPR1L
    
    If PilotFlag = 0 Then
        LEDon
        'Set up CCP1 capture mode every 1 Cycle Rising Edge
        CCP1CON = b'00000000' 
        CCP1CON = b'00000101'
       End If
    If PilotFlag = 1 Then
        LEDoff
        Set COIL1 ON
        TimeCount1 = CapturedTime
        'Set up CCP1 capture mode every 1 Cycle Falling Edge
        CCP1CON = b'00000000' 
        CCP1CON = b'00000100'
       End If
    If PilotFlag = 2 Then
        SnapTiming2 =  CapturedTime - TimeCount1    ' speed measure for 180°
        SnapTiming1 =  Snaptiming2 / 2      ' speed measure for 90°
        Timeoffset = SnapTiming1 / 7                    ' maximum advance 26°
        'Set up CCP1 compare mode
        'Compare mode, generate software interrupt on match 
        'CCP1IF bit is set, CCP1 pin is unaffected
        CCP1CON = b'00000000' 
        CCP1CON = b'00001010'
        CapturedTime = SnapTiming1 - Timeoffset
        CCPR1H = CapturedTime_H     'write pulse width and store 
        CCPR1L = CapturedTime_L 
       End If
    If PilotFlag = 3 Then 
        Set COIL1 Off
       End If
        PilotFlag += 1
    IF PilotFlag = 4 Then PilotFlag = 0
        CCP1IE = 0
        CCP1IF = 0                  'clear capture flag 
        ClearTimer 1
        StartTimer 1
    End Sub
    'The user should keep bit
    'CCP1IE (PIE1<2>) clear to avoid false interrupts and
    'should clear the flag bit CCP1IF following any such
    'change in Operating mode.
    
     
  • Capaction

    Capaction - 2011-02-27

    mmotte thank you for your suggestion.
    My code does not work. I add an ignition test before the Do-wait-Loop  this code is OK with the PCB.
    then the Led is on, when I start the motor the led stays off;  meaning that the interrupts don't work.
    My code is there:
      http://capaction.free.fr/16F628_V12.txt

    I am puzzled

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.