Methods of delays (18F PIC)

Discussion in 'Embedded Systems and Microcontrollers' started by HarG, Nov 21, 2012.

  1. HarG

    Thread Starter New Member

    Nov 20, 2012
    18
    0
    Does anyone have any links/info on how to use delays (such as __delay_ms()) and on-chip timers (e.g. timer 0). I think the main question I have is when is best to use each one.

    For example which would be better for a small delay in an 'if' statement for debouncing a switch.


    Thanks for any help
     
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    Essentially, both would do the same thing while you are polling the timer. However, a timer can be configured to generate and interrupt after a delay, which can free up your processor in the mean time to do other things...
     
  3. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,015
    For using a delay, tt is going to depend on what compiler your are using and what mcu.

    The best one is one that suits your needs. If you don't care if the code "stops" then a call to a delay function is the easiest way to go. If you want your mcu to do other stuff while delaying then you might want to use a timer.
     
  4. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    You can still poll a timer... you'd need to configure for interrupts...
     
  5. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,015
    If you are polling a timer then there is no need to configure interrupts (better to have the interrupt just set a flag) or visa versa.
     
  6. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    I suppose I should have stated that clearer:p

    What I meant to say was that you can poll a timer and still block the processor function.
    You would have to use interrupts otherwise...
     
  7. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,015
    Yes I agree but not sure why you would want to poll then. You could poll in a loop say do stuff for 10ms. That would make sense to poll the timer.
     
  8. HarG

    Thread Starter New Member

    Nov 20, 2012
    18
    0
    Thanks guys thats really helpful.
     
  9. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    If you use the Hi-Tech C compiler or XC8 compiler you can use the __dealy_ms() and __delay_us() functions
     
  10. tshuck

    Well-Known Member

    Oct 18, 2012
    3,531
    675
    I do believe the OP knew that, considering the use of that exact function in the first post :p
     
  11. HarG

    Thread Starter New Member

    Nov 20, 2012
    18
    0
    Really I'm just a bit paranoid about getting bad practices etc but I'm sure I will just establish with trial and error which method is suitable for each problem.


    Thanks
     
  12. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Interrupt routines, LED example, can be changed to debounce

    C Routine, polled, very cycle intensive for little gain

    I usually use hardware debouncing, either a small R/C Circuit, or, rarely, a Debouncing IC. Having a controller continually polling for a key press means it cannot go to sleep/low power mode (unless you use a wake on interrupt).

    The downside of polled debouncing is that a lot of cycles will be looking for an input that doesn't exist. From controller speed views, button presses are relatively rare event, compared to how fast the actual "work" of the processor needs to be completed.

    If out of interrupts and timers, I'd suggest simply letting the rest of the code be your delay, in other words, call the button test routine once for every other time the program makes a loop (toggle a flag bit, then test it).

    The button will still be checked several hundred thousand times per second (or more), but less overhead is used looking for it. This is a crude implementation of multitasking, and due to the speeds controllers run at, humans are not going to notice the delay unless your main procedure uses the evil delay_xx functions, try to learn/use timer interrupts to minimize delay calls.
     
  13. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Timers have a number of advantages, code ROM size is usually smaller (especially on larger delays) as you just clear the timer then wait until timer>X, which also uses no RAM.

    Timers are more accurate for repeated periods like testing something every X uS as the overhead "fluff" like calls/returns and decision making branching etc won't affect the timer, this is why you use timers to make 1 second delays in a clock, or make a repeated baud delay in a manual serial transmitter etc.

    And an important benefit of timers is that your code can be doing stuff DURING the delay, so you can do this;
    1. clear timer
    2. do stuff (anything that takes less than 1mS)
    3. if timer <1mS goto 3
    which lets you do a long task(s) during the delay,

    or this;
    1. clear timer
    2. do stuff (anything that is fast, like checking buttons)
    3. if timer <1mS goto 2
    which lets you keep checking fast things for the entire delay period.

    I suggest you learn to use the timers they are very powerful, and as a general rule using the timers will give you better accuracy and less ROM/RAM used.
     
  14. atferrari

    AAC Fanatic!

    Jan 6, 2004
    2,648
    764
    To explain how I do debouncing please read about how I do delays in PIC micros, working in Assembler. It is based on a suggestion in the Microchip forum many years ago:

    Except when starting the LCD module, most of the delays (if not all) used in the different tasks, progress "in parallel" with the main loop code.

    A specific delay starts when its own counter is loadey with a >0 value and is materialized in the time it takes a repetitive "decrement until =0" of it. The decrement is done in an ad hoc routine called from inside the main loop.

    The counter for each delay, is defined beforehand.

    There is the ISR in charge (triggered by the overflow of Timer 2), setting the pace with a time base ticking every 5 msec, and setting every time, a "time base elapsed" flag.

    The decrement routine, when finds that flag set, decrements all non =0 counters.

    When a counter reaches =0 it stays like that forever unless reloaded with a new value (>0) somewhere inside the code.

    This is the main loop of an application running on my bench right now:

    Code ( (Unknown Language)):
    1. MAIN_LOOP
    2.   CALL DECR_COUNTERS
    3.   CALL READ_KEYB
    4.   BRA MAIN_LOOP
    Now for the debouncing:

    The keyboard matrix is read for the first time. If a key is pressed, "key-active" is flagged and the debounce counter loaded with 8. (8*5 = 40 msec)

    Every time it is called, the decrement routine will check the flag from the ISR indicating a tick's time elapsed. If so, every counter (>0) will be decremented.

    Meantime, every time it was called, the keyboard reading routine has checked the key-active flag which is set but did nothing because the debounce counter was not =0 yet.

    Once the routine finds the key-active flag set AND the debounce counter =0 it goes to the second reading. If both readings match, that is a valid key.

    Additional comments:

    The first time I realized how I could use this concept of delays based on counters, I implemented 8 LEDs going ON and OFF in the most arbitrary and complicated patterns whether a continuous blink, randomly or at the push of buttons. The beauty of it: just load a register with a value and away it goes.

    I built some years ago an inteligent alarm panel. Using the sopwatch I timed how long it took to sense all inputs. Even using a high number of counters (for delays) it worked quite under the maximum time allowed.

    Few days ago, prior writing the code running right now, I revisited the whole thing. Besides a tidy up of the formatting, found good to leave it as is.
     
    Last edited: Nov 23, 2012
  15. HarG

    Thread Starter New Member

    Nov 20, 2012
    18
    0
    Thank you for your replies, especially the level of detail. It makes understanding these concepts far easier when reading about them in a non-formal context.
     
Loading...