学习MCS-51单片机,如果用软件延时实现时钟,会接触到如下形式的延时子程序:delay:mov R5,#data1
d1:mov R6,#data2
d2:mov R7,#data3
d3:djnz R7,d3
djnz R6,d2
djnz R5,d1
Ret
其精确延时时间公式:t=(2*R5*R6*R7+3*R5*R6+3*R5+3)*T
(“*”表示乘法,T表示一个机器周期的时间)近似延时时间公式:t=2*R5*R6*R7 *T
假如data1,data2,data3分别为50,40,248,并假定单片机晶振为12M,一个机器周期为10-6S,则10分钟后,时钟超前量超过1.11秒,24小时后时钟超前159.876秒(约2分40秒)。
这都是data1,data2,data3三个数字造成的,精度比较差,建议C描述。
上表中e=-1的行(共11行)满足(2*R5*R6*R7+3*R5*R6+3*R5+3)=999,999
e=1的行(共2行)满足(2*R5*R6*R7+3*R5*R6+3*R5+3)=1,000,001 假如单片机晶振为12M,一个机器周期为10-6S,若要得到精确的延时一秒的子程序,则可以在之程序的Ret返回指令之前加一个机器周期为1的指令(比如nop指令),
data1,data2,data3选择e=-1的行。
比如选择第一个e=-1行,则精确的延时一秒的子程序可以写成:
delay:mov R5,#167
d1:mov R6,#171
d2:mov R7,#16
d3:djnz R7,d3
djnz R6,d2
djnz R5,d1
nop ;注意不要遗漏这一句
Ret
附:
#include"iostReam.h"
#include"math.h"
int x=1,y=1,z=1,a,b,c,d,e(999989),f(0),g(0),i,j,k;
void main()
{
foR(i=1;i<255;i++)
{
foR(j=1;j<255;j++)
{
foR(k=1;k<255;k++)
{
d=x*y*z*2+3*x*y+3*x+3-1000000;
if(d==-1)
{
e=d;a=x;b=y;c=z;
f++;
cout<<"e="<<e<<" "<<"R5="<<a<<" "<<"R6="<<b<<" "<<"R7="<<c<<"
"<<"f="<<f<<endl<<endl;
};
if(d==1)
{
e=d;a=x;b=y;c=z;
g++;
cout<<"e="<<e<<" "<<"R5="<<a<<" "<<"R6="<<b<<" "<<"R7="<<c<<" "<<"g="<<g<<endl<<endl;
};
x++;
}
x=1;y++;
}
y=1;z++;
}
}。