Elapsed Timer Demo


Closed Thread
Results 1 to 40 of 112

Hybrid View

  1. #1
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default Elapsed Timer Demo

    Elapsed Timer Demo

    Attached to this post is a Zip file that contains a "Drop-In" elapsed timer that uses Timer1 and interrupts. It's waaay down there at the bottom of all this dribble. This may get rather long winded, so my first suggestion is to scroll down to the bottom of this post and check out the file then come back and read this post later.

    --------------------- ----------------------- -----------------------------
    The files contained in the Zip are:

    Test_Elapsed_SER.pbp ' Demo of Elapsed Timer using serout2 command and HyperTerminal
    Test_Elapsed_LCD.pbp ' Demo of Elapsed Timer using an LCD
    Elapsed.bas ' Elapsed Timer include file
    ASM_INTS.bas ' Assembly language Interrupt Stubs

    Note: These files are intended to be used on 14-bit core PICS (12F, 16C and 16F) that have a TIMER1 module.
    Note2: They are written for use as the only interrupt in the program. If you need to use other interrupts as well, the program will have to be modified before it will work.
    Note3: It will NEVER work in conjunction with PBP's ON INTERRUPT statement.

    In it's simplest form, this is all it takes to use the Elapsed Timer:
    Code:
        Include "Elapsed.pbp"
        Gosub ResetTime    ' Reset Time to  0d-00:00:00.00
        Gosub StartTimer   ' Start the Elapsed Timer
    This will create a Clock counting at 1/100 seconds. It runs in the background of PBP without any other program intervention required.

    The time is kept in the variables:
    Code:
        Ticks    var byte   ' 1/100th of a second
        Seconds  var byte   ' 0-59
        Minutes  var byte   ' 0-59
        Hours    var byte   ' 0-23
        Days     var word   ' 0-65535
    The time can be easily displayed with a single line:
    Code:
        LCDout $FE,2, dec Days,"d-",dec2 Hours,":",dec2 Minutes,":",dec2 Seconds
    For each of the variables (Seconds, Minutes, Hours and Days) there is a flag that indicates when the value of that variable has changed.
    The Flags are:
    Code:
        SecondsChanged   var bit
        MinutesChanged   var bit
        HoursChanged     var bit
        DaysChanged      var bit
    So, if you wanted to display the time like a clock, you could wait until SecondsChanged = 1, display the time, then reset the flag.
    Code:
        Loop1:
            if SecondsChanged = 1 then
               LCDout $FE,2, dec Days,"d-",dec2 Hours,":",dec2 Minutes,":",dec2 Seconds
               SecondsChanged = 0
            endif
        Goto Loop1
    If you only wanted to display the time each minute instead of every second just do the same thing using the MinutesChanged flag.
    Code:
        Loop1:
            if MinutesChanged = 1 then
               LCDout $FE,2, dec Days,"d-",dec2 Hours,":",dec2 Minutes<br>           MinutesChanged = 0
            endif
        Goto Loop1
    The timer can be Stopped and Started, like a stopwatch.
    Code:
        Gosub StopTimer
        Gosub StartTimer
    --------------------- ----------------------- -----------------------------
    The Elapsed.bas include file also Includes another file, ASM_INTS.bas This file can also be used in your other programs as well. It handles the "Context Saving" that is required for any Assembly language interrupt.

    It contains 2 macros:
    INT_START
    Saves the W, STATUS, PCLATH and FSR registers. This can be used at the beginning of your Interrupt routine.

    INT_RETURN
    Restores the W, STATUS, PCLATH and FSR registers after the Interrupt routine is finished and then returns from the Interrupt (RETFIE).

    Using it in a normal Assembly language interrupt might look something like this:

    Code:
        Define  INTHAND  INT_CODE    ' Tell PBP Where the code starts on an interrupt
    ASM
    INT_CODE
        INT_START                ' Save Context
            ... Your Interrupt routine goes here ...
        INT_RETURN               ' Restore Context
    EndAsm
    Well, I guess that covers most of it. if I've missed anything, or you still have questions, please don't hesitate to ask.

    Happy holidays,
    Attached Files Attached Files
    Last edited by Darrel Taylor; - 10th June 2013 at 20:12.

  2. #2
    Bob_W's Avatar
    Bob_W Guest


    Did you find this post helpful? Yes | No

    Default

    Cool piece of code. I noticed something trying to use it..... I'm using a 12F675 at 4 mhz. I noticed that the ticks were incrementing at 1/4 the rate they were supposed to. Upon fishing around I thought about the fact that there's a 1:1, 1:2, 1:4, and 1:8 prescaler on this part, as well as many others. Forcing the prescaler off makes it count correctly. Just curious.... what part did you use when you wrote this?


    Update... Nevermind.... I had left piece of my code in place that messed with the prescaler.
    Last edited by Bob_W; - 3rd September 2005 at 22:42.

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    That's the closest thing to "Hey it works" that I've gotten after it being here almost 2 years.

    Thanks Bob!
    DT

  4. #4
    Bob_W's Avatar
    Bob_W Guest


    Did you find this post helpful? Yes | No

    Default

    Ok.... "Hey it works" Really well, I might add! A couple questions..
    In elapsed.bas you've got:
    if Ticks = 100 then
    Ticks = Ticks-100
    Is there a reason you subtract 100 instead of zeroing Ticks?

    The question arises from a little excursion I had because of of the results I got doing subtraction to detect and handle rollovers. I found out that the first section evaluates true because of the unsigned nature of the math. I wound up reversing the sections and verifying the result for the rollover test wasn't > 255. Is there a better way. Also, what's the instruction count offset between 0x10000 - ((clock_freq / 4) /100) It looks like it's 7.

    tmr is 80 Ticks sample at beginning of 500 ms interval
    Ticks is 20 Ticks value now....

    (The forum removed all my indentation, so it looks wierd)


    ms100 = ticks
    IF ms100 - tmr >= 50 THEN
    GOSUB lptoggle
    ELSE
    IF ms100 < tmr THEN
    IF (ms100 + 100) - tmr >= 50 THEN
    GOSUB lptoggle
    END IF
    END IF
    END IF
    RETURN

    lptoggle:
    Toggle 0
    RETURN

  5. #5
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Is there a reason you subtract 100 instead of zeroing Ticks?
    Not really. The original program used ON INTERRUPT, and there was a possibility that Ticks might be higher than 100 by the time it got around to calculating the time. But when I switched it over to ASM interrupts, it wasn't needed anymore. Just never changed it.

    And for the ms100 routine, I can't figure out what you're trying to do there.

    If tmr = 80 then (ms100 - tmr >= 50) will be True when ms100 is between 0-79. So the output will be toggled on every loop. Then for 80-99 the (ms100 < tmr) will never evaluate True since it's always >= 80.

    Maybe if you explained what you're trying to do, we can come up with something that'll work.
    <br>
    DT

  6. #6
    Bob_W's Avatar
    Bob_W Guest


    Did you find this post helpful? Yes | No

    Default

    Basically, I want to turn something on - like an LED (later it will actually be a 7 HP siren with a longer on and off time) for 500 ms. I go through all the decision process to decide it should be turned on. Then....

    I save the current ticks value - tmr - # of ticks at start, which is 16 for this grab.

    I turn on the port - for the test program, I'm just toggling an LED at 500 ms intervals.

    I come out of the main program loop every pass to see if I have expired my timer. Get current ticks - ms100 - we'll say I get 65 for this grab.

    Sooo... IF ms100 - tmr >= 50 THEN 65 - 16 = 49.... almost there..

    Where you run into the problem is if you grab, say 80 for tmr.

    For 500 ms to elapse, you'd have to roll over the 100 mark. So, if you try to do the test IF ms100 - tmr >= 50 THEN with tmr = 80, and ms100 = 10 it evaluates true because, under pic math 10 - 80 = 250, or 65391 if you look at all 16 bits. So I figured out that you have to test to see if ms100 (the current tick value) is less than tmr (the tick value when you started timing) and if so, add 100 to the ms100 before subtracting tmr to see if it's 50 or better elapsed.

    Sure you do timing with pause, but you can't look at change of state while you wait for pause to expire. Your timing routine makes it possible watch inputs, and manipulate and time multiple outputs at the same time.

    I used to run into this when doing timing in vbdos. Seconds was easy - if you wound up with a negative, just add 86400.

Similar Threads

  1. Instant Interrupts - Revisited
    By Darrel Taylor in forum Code Examples
    Replies: 772
    Last Post: - 17th February 2016, 22:14
  2. Get elapsed time while TIMER samples pulses
    By RodSTAR in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 27th March 2009, 16:27
  3. Elapsed Timer Demo in a PIC12F675
    By Leonardo in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 21st November 2008, 00:01
  4. Totally Baffled with Elapsed Timer
    By CocaColaKid in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 11th June 2008, 21:01
  5. Darrel Taylor Elapsed Timer
    By rwskinner in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 13th March 2008, 01:22

Members who have read this thread : 4

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