James Cameron says:
These PICs are just too fast, we often need a way to have the processor wait around for a while. A series of NOP (no operation) instructions is straightforward, but wasteful of instruction memory. A counted loop is the next common trick, because that lets us tune it.But what are some of the more exotic ways to delay?
) The Common NOP, a delay for one instruction cycle
DELAY NOP ; delay one cycle ... DELAY4 ; delay 4 cycles NOP NOP NOP NOPAdvantages: extremely simple, obvious, maintainable, scaleable.
Disadvantages: is it really there for a reason? For long delays, uses a lot of instruction memory.) The Common Loop, three times the initial value plus three
DELAY MOVLW D'95' ; 288 cycle delay MOVWF COUNTER DECFSZ COUNTER,F GOTO $-1Advantages: fairly simple, maintainable, scaleable up to 771 cycles; after that go for a nested loop.
Disadvantages: costs one file register; though there is a variant using just the W register.
) The Novel GOTO, two instruction cycles in one instruction
GOTO $+1 ; two cycle delayAdvantages: half the space of two NOPs.
Disadvantages: obscure unless commented.
) The CALL to Nowhere, four instruction cycles
ORG 0 GOTO MAIN FOUR RETURN ; four cycle delay function [...] DELAY CALL FOURAdvantages: quarter the space of four NOPs, the RETURN can be reused by other code, good use for those three bytes between the reset vector and the interrupt vector on a PIC 16F84.
Disadvantages: implementation separate from use, can look odd, uses one stack level.Scott Dattalo says:
...if you want a 4-cycle single-instruction delay: call some_return_in_your_code Of course, you run the risk of stack overflow on [some processors]
) The Double Call to Nowhere, eight or four cycles
ORG 0 GOTO MAIN EIGHT CALL FOUR FOUR RETURN [...] DELAY CALL EIGHTAdvantages: looks simple, allows various size delays to be rapidly constructed during prototyping.
Disadvantages: uses two stack levels.[ed: See the "Stack Recursive Delay" below]
) The Do Something Useful Extension to the Common Loop, five times the initial value plus three
DELAY MOVLW D'95' MOVWF COUNTER MOVF TRISM ; fetch TRIS mirror TRIS TRISB ; reapply it DECFSZ COUNTER,F GOTO $-3Advantages: good for precise delays that are no multiples of three, allows useful functionality to be placed within the delay.
Disadvantages: increased convolution of code, lower maintainability.
) The Long Delay Using Timer, more of a technique than a code fragment, set the timer, wait for it to roll over.
Advantages: immune to distortion by interrupts, easily scaled using a prescaler, even possible to tune the delay by modifying the preload value.
Disadvantages: allocates a timer.Paul B. Webster says:
I feel that many applications (real-time control, clocks) resolve to a fundamental "tick" or hierarchy thereof, often around a millisecond, which method {7} provides. Counting a thousand of these gives a second, at which point a train of countdowns (semaphores) can lead to various housekeeping actions i.e., if T1 then { T1--; if T1 == 0 then action1 };On the 1 ms "ticks" also, a debounce uses a counter which counts down from 20 (20 ms) to verify a keypress/ release. Other countdowns in ms are used for playing tunes or "tick", "Click" or "blip" noises.
It is highly undesirable to pre-load or fiddle with the TMR0 when you are using it this way, firstly because it interferes with the prescaler in a very inconvenient fashion, and secondly as the 1 ms countdowns can be used for a 500 Hz tone while the TMR0 MSB can be copied to a port for a 1 kHz tone, bit 6 for a 2 kHz tone, etc., controlled as above in even numbers of milliseconds.
You can similarly, wait on those individual bits by polling, for sub- delays. A sub-delay on bit 3 toggling could be used to time a phase accumulator (32 kHz clock) to generate quite a complete range of square wave tones.
So, you may say that method "uses" a timer-counter, but I submit that in a well-designed application, you get an awful lot of "use" out of it!
) The Watchdog Delay, go to sleep and get woken by the watchdog.
Advantages: Uses the least amount of energy (best when running off batteries). Extremely simple technique. Can be varied by changing the WDT prescaler ratio.
Disadvantages: difficult to calibrate.
[ed: Set up a type of state machine that records where the processor should contine executing code after the reset. Make sure you clear it in your non-timed routines. Also see Using the watchdog timer to sense temperature]
) The Data EEPROM Delay, a typically 10ms delay that can be triggered by writing to data EEPROM and waiting for the interrupt.
Advantages: tests the endurance of the EEPROM.
Disadvantages: tests the endurance of the EEPROM.
See also:
Code:
;================================================================ ;= waitXX100msec -> long time delay routine (with clrwdt!) = ; Usage: ; movlw 5 ; bigger values (1..255) delay longer, except 0 is max delay (256). ; call waitXX100msec ; delay 4 + w*773 instruction cycles more than NOP. ; Change log: ; 2001-06-05:DAV: David Cary: minor modifications. ; 2001-04-04:RB: posted by Roman Black on 2001-04-04 04:06:30 AM ;================================================================ waitXX100msec movwf count_outer ; store the waiting time! (msb) loop_outer: clrf count_inner ; prepare lsb loop_inner: decfsz count_inner ; dec and loop 256 times goto loop_inner ; 1+2 inst x 256 (delay period) clrwdt ; give the dog a bone decfsz count_outer ; dec outer loop counter goto loop_outer ; 1+1+2 inst x value of count_outer ; (delay period) retlw 0 ; return ;================================================================ ; You can add a third (or fourth) loop with no effort, and ; for varying timings you can always load the inner loop ; vars with a value instead of clearing them (which=256). ; ; My personal pref with stepper motors is to set the inner ; loop value so that when initial w==256 I get the slowest ; speed I need. You then get the best speed range possible ; just by varying the initial w byte. ; -- Roman Black
Questions:
if i need to use 3 or 4 nested loops for a 5 secs delay (for example) how would I know which value (0-255) use for each of the decfsz?? Is there a formula or something ??
thanks