89S51单片机实现误差几微秒的计时程序

     小弟学习单片机时间很短,这样的文章对于熟悉的人说很是菜,呵呵,不过我的目的不是显摆我多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 <<" " <<y <<" " <<z <<"/n";   
   }

 

    最后我得到的是x=205 y=171 z=8;这三个参数放到公式里算出来是999993,所以这个延迟就误差7微秒,把这三个值放到开始的延迟程序对应的xyz里,烧写到89S51里,随便用个发光2极管做闪烁,就可以看到效果了,再用秒表做一个粗造的测试,就OK了。
    其实,我这个方法很笨,但我的目的是学习,而且自己的学习有点小小的成果后,拿出来和别人分享,哪怕是错误的,至少我知道错误在哪里,改正错误,这又是一种进步。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值