# Calculating delays for a microcontroller...

#### AceOfHearts

##### New Member
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
This is among the reasons for not implementing delay in this fashion. Good programmers seldom resort to this kind of nonsense.

#### mcs51mc

##### Member
1) You forgot the MOV instructions, once in a while, in your calculation!
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?

#### Papabravo

##### Well-Known Member
Absolutely spot on.

#### MrJammin

##### New Member
mcs51mc, can you explain what you mean by this line:
"Use T0 as a 10ms auto reload timer"

#### Eng.Remon

##### New Member
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
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.

#### mcs51mc

##### Member
I'm sorry if I confused anyone here

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
Thanks for that contribution. Nothing reeks of clarity like a simple piece of code.

#### kinjalgp

##### Active Member
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

• 69.1 KB Views: 11,017

#### AceOfHearts

##### New Member

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!

#### keanhong2

##### New Member
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

• 7.6 KB Views: 429
Last edited:

#### keanhong2

##### New Member
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:

#### keanhong2

##### New Member
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:

#### mcs51mc

##### Member
Dear keanhong2,

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

#### keanhong2

##### New Member
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:

#### mcs51mc

##### Member
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.

#### keanhong2

##### New Member
i appreciate ur comment thanks . last question i still not understand 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 ?

#### mcs51mc

##### Member
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.

#### keanhong2

##### New Member
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: