单片机c语言中nop函数的使用方法和延时计算文档格式.docx
- 文档编号:16244059
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:8
- 大小:17.61KB
单片机c语言中nop函数的使用方法和延时计算文档格式.docx
《单片机c语言中nop函数的使用方法和延时计算文档格式.docx》由会员分享,可在线阅读,更多相关《单片机c语言中nop函数的使用方法和延时计算文档格式.docx(8页珍藏版)》请在冰豆网上搜索。
i<
255;
i++);
for(i=255;
i>
0;
i--);
其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令:
MOV 09H,#0FFH
LOOP:
DJNZ 09H,LOOP
指令相当简洁,也很好计算精确的延时时间。
同样对do…while,while循环语句中,也是如此
例:
unsignedcharn;
n=255;
do{n--}
while(n);
或
while(n)
{n--};
这两个循环语句经过C51编译之后,形成DJNZ来完成的方法,
故其精确时间的计算也很方便。
其三:
对于要求精确延时时间更长,这时就要采用循环嵌套
的方法来实现,因此,循环嵌套的方法常用于达到ms级的延时。
对于循环语句同样可以采用for,do…while,while结构来完
成,每个循环体内的变量仍然采用无符号字符变量。
unsignedchari,j
i--)
for(j=255;
j>
j--);
i=255;
do{j=255;
do{j--}
while(j);
i--;
}
while(i);
while(i)
{j=255;
while(j)
{j--};
i--;
}
这三种方法都是用DJNZ指令嵌套实现循环的,由C51编
译器用下面的指令组合来完成的
MOV R7,#0FFH
LOOP2:
MOV R6,#0FFH
LOOP1:
DJNZ R6,LOOP1
DJNZ R7,LOOP2
这些指令的组合在汇编语言中采用DJNZ指令来做延时用,
因此它的时间精确计算也是很简单,假上面变量i的初
值为m,变量j的初值为n,则总延时时间为:
m×
(n×
T+T),
其中T为DJNZ指令执行时间(DJNZ指令为双周期指令)。
这里的+T为MOV这条指令所使用的时间。
同样对于更长时间的延时,可以采用多重循环来完成。
只要在程序设计循环语句时注意以上几个问题。
下面给出有关在C51中延时子程序设计时要注意的问题
1、在C51中进行精确的延时子程序设计时,尽量不要
或少在延时子程序中定义局部变量,所有的延时子程
序中变量通过有参函数传递。
2、在延时子程序设计时,采用do…while,结构做循
环体要比for结构做循环体好。
3、在延时子程序设计时,要进行循环体嵌套时,采用
先内循环,再减减比先减减,再内循环要好。
unsignedchardelay(unsignedchari,unsignedcharj,unsignedchark)
{unsignedcharb,c;
b="
j"
;
c="
k"
do{
do{
do{k--};
while(k);
k="
c"
j--;
};
while(j);
j=b;
while(i);
这精确延时子程序就被C51编译为有下面的指令组合完成
delay延时子程序如下:
MOVR6,05H
MOVR4,03H
C0012:
DJNZR3,C0012
MOVR3,04H
DJNZR5,C0012
MOVR5,06H
DJNZR7,C0012
RET
假设参数变量i的初值为m,参数变量j的初值为n,参数
变量k的初值为l,则总延时时间为:
l×
(m×
T+2T)+2T)+3T,
其中T为DJNZ和MOV指令执行的时间。
当m=n=l时,精确延时为9T,最短;
当m=n=l=256时,精确延时到16908803T,最长。
-----------------------------------------------------------------------------------------
采用软件定时的计算方法
利用指令执行周期设定,以下为一段延时程序:
指令周期
MOV1
DJNZ2
NOP1
采用循环方式定时,有程序:
MOVR5,#TIME2;
周期1
LOOP1:
MOVR6,#TIME1;
1
LOOP2:
NOP;
DJNZR6,LOOP2;
2
DJNZR5,LOOP1;
定时数=(TIME1*4+2+1)*TIM2*2+4
刚刚又学了一条,用_nop_();
时记得加上#include<
头文件
如:
//==================
#include<
//包含库函数
......
//============
_nop_();
//引用库函数
敬礼。
我一直都是借助仿真软件编。
一点一点试时间。
C语言最大的缺点就是实时性差,我在网上到看了一些关于延时的讨论,其中有篇文章
51单片机KeilC延时程序的简单研究,作者:
InfiniteSpaceStudio/isjfk
写得不错,他是用while(--i);
产生DJNZ来实现精确延时,后来有人说如果while里面不能放其它语句,否则也不行,用do-while就可以,具体怎样我没有去试.所有这些都没有给出具体的实例程序来.还看到一些延时的例子多多少少总有点延时差.为此我用for循环写了几个延时的子程序贴上来,希望能对初学者有所帮助.(晶振12MHz,一个机器周期1us.)
一.500ms延时子程序
程序:
voiddelay500ms(void)
{
unsignedchari,j,k;
for(i=15;
i--)
for(j=202;
j--)
for(k=81;
k>
k--);
}
产生的汇编:
C:
0x08007F0FMOVR7,#0x0F
0x08027ECAMOVR6,#0xCA
0x08047D51MOVR5,#0x51
0x0806DDFEDJNZR5,C:
0806
0x0808DEFADJNZR6,C:
0804
0x080ADFF6DJNZR7,C:
0802
0x080C22RET
计算分析:
程序共有三层循环
一层循环n:
R5*2=81*2=162usDJNZ2us
二层循环m:
R6*(n+3)=202*165=33330usDJNZ2us+R5赋值1us=3us
三层循环:
R7*(m+3)=15*33333=499995usDJNZ2us+R6赋值1us=3us
循环外:
5us子程序调用2us+子程序返回2us+R7赋值1us=5us
延时总时间=三层循环+循环外=499995+5=500000us=500ms
计算公式:
延时时间=[(2*R5+3)*R6+3]*R7+5
二.200ms延时子程序
voiddelay200ms(void)
{
for(i=5;
for(j=132;
for(k=150;
}
产生的汇编
C:
0x08007F05MOVR7,#0x05
0x08027E84MOVR6,#0x84
0x08047D96MOVR5,#0x96
0x080C22RET
三.10ms延时子程序
voiddelay10ms(void)
for(j=4;
for(k=248;
0x08027E04MOVR6,#0x04
0x08047DF8MOVR5,#0xF8
四.1s延时子程序
voiddelay1s(void)
unsignedcharh,i,j,k;
for(h=5;
h>
h--)
for(i=4;
for(j=116;
for(k=214;
0x08047D74MOVR5,#0x74
0x08067CD6MOVR4,#0xD6
0x0808DCFEDJNZR4,C:
0808
0x080ADDFADJNZR5,C:
0x080CDEF6DJNZR6,C:
0x080EDFF2DJNZR7,C:
0x081022RET
在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 语言 nop 函数 使用方法 延时 计算