小弟学习单片机时刻很短,这样的文章关于了解的人说很是菜,,不过我的意图不是显摆我多NB,其实我根本便是个菜鸟,我的意图仅仅想经过这篇文章给和我相同的初级学者有必定协助,至少我把这个程序写出来后,自己对单片机的一些概念的了解的确有协助,好了进入正题!
咱们都知道单片机是作业在脉冲之下,而晶振这个电子元件便是中心,所以单片机里的计时计数器都是经过晶振的脉冲数量来核算的,晶振的标准主要就便是它的振动频率,有12MHZ,11.0592MHZ,8MHZ等等,咱们知道,机器周期便是经过 12 * 晶振的频率的倒数 得到的,比方运用12MHZ的单片机它的机器周期便是1微秒,也便是碑文一个单指令周期需求的时刻。提到这儿许多初学者会有个和我开端相同的疑问,便是为什么要搞个1.0592MHZ的晶振呢?用整数不好么?我开端也是摸不着头脑,但是当我学习到串口通讯的时分,就茅塞顿开了,详细为什么这儿就不介绍了,不明白的能够去了解下串口通讯,相信你也会茅塞顿开。
我的试验板上用的是89S51芯片,运用的晶振是8MHZ的,所以我的89S51碑文一个单周期指令就需求12* 1/8 = 1.5微秒,好了有了这个就能够开端了:
首要咱们用汇编写一个推迟程序,该程序有三个参数,分别为x,y,z,用的是三个循环镶套的结构,至于为什么不必2个,,很简单,由于咱们要赋值的寄存器是8位的,所以规模只能是256,假如用2层那么最大只能是256*256=65536,而咱们的一秒钟但是1000000微秒,所以明显不行,用三层咱们就能够得到最大256*256*256=16777216,这样才够用,好了剖析下面的这个延时程序究竟推迟多久:
咱们的意图便是要使得这个推迟尽量到达1000000微秒的时刻,所以x,y,z的值还不确认,先不论,先剖析下每一行碑文的时刻,阐明一下,这儿的mov是单周期指令,碑文一次便是1.5微秒(别问我怎样来的,前面算的),而djnz是个双周期指令,碑文一次便是1.5*2=3微秒,知道这个了就看下面程序每行后边的详细核算时刻
YS_1S: mov r0,#x 1.5 (只碑文了一次,所以1.5微秒)
d1: mov r1,#y 1.5*x (碑文了x次,每次1.5微秒)
d2: mov r2,#z 1.5*x*y 同上
d3: djnz r2,d3 2*1.5*x*y*z (双周期指令所以还要乘2)
djnz r1,d2 2*1.5*x*y 同上
djnz r0,d1 2*x 同上
ret 1.5
现在咱们把每行相加,1.5 + 1.5*x + 1.5*x*y + 2*1.5*x*y*z + 2*1.5*x*y + 2*x + 1.5得到这个公式,现在要求这个公式算出来大约等于 1000000, 咱们把这个公式加以简化,就的到如下方程:
3+4.5*x+4.5*x*y+3*x*y*z = 1000000
现在咱们要求x,y,z的值,怎样求呢?随意用自己了解的言语,用穷举法,我是用C++写的,如下:
int x,y,z;
for(x=1;x<=256;x++)
for(y=1;y<=256;y++)
for(z=1;z<=256;z++)
//这儿我没写1000000是由于很有可能会呈现这个方程不会彻底等于1000000,所以我仍是取了个 规模,所以为什么标题说是几微秒的夺冠了,
if(((999990>=(3+4.5*x+4.5*x*y+3*x*y*z)))&&((1000000<=(3+4.5*x+4.5*x*y+3*x*y*z))))
{
cout <
最终我得到的是x=205 y=171 z=8;这三个参数放到公式里算出来是999993,所以这个推迟就夺冠7微秒,把这三个值放到开端的推迟程序对应的xyz里,烧写到89S51里,随意用个发光2极管做业绩,就能够看到作用了,再用秒表做一个粗造的测验,就OK了。
其实,我这个办法很笨,但我的意图是学习,并且自己的学习有点小小的效果后,拿出来和他人共享,哪怕是过错的,至少我知道过错在哪里,改正过错,这又是一种前进。