delay延时教程
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
}
}
void main (void) {
Dly1ms();
}
把P1.0接入示波器,运行上面的程序,可以看到P1.0输出的波形为周期是3 ms的方波。其中,高电平为2 ms,低电平为1 ms,即for循环结构“for(j=0;j<124;j++) {;}”的执行时间为1 ms。通过改变循环次数,可得到不同时间的延时。当然,也可以不用for循环而用别的语句实现延时。这里讨论的只是确定延时的方法。
三层循环: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
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080A DFF6 DJNZ R7,C:0802
C:0x080C 22 RET
计算分析:
程序共有三层循环
一层循环n:R5*2= 81*2 = 162us DJNZ 2us
二层循环m:R6*(n+3)= 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us
四、a:delaytime为us级
直接调用库函数:
#include<intrins.h>//声明了void _nop_(void);
_nop_(); //产生一条NOP指令
作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。
eg:可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:
5.在do…while,while语句中,循环体内变量也采用减减方法。
三、编辑注意:
1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。
2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。
3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。
值为m,变量j的初值为n,则总延时时间为:
m×(n×2+2+1),
注:DJNZ A,B是一条转移指令,先将A减1,若减后,
1)A=0;不转移到B处;
2)A!=0;跳到B处;
例2:void delay500ms(void)
{
unsigned charR7,R6,R5;
for(R7=15;R7>0;R7--)
void Delay10us( ) {
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
}
延迟时间=6*1us+2us+2us=10us
b:delaytime为us级
我们用汇编语言写单片机延时10ms的程序,可以编写下面的程序来实现:
unsigned char i,j
sbit T_point = P1^0;
void Dly1ms(void) {
unsigned int i,j;
while (1) {
T_point = 1;
for(i=0;i<2;i++){
for(j=0;j<124;j++){;}
}
T_point = 0;
for(i=0;i<1;i++){
for(j=0;j<124;j++){;}
delay延时教程(用的是12MHz晶振的MCS-51)
一、
1)NOP指令为单周期指令
2)DJNZ指令为双周期指令
3)mov指令为单周期指令
4)子程序调用(即LCALL指令)为双周期指令
5)ret为双周期指令
states是指令周期数,
sec是时间,=指令周期×states,设置好晶振频率就是准确的了
for(R6=202;R6>0;R6--)
for(R5=81;R5>0;R5--);
}
产生的汇编:
C:0x0800 7F0F MOV R7,#0x0F
C:0x0802 7ECA MOV R6,#0xCA
C:0x0804 7D51 MOV R5,#0x51
C:0x0806 DDFE DJNZ R5,C:0806最内层
for(i=255;i>0;i--)
for(j=255;j>0;j--);
或
unsigned char i,j
i=2来自百度文库5;
do
{
j=255;
do{j--}
while(j);
i--;
}
while(i);
或
unsigned char i,j
i=255;
while(i)
{
j=255;
while(j)
{j--};
i--;
}
这三种方法都是用DJNZ指令嵌套实现循环的,由C51编
译器用下面的指令组合来完成的
MOVR7,#0FFH
LOOP2:MOVR6,#0FFH(1周期)
LOOP1:DJNZR6,LOOP1
DJNZR7,LOOP2(2周期)
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初
调试>设置/取消断点”设置或移除断点,也可以用鼠标在该行双击实现同样的功能
二、编程最好:
1.尽量使用unsigned型的数据结构。
2.尽量使用char型,实在不够用再用int,然后才是long。
3.如果有可能,不要用浮点型。
4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。
总结:延时时间=((2*内0+3)*内1+3)*内2
五、使用示波器确定延时时间
利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个I/O口线如P1.0为高电平,在函数的最后清P1.0为低电平。在主程序中循环调用该延时函数,通过示波器测量P1.0引脚上的高电平时间即可确定延时函数的执行时间。方法如下:
}
}
void main (void) {
Dly1ms();
}
把P1.0接入示波器,运行上面的程序,可以看到P1.0输出的波形为周期是3 ms的方波。其中,高电平为2 ms,低电平为1 ms,即for循环结构“for(j=0;j<124;j++) {;}”的执行时间为1 ms。通过改变循环次数,可得到不同时间的延时。当然,也可以不用for循环而用别的语句实现延时。这里讨论的只是确定延时的方法。
三层循环: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
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080A DFF6 DJNZ R7,C:0802
C:0x080C 22 RET
计算分析:
程序共有三层循环
一层循环n:R5*2= 81*2 = 162us DJNZ 2us
二层循环m:R6*(n+3)= 202*165 = 33330us DJNZ 2us + R5赋值1us = 3us
四、a:delaytime为us级
直接调用库函数:
#include<intrins.h>//声明了void _nop_(void);
_nop_(); //产生一条NOP指令
作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。
eg:可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:
5.在do…while,while语句中,循环体内变量也采用减减方法。
三、编辑注意:
1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。
2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。
3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。
值为m,变量j的初值为n,则总延时时间为:
m×(n×2+2+1),
注:DJNZ A,B是一条转移指令,先将A减1,若减后,
1)A=0;不转移到B处;
2)A!=0;跳到B处;
例2:void delay500ms(void)
{
unsigned charR7,R6,R5;
for(R7=15;R7>0;R7--)
void Delay10us( ) {
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
_NOP_( );
}
延迟时间=6*1us+2us+2us=10us
b:delaytime为us级
我们用汇编语言写单片机延时10ms的程序,可以编写下面的程序来实现:
unsigned char i,j
sbit T_point = P1^0;
void Dly1ms(void) {
unsigned int i,j;
while (1) {
T_point = 1;
for(i=0;i<2;i++){
for(j=0;j<124;j++){;}
}
T_point = 0;
for(i=0;i<1;i++){
for(j=0;j<124;j++){;}
delay延时教程(用的是12MHz晶振的MCS-51)
一、
1)NOP指令为单周期指令
2)DJNZ指令为双周期指令
3)mov指令为单周期指令
4)子程序调用(即LCALL指令)为双周期指令
5)ret为双周期指令
states是指令周期数,
sec是时间,=指令周期×states,设置好晶振频率就是准确的了
for(R6=202;R6>0;R6--)
for(R5=81;R5>0;R5--);
}
产生的汇编:
C:0x0800 7F0F MOV R7,#0x0F
C:0x0802 7ECA MOV R6,#0xCA
C:0x0804 7D51 MOV R5,#0x51
C:0x0806 DDFE DJNZ R5,C:0806最内层
for(i=255;i>0;i--)
for(j=255;j>0;j--);
或
unsigned char i,j
i=2来自百度文库5;
do
{
j=255;
do{j--}
while(j);
i--;
}
while(i);
或
unsigned char i,j
i=255;
while(i)
{
j=255;
while(j)
{j--};
i--;
}
这三种方法都是用DJNZ指令嵌套实现循环的,由C51编
译器用下面的指令组合来完成的
MOVR7,#0FFH
LOOP2:MOVR6,#0FFH(1周期)
LOOP1:DJNZR6,LOOP1
DJNZR7,LOOP2(2周期)
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初
调试>设置/取消断点”设置或移除断点,也可以用鼠标在该行双击实现同样的功能
二、编程最好:
1.尽量使用unsigned型的数据结构。
2.尽量使用char型,实在不够用再用int,然后才是long。
3.如果有可能,不要用浮点型。
4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。
总结:延时时间=((2*内0+3)*内1+3)*内2
五、使用示波器确定延时时间
利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个I/O口线如P1.0为高电平,在函数的最后清P1.0为低电平。在主程序中循环调用该延时函数,通过示波器测量P1.0引脚上的高电平时间即可确定延时函数的执行时间。方法如下: