<li id="8g3ty"><tbody id="8g3ty"><th id="8g3ty"></th></tbody></li>
    <label id="8g3ty"><samp id="8g3ty"></samp></label>
  • <span id="8g3ty"></span>

    1. <center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
    2. <bdo id="8g3ty"><meter id="8g3ty"><bdo id="8g3ty"></bdo></meter></bdo><center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
      <label id="8g3ty"><samp id="8g3ty"></samp></label>

    3. 電子開發網

      電子開發網電子設計 | 電子開發網Rss 2.0 會員中心 會員注冊
      搜索: 您現在的位置: 電子開發網 >> 電子開發 >> EDA開發應用 >> Keilc >> 正文

      利用Keil C51實現T0精確定時

      作者:佚名    文章來源:本站原創    點擊數:    更新時間:2008-10-31

          利用89C51設計一個簡易日歷時鐘系統,時鐘系統硬件主要由單片機控制的計時電路、復位等輔助電路、按鍵電路、數碼管顯示電路、電源系統等組成。日歷時鐘可以顯示年、月、時、分、秒;可以設置年、月、時、分 其中計時控制電路由AT89C51單片機控制;按鍵電路包含時間設置;時間顯示屏電路由7個數碼管組成;電源系統由小功率整流濾波穩壓電路組成,輸出直流電壓5 V,向主電路及顯示電路供電。系統框圖如圖1所示。
       
      圖1 日歷時鐘系統框圖
          在計時過程中,系統利用89C51自身的計時器T0作為時鐘基準,計時器中斷的準確度直接關系到整個系統的精度,因此獲取精確的定時時鐘信號成為該系統的關鍵。MCS-51單片機內有2個可編程的16位定時器/計數器,在本系統設計中采用AT89C51的定時器T0,并工作在方式1下,晶振頻率為12 MHz。

      1 T0定時中斷
          定時器/計數器T0工作方式1的電路邏輯結構如圖2所示。T0定時特性功能寄存器由TL0(低8位)和TH0(高8位)構成。特殊功能寄存器TMOD控制定時寄存器的工作方式;TCON則用于控制定時器T0和T1的啟動和停止計數,同時管理定時器T0和T1的溢出標志等。程序開始時需對TL0和TH0進行初始化編程,以定義它們的工作方式,并控制T0和T1的計數。在系統的設計中,計時單位以s為基準,并要求日誤差≤10 s,如果用循環去做,無法滿足精度要求。選用12 MHz的晶體可得到1 s的精度,經分析確定使用定時器0的方式1。這個方式下,定時器0是16位定時器,也就是最大定時值為FFFFH,12 MHz晶體的每個定時周期為1 s,最多可以定時FFFFH×1 s=65635 us,即使使用最大值也無法一次定時1 s,設計中使用1次定時20 ms,50次定時中斷得到1 s。20 ms定時中斷的定時值為:FFFFH-20 ms/1 s= B1DFH。
       
      圖2 定時器/計數器工作方式1邏輯結構

      2 程序測試與調整
      在Keil uVision3平臺下利用C語言實現如下代碼:
      #include<reg52.h>
      #define uchar unsigned char
      uchar data MScond= 0;//ms
      uchar data Scond= 0; //s
      uehar data M inute= 0;//min
      uchar data Hour= 0;//h
      void main(void){
      EA =1; //允許CPU中斷
      ET0 = 1; //定時器0中斷打開
      TMOD =0x1; //設定時器0為方式1
      TH0= 0xB1;
      TL0= 0xDF; //設定時值為20 000 us(20 ms)
      TR0 = 1; //開始定時
      while(1);
      }
      void Time0(void) interrupt 1 using 1
      {
      TH0=0xB1; //20 ms斷點 (1)
      TL0=0xDF; //設定時值
      MScond= MScond+ 1;
      if(MScond == 50)
      {MScond=0;
      Scond= Scond+ 1;
      if(Scond == 60)
      {Scond=0;
      Minute=Minute+1; //分斷點   (2)
      if(Minute == 60)
      {Minute=0;
      Hour=Hour+1; //d,時斷點   (3)
      if(Hour == 24)
      { Hour=0; }}}}
          首先調試每20 ms中斷時的精度,在選項中設定調試晶振為12 MHz,在(1)處設置一個斷點再運行,這時記錄下每次中斷時的時間,如圖3所示。在初始化中費時為551 s,每一次中斷時間應該考慮該項的影響。在實際處理中可以利用兩次中斷時間的差來作為定時器的中斷時
      間間隔。
          通過測試,得到第一次為0.020 568 00 s,第二次為0.040 580 00 s,第三次為0.060 592 00 s。可以看出,每中斷一次會比定時值長了12 s。如果將斷點設定在(2)處,并通過Logic Analyzer tool,得到分鐘第一次中斷的時間為60.036 57 S,第二次中斷的時間為120.072 57 s,則每分鐘的實際時間為60.036 S。再將斷點設定在(3)處,得到小時第一次中斷的時間為3 602.160 576 S,第二次中斷的時間為7204.320 576 S,可以得到小時的實際時間為3602.16 S,如圖4所示。
          為什么會產生這些誤差呢?通過對中斷程序的匯編源碼進行分析,實際上中斷程序入堆棧時使用了兩條語句:PUSH ACC和PUSH PSW。執行人棧指令花費了4個機器周期,加上重新對TH0和TL0的加載又用去2個機器周期,計數值加1花費了2個機器周期,中斷返回約4個機器周期共約12個機器周期。為了消除這些因素的影響,需要在對T0設置計數值時減去12個機器周期,將計算得到的初始值B1DFH加上12(0CH)得到:B1DFH+12=B1EBH作為新的定時器初值,修改后的程序為:
      #include<reg52.h>
      #define uchar unsigned char
      uchar data MScond=0; //ms
      uchar data Scond=0; //s
      uchar data Minute=0; //min
      uchar data Hour=0; //h
      void main(void){
      EA = 1; //允許CPU 中斷
      ET0= 1; //定時器0中斷打開
      TMOD = 0x1; //設定時器0為方式1
      TH0= 0xB1;
      TL0=0xEB; //設定時值為20 000 (20 ms)減去12
      TR0= 1; //開始定時
      while(1);
      }
      void Time0(void) interrupt 1 using 1
      {TH0=0xB1; //20 ms斷點 (1)
      TL0=0xDF; //設定時值
      MScond= MScond+ 1;
      if(MScond == 50)
      {MScond=0;
      Scond= Scond+ 1;
      if rScond == 60)
      {Scond=0;
      Minute=Minute+1; //分斷點 (2)
      if(Minute == 60)
      {Minute=0;
      Hour=Hour+1; //時斷點 (3)
      if(Hour == 24)
      { Hour=0;}}}}
          重新調試程序,仍然在選項中設定調試晶振為12 MHz,重新測試20 ms定時器的實際時間,在(1)處設置一個斷點后運行,重新記錄下每次中斷時的時間,如圖5所示。初始化時間為556 s,為消除其影響,使用兩次中斷時間間隔來作為定時器實際獲得的基準時鐘。得到一次中斷時的時間為0.020 556 00 S,第二次為0.040 556 000,第二次為0.060 556 00 s,可以看出每次中斷間隔剛好20 ms。如果將斷點設定在(2)處.并通過Logic Analyzer tool,得到第一次中斷時時間為60.000 57 s,第二次為120.000 57 s,間隔剛好60 s。將斷點設定在(3)處,得到第一次中斷的時間為3600.000 578 s,第二次中斷時間為7200.000 578 s,時間間隔為3 600 s,測試結果如圖6所示,完全可以滿足系統設計的需要。

      3 總結
          通過對定時器的誤差分析和校正.可以提高系統的精確度。當然.上面的分析是在軟環境下理想晶振頻率下實現的,在現實中會因晶振偏差等因素而造成誤差。在該測試中,主程序沒有進行其他處理,而在日歷設計中還要涉及到計時器T1的中斷來完成對掃描顯示電路的處理,還包括外部中斷對時鐘進行了調整,加上一些鬧鐘功能,這必然會對T0的定時精確性產生影響。另外.當中斷程序中語句越多,占用的機器周期也越多,因此在設計中應充分利用Keil uVision3的分析工具,通過多次調整計數初值以獲取精確的時鐘信號,這對于要求精確時鐘信號的應用具有重要的意義。

      Tags:單片機時鐘,單片機日歷,keil c,單片機  
      責任編輯:admin
    4. 上一篇文章: 沒有了
    5. 下一篇文章:
    6. 請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
      1分 2分 3分 4分 5分

      還可以輸入 200 個字
      [ 查看全部 ] 網友評論
      推薦文章
      最新推薦
      熱門文章
      關于我們 - 聯系我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁面
      下到頁底
      晶體管查詢
      主站蜘蛛池模板: 亚洲综合小说另类图片动图| 一本色道久久综合狠狠躁 | 亚洲五月综合网色九月色| 狠狠狠色丁香婷婷综合久久俺| 久久综合五月婷婷| 色噜噜狠狠色综合欧洲selulu| HEYZO无码综合国产精品227| 日本道色综合久久影院| 天天欲色成人综合网站| 亚洲综合网站色欲色欲| 色综合久久88色综合天天| 一本色道久久88加勒比—综合| 天天综合在线观看| 久久综合国产乱子伦精品免费| 五月天色婷婷综合| 狠狠色综合TV久久久久久| 亚洲欧美熟妇综合久久久久 | 一本一道久久综合久久| 久久99国产综合精品免费| 丁香五月缴情综合网| 久久婷婷午色综合夜啪| 久久久久久久综合| 91精品综合久久久久久五月天| 97久久综合精品久久久综合| 色婷婷五月综合丁香中文字幕 | 亚洲国产精品综合久久网络 | 亚洲综合激情视频| 久久综合综合久久综合| 99精品国产综合久久久久五月天| 狠狠色丁香婷婷综合潮喷 | 亚洲狠狠婷婷综合久久蜜芽| 亚洲国产综合专区电影在线 | 亚洲欧洲国产成人综合在线观看| 色综合天天综合高清网| 六月婷婷激情综合| 九九久久99综合一区二区| 狠狠色伊人亚洲综合成人| 激情综合亚洲色婷婷五月| 色综合久久天天综合绕观看| 丁香伊人五月综合激激激| 久久综合久久精品|