mS Timer


Closed Thread
Results 1 to 7 of 7

Thread: mS Timer

Hybrid View

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


    Did you find this post helpful? Yes | No

    Default

    Grab that app note Steve linked to. It's got some pretty cool stuff in it.

    This will save you a little time deciphering it;

    Code:
    ' Measuring signal pulse widths with capture module
    
    ' 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
    
    ' Test signal:
    ' 12.04kHz pulse with 41uS high / 42uS low
    ' Input signal connected to RC2/CCP1 pin
    
        ' PIC18F242 @20MHz
        DEFINE OSC 20
        DEFINE DEBUG_REG PORTC
        DEFINE DEBUG_BIT 6 
        DEFINE DEBUG_BAUD 115200
        DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true
    
        Symbol    Capture = PIR1.2 ' CCP1 capture flag
        T1        VAR WORD         ' 1st capture value
        PW        VAR WORD         ' 2nd capture value & ultimately final pulse width
    
        TRISC.2 = 1          ' CCP1 input pin (Capture input)
        INTCON = 0           ' Interrupts off
        
    ReLoad:
        CCP1CON = %00000101  ' Capture mode, capture on rising edge
        T1CON = 0            ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
        TMR1H = 0            ' Clear high byte of TMR1 counter
        TMR1L = 0            ' Clear low byte
        T1CON.0 = 1          ' Turn TMR1 on here
    
        Capture = 0         ' Clear capture int flag bit
        While !Capture      ' Wait here until capture on rising edge
        Wend
        
        ' Rising edge detected / stuff Timer1 value in T1
        T1.HighByte = CCPR1H
        T1.LowByte = CCPR1L
        
        CCP1CON.0 = 0       ' Configure capture for falling edge now
        Capture = 0         ' Clear capture interrupt flag bit
        
        While !Capture      ' While here until capture on falling edge
        Wend
        
        ' Falling edge detected / stuff Timer1 value in PW
        PW.HighByte = CCPR1H
        PW.LowByte = CCPR1L
        
        PW = PW-T1           ' High pulse width = PW-T1
        ' Convert to uS for 20MHz osc with 200nS Timer1 ticks
        PW = (PW * 2)/10
    
        DEBUG dec PW,"uS High",13,10	' Output to RS232 display
        GOTO ReLoad
        
        END
    I ran it with a 2nd PIC delivering a 12.04kHz signal: HPWM 1,127,12000 to the
    18F242 CCP1 pin. 41uS high, 42uS low.

    It's spot-on. Returns 41uS High on MCS serial terminal. Fluke ScopeMeter 123
    shows precisely the same timing.

    Much nicer than pulsin, count, etc..

    Darrel Taylors' instant interupts works perfect for this.
    Code:
    ' PIC18F242 @20MHz
    DEFINE OSC 20
    DEFINE DEBUG_REG PORTC
    DEFINE DEBUG_BIT 6 
    DEFINE DEBUG_BAUD 115200
    DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true
    
    OverFlows  VAR BYTE ' Timer1 overflow total
    Remainder  VAR WORD ' Remaining Timer1 ticks after falling edge capture
    
    INCLUDE "DT_INTS-18.bas"       ; Base Interrupt System
    INCLUDE "ReEnterPBP-18.bas"    ; Include if using PBP interrupts
    
    ;----[High Priority Interrupts]----------------------------------------
    ASM
    INT_LIST  macro    ; IntSource,   Label,   Type, ResetFlag?
            INT_Handler   CCP1_INT,  _Capture,  PBP,  yes
            INT_Handler   TMR1_INT,  _Timer1,   PBP,  yes
        endm
        INT_CREATE               ; Creates the High Priority interrupt processor
    ENDASM
    
    CCP1CON = %00000101  ' Capture mode, capture on rising edge
    T1CON = 0            ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
    @    INT_ENABLE  CCP1_INT    ; enable Capture interrupts
    
    Main:    
        IF T1CON.0 = 0 THEN ' If done, show result
          DEBUG "Timer Overflows = ",DEC OverFlows
          DEBUG " Remaining ticks = ",dec Remainder,13,10
        ENDIF
        PAUSE 2000
        @    INT_ENABLE  CCP1_INT     ; Start new capture
        GOTO Main
    
    '---[CCP1 - interrupt handler]------------------------------------------
    Capture:
       IF CCP1CON = %00000101 THEN     ' If rising edge capture then
         TMR1L = 0                     ' Clear Timer1 counts
         TMR1H = 0
         T1CON.0 = 1                   ' Turn Timer1 on at rising edge capture
         OverFlows = 0                 ' Clear over flow counts
         Remainder = 0                 ' Clear remainder
         CCP1CON = %00000100           ; Switch to falling edge capture
         PIR1.0 = 0                    ; Clear Timer1 overflow flag before enable
         @    INT_ENABLE  TMR1_INT     ; Enable Timer 1 Interrupts 
         GOTO OVER_CCP                 ; Done, exit
       ENDIF
       
       IF CCP1CON = %00000100 THEN     ; If falling edge capture then
         T1CON.0 = 0                   ; Stop Timer1
         CCP1CON = %00000101           ; Switch back to rising edge capture
         @    INT_DISABLE  TMR1_INT    ; Disable Timer 1 Interrupts
         @    INT_DISABLE  CCP1_INT    ; Disable CCP1 Interrupts
         Remainder.LowByte = TMR1L     ; Get remaining Timer1 counts on falling edge
         Remainder.HighByte = TMR1H
       ENDIF
    OVER_CCP:
    @ INT_RETURN
    
    '---[TMR1 - interrupt handler]---------------------------------------------
    Timer1:
        OverFlows = OverFlows + 1
    @ INT_RETURN
    
         END
    Input for testing was a 2nd PIC providing a 30mS pulse followed by a 1000mS
    pulse with a 5 second delay between each.

    For the 30mS pulse it displays: Timer Overflows = 2 Remaining ticks = 19048

    The total pulse width: (2 * 65536 * 200nS) + (19048 * 200nS) = 30.0242mS

    For the 1000mS pulse: Timer Overflows = 76 Remaining ticks = 19480
    So: (76 * 65536 * 200nS) + (19480 * 200nS) = 1.0000432 S

    Darrels interrupt routines are pretty handy.
    Last edited by Bruce; - 20th July 2006 at 16:47.
    Regards,

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

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


    Did you find this post helpful? Yes | No

    Default

    And then there's the old fashioned way..;o}
    Code:
    ' PIC18F242 @20MHz
    DEFINE OSC 20
    DEFINE INTHAND Capture   ' Context saving for High Priority Ints
    DEFINE DEBUG_REG PORTC
    DEFINE DEBUG_BIT 6 
    DEFINE DEBUG_BAUD 115200
    DEFINE DEBUG_MODE 0      ' 1 = inverted, 0 = true
    
    OverFlows  VAR BYTE BANKA SYSTEM ' Timer1 overflow total
    Remainder  VAR WORD BANKA SYSTEM ' Remaining Timer1 ticks after falling edge capture
    Ready      VAR BYTE BANKA SYSTEM ' Indicates pulse width measurement is complete when 1
    Ready = 0
    
    ReStart:
        CCP1CON = %00000101  ' Capture mode, capture on rising edge
        T1CON = 0            ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
        RCON.7 = 1           ' Enable priority interrupts
        PIE1.0 = 0           ' Disable Timer1 over flow interrupt
        PIE1.2 = 1           ' Enable CCP1 interrupt
        PIR1 = 0             ' Clear any pending interrupt flags
        PIR2 = 0             ' before enabling global
        INTCON.7 = 1         ' Enable all unmasked interrupts
    
    Main:    
        WHILE !Ready         ' While not ready, wait
        ' Do other stuff here if needed
        WEND
        
        ' Result is ready
        DEBUG "Timer Overflows = ",DEC OverFlows
        DEBUG "Remaining ticks = ",DEC Remainder,13,10
        Ready = 0
        
        PAUSE 2000
        GOTO ReStart
    
    '---[CCP1 & Timer1 - interrupt handler]------------------------------------------
    ASM
    Capture
        btfsc PIR1,TMR1IF         ; Timer1 interrupt?
        bra   T1_Int              ; Yes. Goto T1_Int
        bcf   PIR1,CCP1IF         ; No it's a capture int so clear capture int flag
        btfss CCP1CON,0           ; Rising edge capture?
        bra   FallingEdge         ; No. Skip to falling edge capture
        clrf  TMR1H               ; Yes. Clear high count
        clrf  TMR1L               ; Clear low count
        bsf   T1CON,0             ; Turn Timer1 on at rising edge capture
        clrf  OverFlows           ; Clear over flow count
        clrf  Remainder           ; Clear remainder count
        bcf   PIE1,CCP1IE         ; Disable capture interrupt before switching
        bcf   CCP1CON,0           ; Switch to falling edge capture
        bcf   PIR1,0              ; Clear Timer1 overflow flag before enable
        bsf   PIE1,TMR1IE         ; Enable Timer1 Interrupt
        bsf   PIE1,CCP1IE         ; Re-enable capture interrupt
        bra   OVER_CCP            ; Done, exit
        
    T1_Int
        bcf   PIR1,TMR1IF         ; Clear Timer1 overflow flag
        incf  OverFlows,f         ; Increment over flow count
        bra   OVER_CCP            ; Done, exit
           
    FallingEdge
        bcf   T1CON,0             ; Stop Timer1
        bcf   PIE1,CCP1IE         ; Disable CCP1 interrupt
        bcf   PIE1,TMR1IE         ; Disable Timer1 interrupt
        bsf   CCP1CON,0           ; Switch back to rising edge capture
        movff TMR1L, Remainder    ; Get low byte on falling edge
        movff TMR1H, Remainder+1  ; Get high byte
        bsf   Ready,0             ; Indicate process is complete
     
    OVER_CCP
        retfie fast               ; Done, return
    ENDASM
    
         END
    Last edited by Bruce; - 20th July 2006 at 19:10.
    Regards,

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

  3. #3
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Re: mS Timer

    Hi All,

    Working through a similar issue trying to time a couple of events and looking for some clarification.
    In this explanation, and in the tips and tricks there is this line:

    "2. Setup Timer1 so it will not overflow during max pulse width time".

    Yet the amount of overflows is how you're measuring the pulse. What am I overlooking here, and why mention that?

    I'm on a 12F683 and have been trying to use GPC_INT (Interupt on change) to do this, while keeping within one cycle of TMR1 and it has limitations. Using the overflow count and remainder looks like a much better idea. I'm going to crank through it that way and see if it solves my problem, I am just confused about that line.

    Thanks
    bo

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,705


    Did you find this post helpful? Yes | No

    Default Re: mS Timer

    that post has two separate methods , one measures the pulse width with timer counts the other by timer overflows
    Warning I'm not a teacher

  5. #5
    Join Date
    Feb 2008
    Location
    Michigan, USA
    Posts
    231


    Did you find this post helpful? Yes | No

    Default Re: mS Timer

    Thank you Richard, I have few arenas that bring out self doubt as quickly as trying to muscle one of these little buggers.
    I almost have it rewritten using this scheme. I hope to test it when I get back to the shop.
    bo

Similar Threads

  1. Elapsed Timer Demo
    By Darrel Taylor in forum Code Examples
    Replies: 111
    Last Post: - 29th October 2012, 18:39
  2. High Resolution Timer & Speed Calculator
    By WOZZY-2010 in forum Code Examples
    Replies: 4
    Last Post: - 7th February 2010, 17:45
  3. Timer + rc5
    By naga in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 19th November 2009, 08:56
  4. Timer interrupt frequency
    By Samoele in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 18th January 2009, 00:49
  5. timer interupt help 16f73
    By EDWARD in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 3rd July 2005, 09:41

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