新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 89S51單片機實現(xiàn)誤差幾微秒的計時程序

        89S51單片機實現(xiàn)誤差幾微秒的計時程序

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

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

        本文引用地址:http://www.104case.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

        現(xiàn)在我們把每行相加,1.5 + 1.5*x + 1.5*x*y + 2*1.5*x*y*z + 2*1.5*x*y + 2*x + 1.5得到這個公式,現(xiàn)在要求這個公式算出來大概等于 1000000, 我們把這個公式加以簡化,就的到如下方程:


        3+4.5*x+4.5*x*y+3*x*y*z = 1000000


        現(xiàn)在我們要求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是因為很有可能會出現(xiàn)這個方程不會完全等于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;這三個參數(shù)放到公式里算出來是999993,所以這個延遲就誤差7微秒,把這三個值放到開始的延遲程序?qū)?yīng)的xyz里,燒寫到89S51里,隨便用個發(fā)光2極管做閃爍,就可以看到效果了,再用秒表做一個粗造的測試,就OK了。
        其實,我這個方法很笨,但我的目的是學(xué)習(xí),而且自己的學(xué)習(xí)有點小小的成果后,拿出來和別人分享,哪怕是錯誤的,至少我知道錯誤在哪里,改正錯誤,這又是一種進步。



        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 女性| 望城县| 晋州市| 泉州市| 邵武市| 泸溪县| 甘孜| 竹溪县| 多伦县| 神农架林区| 钟山县| 襄汾县| 苏尼特左旗| 印江| 乌审旗| 潜江市| 会理县| 兰考县| 荆州市| 来凤县| 泸西县| 彝良县| 老河口市| 金寨县| 喀喇| 江北区| 双峰县| 三门县| 台东市| 三亚市| 林甸县| 长武县| 乐清市| 秦安县| 莱阳市| 甘肃省| 衡水市| 蛟河市| 枝江市| 西华县| 桑日县|