Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Better way to implement variable time delays

Status
Not open for further replies.

carbonzit

Active Member
In another thread ("Relocatable code") someone (Mr RB, actually) proposed this method of generating delays using a delay subroutine:

Code:
  movlw 230
delay_2point3
   call delay_10mS
   sublw 1
   btfss STATUS,C
   goto delay_2point3

While this will definitely work, there is what I believe is a better way: easier and less code.

What I've done is to create a delay routine that uses a variable, set before being called, as a loop count to control the delay length. So instead of looping in the code, as in Roman's method, all you do is load the variable with the desired delay length value, then call the routine.

Here's my code in SX-28 assembly language: my apologies if this isn't familiar, but it's similar enough to PIC code to be understandable, hopefully. (The SX uses "skip"-type branches instead of the more familiar conditional jumps.) First, the delay subroutine:

Code:
;*******************************************************
; Short delay subroutine (~40-255 usec)
;
; On entry:
;	W = 256-count to delay (in microseconds)
;
; This routine waits for the flag bit set by the ISR (when the
; RTCC rolls over) to go high.
;*******************************************************

ShortDelay
	MOV	RTCC_FR, W		;Load RTCC
	CLRB	Flag.FLAG_RTCC		;Clear rollover flag bit
dloop	SB	Flag.FLAG_RTCC		;Has bit been set yet?
	JMP	dloop			;No, keep checking
	RET				;Yes, return.

Next, here's how you invoke it:

Code:
	MOV	W, #DELAY_40uS
	CALL	ShortDelay

See how easy that is?

I should point out that the way this works is a little indirect with this processor, since the delay routine loads the delay value into a system register, the RTCC (real-time clock counter) which gets decremented in an interrupt service routine (ISR); however, you could use this same scheme by simply decrementing the variable and checking for zero directly in the subroutine.

Now, because of the limit of the maximum value of a variable and the "atomic delay unit" (i.e., the shortest delay possible, if you set the delay variable to 1), I found I had to create both short delay and long delay routines. Still very simple to implement and use.

I like stuff like this, since I'm kind of a fanatic about making code as compact and fast as possible ...
 
hi cz,
Isn't that the way most 'pro' programmers preload and call a delay loop.????
 
There really seems little advantage to it, just a 'need' to use hardware when there's no need.

The advantages of simple loops are that they have better precision, and they aren't limited to specific hardware facilities.

Well, just to be clear, my suggestion has nothing to do with the actual method used to derive the delay: that could be polling a hardware-controlled value, as in my example, or just a simple loop. The point I was trying to make is that it's easier to put the delay, however it's implemented, into a subroutine, controlled by a single variable (in a register or memory), which only requires setting that value and then calling the routine, as opposed to putting loops in the code in-line, as suggested by Mr RB.
 
I suggested that code to a person without knowing his skill level, and it was chosen to be very simple to understand (and also use no RAM resources). :)

Generally it is better to use a dedicated function and load the desired delay value in a RAM register (on in W which is better as it uses no RAM).
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top