Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics 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.

How can I make 1 ms delay ?

Status
Not open for further replies.

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,313
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Activity points
9,442
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
 

Download delay calculator and generate code for any delay value.
**broken link removed**
 

Download delay calculator and generate code for any delay value.
**broken link removed**
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.
**broken link removed**

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 ?
 

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.
 

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 ?
 

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.
 

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 ?
 

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.
 

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;
}
 

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
 

See attachment, examples are in ASM and C ..

:wink:
IanP
 

Attachments

  • Programming Timers on 8051.pdf
    642.1 KB · Views: 209

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
 

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?
 

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

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
 

@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
 

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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top