Elapsed Timer findings


+ Reply to Thread
Results 1 to 40 of 48

Hybrid View

  1. #1
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: Elapsed Timer findings

    Actually, it really looks like DT's "Elapsed_INT-18.bas" file in his T_Elapsed-18 project which uses DT_INTS-18 for 18F PICs.
    That is where I got the inspiration for my version of the 1ms Elapsed Timer Demo for DT_INTS-14 and I posted in the separate thread in the Code Examples forum.
    Regards,
    TABSoft

  2. #2
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    1 out of 1 members found this post helpful. Did you find this post helpful? Yes | No

    Default Re: Elapsed Timer findings

    I would like to provide a follow up to the discussion in this thread regarding Darrel Taylor's Elapsed Timer demo application.

    The Elasped Timer demo we are speaking of is a project that Darrel had posted here and on his website.
    The Project was called Elapsed_Demo.bas (code dated Jan 10, 2006) and also had the following include files.
    INCLUDE "DT_INTS-14.bas"
    INCLUDE "ReEnterPBP.bas"
    INCLUDE "Elapsed_INT.bas"

    The issue is within the "Elapsed_INT.bas" include file where Darrel provided hard-coded values for the "TimerConst" variable for Oscillator rates of 4/8/10/16/20 MHz.
    It is these hard-coded values that are incorrect.
    Code:
    Relevant section of Elapsed_INT.bas:
    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 == 16
    TimerConst = 063C7h
      EndIF
      If OSC == 20
    TimerConst = 03CB7h
      EndIF
    As Art had pointed out a little earlier in this thread, and we have confirmed through code review and testing, Darrel's hard-coded values he used for the Timer1 Preload values (TimerConst) for a 10ms (100Hz) Interrupt were incorrect.

    The value he used for each of the Oscillator rates is (1) less than it should be.
    The reason is that he calculated the Timer1 counter overflow value as 65535 instead of using 65536.
    Timer1 is a 16bit counter from 0 to 65535.
    It takes 65536 counts to overflow (Wrap back to 0) and trigger the Timer1 interrupt.
    This means that his 10ms interrupt will actually run longer by (1) instruction than it should.

    As an example of the wrong value used, for a 4MHz Oscillator rate the interrupt will fire at 10ms + 1 instruction cycle (1us).
    Darrel's Preload value (TimerConst) was hard-coded to 0D8F7h (55543 dec), which is incorrect and it should be 0DF8h (55544 dec)

    For those interested, here is the math.

    When using a Timer1 Interrupt without any prescale or postscale values, Timer1's counter will increment by 1 for each instruction executed.
    Each instruction takes (1 / (Fosc / 4)) amount of time.
    So for a 4Mhz Oscillator rate, 1 instruction cycle (Tcy) = 1 / (4000000 / 4) = 1 / 1000000 = .000001 seconds (1us).

    Darrel calculated the preload value (number to preset the counter to) this way.
    Tpl = 65535 - (It / (1 / (Fosc / 4)) - Tric)

    Where:
    Tpl = Timer Preload value
    65535 = Timer1 Counter Overflow value (Which is wrong, should be 65536)
    Fosc = OSC Frequency
    It = Target Interrupt Time
    Tric = Timer Reload Instruction Cycles

    So for the 4MHz Oscillator rate example:
    Tpl = 65535 - (.01 / (1 / (4000000 / 4)) - 8)
    Tpl = 65535 - (.01 / (1 / (1000000)) -8)
    Tpl = 65535 - (.01 / (.000001) - 8)
    Tpl = 65535 - (10000 – 8)
    Tpl = 65535 - 9992
    Tpl = 55543 (D8F7h)

    This will load 55543 into Timer1's counter.
    Now how many counts does it take for Timer1 to overflow from here?
    If your target is a 10ms interrupt and the Instruction Cycle time is 1us, then you want it to count exactly 10000 instructions including the instructions it uses when it reloads the Timer preset (which the code does in 8 instructions).
    So starting at 55543 + (10000-8) = 55543 + 9992 = 65535

    Timer1's counter is now at 65535 and it will not overflow until 1 more instruction occurs.

    So this 4MHz example shows that the Timer1 interrupt will fire at 10.001ms not 10ms.

    Even though the error is just 1 instruction cycle, the timing impact could be significant.
    The timing error is inversely proportional to the Oscillator rate.
    The slower the Oscillator rate, the worse the timing will be off.

    And as Art pointed out the error is cumulative.
    Every time the interrupt fires, 1 extra instruction is executed, so if the interrupt fires 10 times the total elapsed time for the 4MHz example would be 10.010ms instead of the correct 10ms.

    I hope this clarifies Art's observations and our subsequent findings.
    Last edited by Tabsoft; - 20th May 2015 at 14:45. Reason: Grammatical Issue
    Regards,
    TABSoft

  3. #3
    Join Date
    Nov 2007
    Location
    West Covina, CA
    Posts
    219


    Did you find this post helpful? Yes | No

    Thumbs up Re: Elapsed Timer findings

    Excellent tutorial Tabsoft.
    Explains why I always had to "fine tune" after the fact when setting up a timer.
    Louie

  4. #4
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Elapsed Timer findings

    Ok I was thinking where you said you made the PWM to measure on a scope,
    so had my best go at that sitting here rather than scab the code
    Probably not the most effective with memory or time, but I think the frequency will be correct.
    and it’s probably also more like asm pseudo code at the moment.

    Code:
    ‘start of code somewhere:
    ‘
    flipflip var byte
    
    
    ‘in ISR straight after Ticks is incremented
    ‘
    @ btfsc flipflop ,00 		; 1/2
    @ goto aaaa			; 2
    @ goto bbbb			; 2
    aaaa:				‘
    @ bsf portb, 07			; 1
    @ goto overpwm			; 2
    bbbb:				‘
    @ nop				; 1
    @ bcf portb, 07			; 1
    overpwm:			‘
    @ comf flipflop 		; 1 - but timing doesn’t matter here
    
    ‘instruction time 6 for flip state, 6 for flop state,
    ‘7 for the code to execute no matter the status
    I like the idea the PWM is almost free if you wanted it,
    and there might be a situation you’d want the electrical frequency of the timer.

    It might not have originally been obvious I was setting this up for a pic.. only works up to 20MHz though:
    Code:
    '$FFFF - (((20 / 4) * 10000) - 8) = $3CB7
    ‘might as well fix the constant val too
    
    constval = $FFFF - (((f/4)*10000-7)'
    Though I have not needed to, it’s pointless unless you are varying the pic’s oscillator frequency,
    and also telling the pic program the new osc frequency, or figuring out some other way what frequency the pic is running at.
    That PWM would indicate resolution error at runtime for different osc frequencies.
    Last edited by Art; - 20th May 2015 at 16:02.

  5. #5
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: Elapsed Timer findings

    Very similar to what I did.
    I used the Elapsed Timer to generate a 1KHz 50% duty cycle signal on PORTA.4.
    I wanted to test the stability of the Timer1 interrupt period using the Elapsed Timer code we have been discussing.

    In the ISR I used a call to the RELOAD_TIMER macro after setting the state of the pin.
    That lets the Elapsed Timer code handle things and I could check the accuracy of the output.

    I was lazy though and did not setup a variable to track the state of the pin.
    I just read the port and flipped the pin.
    This was a test and I really didn't mind if I hit the other pins on PORTA.

    500ms Timer1 ISR:
    Code:
            asm
                COMF PORTA, 0   ; 1 Tcy - Complement PORTA, Store in W
                ANDLW 10h         ; 1 Tcy - Force all PORTA pins to 0 except pin 4 
                MOVWF PORTA    ; 1 Tcy - Set the new value for PORTA
                RELOAD_TIMER    ;  Reload the timer
            endasm
    Last edited by Tabsoft; - 20th May 2015 at 16:20. Reason: Additional Info
    Regards,
    TABSoft

  6. #6
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Elapsed Timer findings

    There’s some fun to be had. It would be possible to rotate a byte with any value in it
    and look at the value of a bit in that byte to get some more free frequency divisions.
    Or if you had a 100Hz timer and wanted a 1Hz pulse, you could do similar to the timer code,
    load a constant value to a byte, increment it, and watch for one of the more significant bits to be set.

Similar Threads

  1. Elapsed Timer Demo
    By Darrel Taylor in forum Code Examples
    Replies: 111
    Last Post: - 29th October 2012, 17:39
  2. SPWM and Elapsed Timer
    By CocaColaKid in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 8th May 2008, 03:16
  3. Darrel Taylor Elapsed Timer
    By rwskinner in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 13th March 2008, 01:22
  4. DT Elapsed Timer
    By rwskinner in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 9th March 2008, 23:17

Members who have read this thread : 9

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