2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 延时1us程序12mhz晶振c语言 51单片机 Keil C 延时程序的简单(晶振12MHz 一个机器周期1us.)...

延时1us程序12mhz晶振c语言 51单片机 Keil C 延时程序的简单(晶振12MHz 一个机器周期1us.)...

时间:2021-03-19 16:37:51

相关推荐

延时1us程序12mhz晶振c语言 51单片机 Keil C 延时程序的简单(晶振12MHz 一个机器周期1us.)...

一. 500ms延时子程序

void delay500ms(void)

{

unsignedchari,j,k;for(i=15;i>0;i--)for(j=202;j>0;j--)for(k=81;k>0;k--);

}

产生的汇编:

C:0x08007F0F MOV R7,#0x0F

C:0x0802 7ECA MOV R6,#0xCA

C:0x0804 7D51 MOV R5,#0x51

C:0x0806 DDFE DJNZ R5,C:0806

C:0x0808 DEFA DJNZ R6,C:0804

C:0x080A DFF6 DJNZ R7,C:0802

C:0x080C 22RET

计算分析:

程序共有三层循环

一层循环n:R5*2 = 81*2 = 162us DJNZ 2us

二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us

三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值1us = 3us

循环外: 5us子程序调用2us +子程序返回2us + R7赋值1us = 5us

延时总时间=三层循环+循环外= 499995+5 = 500000us =500ms

计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5

二. 200ms延时子程序

void delay200ms(void)

{

unsignedchari,j,k;for(i=5;i>0;i--)for(j=132;j>0;j--)for(k=150;k>0;k--);

}

产生的汇编

C:0x08007F05 MOV R7,#0x05

C:0x0802 7E84 MOV R6,#0x84

C:0x0804 7D96 MOV R5,#0x96

C:0x0806 DDFE DJNZ R5,C:0806

C:0x0808 DEFA DJNZ R6,C:0804

C:0x080A DFF6 DJNZ R7,C:0802

C:0x080C 22RET

三. 10ms延时子程序

void delay10ms(void)

{

unsignedchari,j,k;for(i=5;i>0;i--)for(j=4;j>0;j--)for(k=248;k>0;k--);

}

产生的汇编

C:0x08007F05 MOV R7,#0x05

C:0x0802 7E04 MOV R6,#0x04

C:0x0804 7DF8 MOV R5,#0xF8

C:0x0806 DDFE DJNZ R5,C:0806

C:0x0808 DEFA DJNZ R6,C:0804

C:0x080A DFF6 DJNZ R7,C:0802

C:0x080C 22 RET

四. 1s延时子程序

void delay1s(void)

{

unsignedcharh,i,j,k;for(h=5;h>0;h--)for(i=4;i>0;i--)for(j=116;j>0;j--)for(k=214;k>0;k--);

}

对1s延时的验证:

1.设置仿真的晶振为12MHz

2.在延时函数设置断点

3.单步运行程序,到达延时函数的入口

4.先记下进入延时函数的时间

5.step out跳出函数,记下此时时间,两个时间相减即为延时函数运行时间

函数运行时间=1.00041400-0.00041600≈1s

产生的汇编

C:0x08007F05 MOV R7,#0x05

C:0x0802 7E04 MOV R6,#0x04

C:0x0804 7D74 MOV R5,#0x74

C:0x0806 7CD6 MOV R4,#0xD6

C:0x0808 DCFE DJNZ R4,C:0808

C:0x080A DDFA DJNZ R5,C:0806

C:0x080C DEF6 DJNZ R6,C:0804

C:0x080E DFF2 DJNZ R7,C:0802

C:0x0810 22 RET

在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.

void mDelay(unsigned int Delay) //Delay = 1000 时间为1S

{

unsignedinti;for(;Delay>0;Delay--)

{for(i=0;i<124;i )

{;}

}

}void waitms(inti)

{charm;for( ; i ;i--)

{for(m = 203; m ; m--)

{

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

}

}

}

延时1ms的函数时钟频率12MHz

unsigned intsleepTime;

unsingedchar inSleep = 0;void sleepService(void)

{if (inSleep) sleepTime--;if (sleepTime == 0) inSleep = 0;

}void isr_timer(void) //假定定时器中断1ms 中断一次。

{

...

sleepService();

...

}void sleep(unsigned int ms) //延时子程序

{

sleepTime=ms;

inSleep= 1;while(inSleep);

}void main(void)

{

....

sleep(1000); //延时 1秒

...

}

如果要求是秒级的这么长的延时,单片机中一般采取不占CPU时间的延时,利用定时器来实现延时,如果非得用循环延时,在C中也通常嵌入汇编实现,这样误差比较小。

转载自:/heiyue/p/3246988.html

==========================================================================

如下程序能实现ms毫秒级的比较精确的延时

void Delayms(unsigned intn)

{

unsignedinti,j;for(j=n;j>0;j--)for(i=112;i>0;i--);

}

用keil可以看出这个延时的时间,我们先延时1ms(Delayms(1))。

进入Delayms前,sec=0.00042209s

延时后,sec=0.00142253s

可以知道Delayms(1)实际延时0.00142253s—0.00042209s=0.00100044s≈1ms

同样如果想延时15ms的话,用Delayms(15),实际延时0.01480903s≈15ms,延时还是挺精确的。

=======================================================

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。