Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

How can I make 1 ms delay ?

Status
Not open for further replies.

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
Guys,

How can I make 1 ms second delay for 11.093Mhz crystal on AT89S52
Is this code right ?

Code:
void delay_ms(unsigned int msec)    //delay function
	{	
	 	//;
		
		unsigned int i,j;
		for(i=0;i<msec;i++);
		for(j=0;j<1110;j++);
		
     	
	}
Thanks
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
Download delay calculator and generate code for any delay value.
Delay Generator - 8052.com
Thank you for the info, I'm gonna download it and try....

---------- Post added at 14:26 ---------- Previous post was at 14:22 ----------

Download delay calculator and generate code for any delay value.
Delay Generator - 8052.com
I've tried it
Code:
; Delay Routine
Delay:
	mov	R0,#8		; 1
D1:
	mov	R1,#1		; 1

D2:
	mov	R2,#59		; 1 
	djnz	R2,$		; 2
	nop			; 1
	djnz	R1,D2		; 2
	djnz	R0,D1		; 2
	ret			; 2
;
; call into routine		; 2
;
; initial mov			; 1
;
; End of Delay - total cycles 1005
any idea on how to translate it into C ?
 

doraemon

Super Moderator
Staff member
Joined
Jun 21, 2009
Messages
1,068
Helped
273
Reputation
554
Reaction score
248
Trophy points
1,343
Location
Japan
Activity points
10,597
Hello!

You can directly use this inside your C code.
I wouldn't bother with assembler. It's not portable, and if you look at the code
in 2 or 3 months, it will not be readable anymore even if you wrote it.

Th C function above is right, it should work.
BUT: You should NEVER hard code the ms value (1110).
Instead:
#define LOOP_COUNT 1110

and then for(j = 0 ; j< LOOP_COUNT ; ++j)

Doing this, you can reuse your code on any other processor by changing the LOOP_COUNT to the
proper value.

Now one more comment: this method is one of the worst. Any micro controller has timers.
You can fire a timer, put the CPU to sleep and wait for the timer interrupt.

Dora.
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
Hello!



I wouldn't bother with assembler. It's not portable, and if you look at the code
in 2 or 3 months, it will not be readable anymore even if you wrote it.

Th C function above is right, it should work.
BUT: You should NEVER hard code the ms value (1110).
Instead:
#define LOOP_COUNT 1110

and then for(j = 0 ; j< LOOP_COUNT ; ++j)

Doing this, you can reuse your code on any other processor by changing the LOOP_COUNT to the
proper value.

Now one more comment: this method is one of the worst. Any micro controller has timers.
You can fire a timer, put the CPU to sleep and wait for the timer interrupt.

Dora.
thank you for the advice,
how can I use the timer, do you have idea ?
 

doraemon

Super Moderator
Staff member
Joined
Jun 21, 2009
Messages
1,068
Helped
273
Reputation
554
Reaction score
248
Trophy points
1,343
Location
Japan
Activity points
10,597
Hello!

thank you for the advice,
how can I use the timer, do you have idea ?
You mean the hardware timer? It depends on your processor.
Basically:
- Set up the timer; (to be done only once in the program setup)
Now when you want to use it:
- Let it start counting;
- Put the processor to sleep;

When the interrupt comes, continue what you were doing. This implies
some changes in your code architecture, but it's worth the pain.
The timer method works well for milliseconds, but for microseconds
it would probably become tricky due to the interrupt overhead
(maybe a few 10 **** cycles).

Dora.
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
I'm using 89S52, how can I make the code below becoming 1ms ?

like this one :
Code:
#include <reg52.h>
#include <stdio.h>

/*------------------------------------------------
Timer 0 Interrupt Service Routine.

Set a breakpoint on 'overflow_count++' and run the
program in the debugger.  You will see this line
executes every 65536 clock cycles.
------------------------------------------------*/
static unsigned long overflow_count = 0;

void timer0_ISR (void) interrupt 1
{
overflow_count++;   /* Increment the overflow count */
}

/*------------------------------------------------
MAIN C function
------------------------------------------------*/
void main (void)
{
/*--------------------------------------
Set Timer0 for 16-bit timer mode.  The
timer counts to 65535, overflows, and
generates an interrupt.

Set the Timer0 Run control bit.
--------------------------------------*/
TMOD = (TMOD & 0xF0) | 0x01;  /* Set T/C0 Mode */
ET0 = 1;                      /* Enable Timer 0 Interrupts */
TR0 = 1;                      /* Start Timer 0 Running */
EA = 1;                       /* Global Interrupt Enable */

/*--------------------------------------
Do Nothing.  Actually, the timer 0
interrupt will occur every 65536 clocks.
--------------------------------------*/
while (1)
  {
  }
}


---------- Post added at 09:24 ---------- Previous post was at 09:20 ----------

Hello!



You mean the hardware timer? It depends on your processor.
Basically:
- Set up the timer; (to be done only once in the program setup)
Now when you want to use it:
- Let it start counting;
- Put the processor to sleep;

When the interrupt comes, continue what you were doing. This implies
some changes in your code architecture, but it's worth the pain.
The timer method works well for milliseconds, but for microseconds
it would probably become tricky due to the interrupt overhead
(maybe a few 10 **** cycles).

Dora.

- Let it start counting;
- Put the processor to sleep;

How can I do that ?
 

doraemon

Super Moderator
Staff member
Joined
Jun 21, 2009
Messages
1,068
Helped
273
Reputation
554
Reaction score
248
Trophy points
1,343
Location
Japan
Activity points
10,597
Hello!

As I told you, it depends on your processor.
If your processor has some kind of sleep mode, then you can do it. First read the docs.
Configure your timer, write an interrupt function, put the processor to sleep.
If there is no sleep mode, then using a timer is still a good solution because you will
have a better precision (you can fine-tune down to 1 clock cycle vs about 10 in the case
of a loop.

Dora.
 

Marvin_G

Junior Member level 3
Joined
Nov 21, 2011
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,485
Guys,

How can I make 1 ms second delay for 11.093Mhz crystal on AT89S52
Is this code right ?

Code:
void delay_ms(unsigned int msec)    //delay function
	{	
	 	//;
		
		unsigned int i,j;
		for(i=0;i<msec;i++);
		for(j=0;j<1110;j++);
		
     	
	}
Thanks
easy...just use crystal frequency...set timer 0 as delay..set in Timer mode register..baudrate..and serial port as well..
void delay (void) //1ms delay
{
TH0=0;
TL0=0;
TH0 = 0xFC;
TL0 = 0x66;
TR0 = 1;
while(!TF0);
TR0 = 0;
TF0 = 0;
return;
}
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
easy...just use crystal frequency...set timer 0 as delay..set in Timer mode register..baudrate..and serial port as well..
void delay (void) //1ms delay
{
TH0=0;
TL0=0;
TH0 = 0xFC;
TL0 = 0x66;
TR0 = 1;
while(!TF0);
TR0 = 0;
TF0 = 0;
return;
}
How can I calculate :

Code:
     TH0 = 0xFC;
     TL0 = 0x66;
as 1 ms my crystal is 11.0592 Mhz, and uC =AT89S52

Thanks

---------- Post added at 23:14 ---------- Previous post was at 23:09 ----------

How can I calculate :

Code:
     void delay (void) //1ms delay
{
TH0=0;
TL0=0;
TH0 = 0xFC;
TL0 = 0x66;
TR0 = 1;
while(!TF0);
TR0 = 0;
TF0 = 0;
return;
}
as 1 ms my crystal is 11.0592 Mhz, and uC =AT89S52



Thanks
11Mhz divide by FC66 ? equal to 1ms ?

11Mhz / 64614 = 171 ?

is it 171 cycle equal to 1ms ???

Thanks
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
See attachment, examples are in ASM and C ..

:wink:
IanP
Thank you very much for the document

---------- Post added at 04:46 ---------- Previous post was at 04:42 ----------

I got it x=1ms/(6/11Mhz), then y= 65535- x, I must enter y into the timer to get 1ms delay, y=65535-1843 , y = FC66 Hex...

Thanks

---------- Post added at 04:49 ---------- Previous post was at 04:46 ----------

I can put this delay function like this ?

....
function A();
delay();
functionB();

Thanks
 

Marvin_G

Junior Member level 3
Joined
Nov 21, 2011
Messages
28
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,485
How can I calculate :

Code:
     TH0 = 0xFC;
     TL0 = 0x66;
as 1 ms my crystal is 11.0592 Mhz, and uC =AT89S52

Thanks

---------- Post added at 23:14 ---------- Previous post was at 23:09 ----------



11Mhz divide by FC66 ? equal to 1ms ?

11Mhz / 64614 = 171 ?

is it 171 cycle equal to 1ms ???

Thanks
its 11.0729MHz..1 period freq-=12*(1/11.0729M)=1.085microsec
1ms/1.085microsec=922 cycles..
65536(max cycle) - 922= 64614 (decimal) = FC66 (hex)...this is for 1ms delay..understood?
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
its 11.0729MHz..1 period freq-=12*(1/11.0729M)=1.085microsec
1ms/1.085microsec=922 cycles..
65536(max cycle) - 922= 64614 (decimal) = FC66 (hex)...this is for 1ms delay..understood?
I got it, I read the document above..
 

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,312
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,436
easy...just use crystal frequency...set timer 0 as delay..set in Timer mode register..baudrate..and serial port as well..
void delay (void) //1ms delay
{
TH0=0;
TL0=0;
TH0 = 0xFC;
TL0 = 0x66;
TR0 = 1;
while(!TF0);
TR0 = 0;
TF0 = 0;
return;
}
if I want to create 100ms,

Code:
void delay (void) //1ms delay
{
TH0=0;
TL0=0;
TH0 = 0xFC;
TL0 = 0x66;
TR0 = 1;
while(!TF0);
TR0 = 0;
TF0 = 0;
return;
}

for (i=0;i<100;i++)
{
 delay()
}
?

Thanks
 

luben111

Advanced Member level 1
Joined
Mar 2, 2002
Messages
491
Helped
111
Reputation
223
Reaction score
107
Trophy points
1,323
Location
UK
Activity points
3,901
@dora

Hello!
If there is no sleep mode, then using a timer is still a good solution because you will
have a better precision (you can fine-tune down to 1 clock cycle vs about 10 in the case
of a loop.
Dora.
Just to mention that it's possible to make a software delay with 1 cycle resolution. Even it's possible to make universal software delay procedure that takes the number of delay cycles and has resolution of one machine cycle. For sure it's more complex from what was listed above. And the timer is the preferred way for the delays - while you're waiting you can do some other tasks.
Regards
 

doraemon

Super Moderator
Staff member
Joined
Jun 21, 2009
Messages
1,068
Helped
273
Reputation
554
Reaction score
248
Trophy points
1,343
Location
Japan
Activity points
10,597
Hello!

I'm aware of that.
If it just consists in consuming cycles, IAR provides a kind of function called delay_cycles(uint32 count);
I have never tried with only a few cycles, but with a fair amount of cycles (for instance delay_cycles(CLK_KHZ) allows
to delay exactly 1ms. CLK_KHZ is the clock frequency in khz. 25000 in case of a 25MHz clock. However, it consumes
clocks (therefore energy) and setting a timer is better.

Dora.

@dora



Just to mention that it's possible to make a software delay with 1 cycle resolution. Even it's possible to make universal software delay procedure that takes the number of delay cycles and has resolution of one machine cycle. For sure it's more complex from what was listed above. And the timer is the preferred way for the delays - while you're waiting you can do some other tasks.
Regards
 

Status
Not open for further replies.
Toggle Sidebar

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top