<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統 > 設計應用 > 89S51單片機實現誤差幾微秒的計時程序

          89S51單片機實現誤差幾微秒的計時程序

          作者: 時間:2016-11-19 來源:網絡 收藏
          小弟學習單片機時間很短,這樣的文章對于熟悉的人說很是菜,,不過我的目的不是顯擺我多NB,其實我根本就是個菜鳥,我的目的只是想通過這篇文章給和我一樣的初級學者有一定幫助,至少我把這個程序寫出來后,自己對單片機的一些概念的理解確實有幫助,好了進入正題!

          我們都知道單片機是工作在脈沖之下,而晶振這個電子元件就是核心,所以單片機里的計時計數器都是通過晶振的脈沖數量來計算的,晶振的規(guī)格主要就就是它的振蕩頻率,有12MHZ,11.0592MHZ,8MHZ等等,我們知道,機器周期就是通過 12 * 晶振的頻率的倒數 得到的,比如使用12MHZ的單片機它的機器周期就是1微秒,也就是執(zhí)行一個單指令周期需要的時間。說到這里很多初學者會有個和我開始一樣的疑問,就是為什么要搞個1.0592MHZ的晶振呢?用整數不好么?我開始也是摸不著頭腦,但是當我學習到串口通訊的時候,就恍然大悟了,具體為什么這里就不介紹了,不明白的可以去了解下串口通訊,相信你也會恍然大悟。
          我的實驗板上用的是89S51芯片,使用的晶振是8MHZ的,所以我的89S51執(zhí)行一個單周期指令就需要12* 1/8 = 1.5微秒,好了有了這個就可以開始了:
          首先我們用匯編寫一個延遲程序,該程序有三個參數,分別為x,y,z,用的是三個循環(huán)鑲套的結構,至于為什么不用2個,,很簡單,因為我們要賦值的寄存器是8位的,所以范圍只能是256,如果用2層那么最大只能是256*256=65536,而我們的一秒鐘可是1000000微秒,所以顯然不夠,用三層我們就可以得到最大256*256*256=16777216,這樣才夠用,好了分析下面的這個延時程序到底延遲多久:

          本文引用地址:http://www.ex-cimer.com/article/201611/318295.htm

          我們的目的就是要使得這個延遲盡量達到1000000微秒的時間,所以x,y,z的值還不確定,先不管,先分析下每一行執(zhí)行的時間,說明一下,這里的mov是單周期指令,執(zhí)行一次就是1.5微秒(別問我怎么來的,前面算的),而djnz是個雙周期指令,執(zhí)行一次就是1.5*2=3微秒,知道這個了就看下面程序每行后面的具體計算時間

          YS_1S: mov r0,#x 1.5 (只執(zhí)行了一次,所以1.5微秒)
          d1: mov r1,#y 1.5*x (執(zhí)行了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里,隨便用個發(fā)光2極管做閃爍,就可以看到效果了,再用秒表做一個粗造的測試,就OK了。
          其實,我這個方法很笨,但我的目的是學習,而且自己的學習有點小小的成果后,拿出來和別人分享,哪怕是錯誤的,至少我知道錯誤在哪里,改正錯誤,這又是一種進步。



          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();