• 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.

Calculating delays for a microcontroller...

Thread starter #1
Peace,

Here is a common delay loop in assembly language:

DELAY: MOV R5, #7
HERE1: MOV R4, #255
HERE2: MOV R3, #255
HERE3: DJNZ R3, HERE3
DJNZ R4, HERE2
DJNZ R5, HERE1
RET

Let us assume the crystal frequecy is 11.0592MHz. 8051 uses 1/12 of oscilator frequency, which is 921.6kHz

Each oscilator cycle's time period becomes 1/f = 1/921.6kHz = 1.085uS

If we follow through the above loop, and if I understood correct, then the total time spent in the DELAY loop above is as follows:

255 + (255 * 255) + (255 * 255 * 7) * 1.085uS = 0.56S

HOWEVER, looking at a datasheet, i can see that the 8051 spends two cycles per DJNZ mnemonic, not one as I am assuming.

This will drastically affect the anticipated delay calculation.

Any input?

Thanks
 

Papabravo

Well-Known Member
#2
This is among the reasons for not implementing delay in this fashion. Good programmers seldom resort to this kind of nonsense.
 
#3
1) You forgot the MOV instructions, once in a while, in your calculation!
2) Read datasheet first instead of assuming things!
3) How I do delays?

Use T0 as a 10ms auto reload timer
Declare 1 RAM byte "Delay"
In the ISR of T0 decrement "Delay" when it's > 0
In your main code check "Delay", as long as it's > 0 your delay is still on
When you need a delay of let say 1870ms load 187 into "Delay"
That way you can make any delay in 10ms increment

Note that you still can use T0 for other 10ms timed things.

Is that good practice Papabravo?
 
#5
mcs51mc, can you explain what you mean by this line:
"Use T0 as a 10ms auto reload timer"
I couldn't follow what you were talking about.
 
#6
u should read about timers in mode 2 that gona help u to understand the auto reload timer .u will find th & tl Reg which contain the number of delay the tf will be setted on. u have to read to understand it correctly.
 

Papabravo

Well-Known Member
#7
Timer 0, also called T0, is a free running counter. It counts clock pulses. You can program it for a fixed interval by knowing how many clock pulses it takes to equal that interval. Auto-Reload simply means that when Timer 0 reaches it's terminal count(zero in the case of T0), it will automatically be loaded with the correct value to begin a new timing interval. It will also set an interrupt flag if you wish to do additional processing when the counter overflows.
 
#8
I'm sorry if I confused anyone here :eek:

When I wrote "Use T0 as a 10ms auto reload timer"
I ment: "16 bit timer" (mode 1)

Sorry again, my mistake :(
But the principle remain the same :)

code for you main prgm
Code:
Time_0      EQU   55535

mov  TH0,#HIGH Time_0	;set-up T0
mov  TL0,#LOW  Time_0
mov  TMOD,#01H               ;T0 mode 1
setb ET0                          ;enable interrupt T0
setb EA
setb TR0                          ;start T0
Code for the ISR of T0
Code:
ISR_T0:       mov  th0,#High Time_0		;Reload timer
                  mov  tl0,#Low  Time_0
;
;Do all you other timed stuff here
;
LBL_Delay:   mov  a,Delay                 	;Delay X * 10 ms 
	    setb c                          ;X managed by main prgm
	    subb a,#0
	    jc   LBL_Delay_End
	    dec  Delay                    ;Delay = Delay - 1 when > 0
LBL_Delay_End:
Hope it's clear now :)
 

Papabravo

Well-Known Member
#9
Thanks for that contribution. Nothing reeks of clarity like a simple piece of code.
 

kinjalgp

Active Member
#10
Software like DcWin can save you from burden of calculating delays yourself.
I don't remember from where I downloaded it so I am attaching my copy.
 

Attachments

Thread starter #11
Thanks for all your suggestions.

I have switched to using the Timers as a means to measure delays.

I am finding it much neater and easier to use.

Thanks again!
 
#12
i suggest use this one better to understand and easy

total delay time is 0.1024 second because 256 X 200 X 2us =0.1024 sec.

below is a subroutine program :-
Code:
DELAY : MOV R0,#00      ; load R0 with # 00 = 256 is maximum number 
	MOV R1,#200    ;load R1 with 200 
LOOP  : DJNZ R0,LOOP  ; loop it self R0 256 times
	DJNZ R1,LOOP  ;loop R0 and R1 it self R0=256 , R1=200 ,200X256=51200 times 
	RET
 

Attachments

Last edited:
#13
Subroutine of assembly language

if u want longer delay time just ADD R2 total delay time 256 X 256 X 200 X 2us =26.2144 second
Code:
DELAY : MOV R0,#00      ; load R0 with # 00 = 256 is maximum number 
	MOV R1,#00    ;load R1 with 256 
        MOV R2,#200  ;LOAD R2 WITH 200
LOOP  : DJNZ R0,LOOP  ; loop it self R0 256 times
	DJNZ R1,LOOP  ;loop R0 and R1 it self R0=256 , R1=256 ,256X256=65536 times 
        DJNZ R2,LOOP; 256X256X200 = 13107200 TIMES 
	RET
 
Last edited:
#14
change r2 value to specify delay time u need

change r2 value if
r2 = #152 , total delay time is 152 X 256 X 256 X 2us =19.922944 sec =20 sec .
r2 = # 77 = 10.92544 second .
just take a calculator to calculate the time u want
formula as below:

Code:
r2 X 256 x 256 X 2 us = total delay time .



just replace r2 with a value not more then 255 , and if u want 256 put 0
 
Last edited:
#15
Dear keanhong2,

It's a pitty to reopen such old thread for such bad, very, very very bad code :(

Do you realize what you are doing?
Let me tell you: YOU HANG YOUR µCONTROLLER and that's something you NEVER, NEVER should do!!!!!

So please check the code I posted, try to understand it, then use it at your convenience and, if you have any further questions, let us know :)

Best Regards
mcs51mc
 
#16
I just share and welcome to yours to discuss about my code shown .

below are example of running light output to p1 and p2

Code:
	ORG 0000H
	MOV A ,#11111110B
START : MOV P1,A
	MOV P2,A
	MOV R2,#5
	CALL DELAY
	RL A
	JMP START
DELAY : MOV R0,#00
	MOV R1,#200
LOOP  : DJNZ R0,LOOP
	DJNZ R1,LOOP
	DJNZ R2,DELAY
	RET
	END
this LED run from right to left delay each change is 0.5 sec . i will appreciate if u comment to my code.
 
Last edited:
#17
My previous post on your code was a little raw, maybe a little crude :) so that you will keep in mind to never, never use time delay's in such way in the future since you hang the µC.
So, to fool around with some led's it's ok but now try the same functionality with the Timer0 from the µC, that's the way to go.
 
#18
i appreciate ur comment thanks .:) last question i still not understand:confused: why it will hang lecture tell that this code is use for loop it self for delay , or maybe i haven't graduate i don't understand i take diploma.i study the data-sheet atmel 89s52 have build in a 2 timer function is that u use that time as delay ? and why my code hang uc ?
 
#19
As long as the µC loops in your delay code
Code:
DELAY : MOV R0,#00
	MOV R1,#200
LOOP  : DJNZ R0,LOOP
	DJNZ R1,LOOP
	DJNZ R2,DELAY
it does nothing else.
No check of inputs, no control of outputs, no control of LCD, ... ... ... nothing except decrementing some registers.

If your project has some push buttons, the µC will never detect that the user pressed a button during your delay code.
When later on you will use interrupts, be aware that this timing will fail since an ISR (interrupt service routine) can interrupt your delay.
So that's why I said that you "hang" your µC during tour delay.
 
#20
What mean $ ?

mcs51mc i want to ask u a question ?
Code:
; Delay routine
Delay: 
	mov	R0,#1		; 1
D1:
	mov	R1,#16		; 1

D2:
	mov	R2,#29		; 1 
	djnz	R2,$		; 2
	nop			; 1
	djnz	R1,D2		; 2
	djnz	R0,D1		; 2
	ret
What is that $ mean ??
 
Last edited:

Latest threads

EE World Online Articles

Loading

 
Top