標題: 采用單片機定時器0的工作方式1寫一段5ms的延時函數,請大家?guī)臀铱纯茨睦锍隽藛栴}? [打印本頁]

作者: tongguan123    時間: 2023-5-18 01:20
標題: 采用單片機定時器0的工作方式1寫一段5ms的延時函數,請大家?guī)臀铱纯茨睦锍隽藛栴}?
一:問題描述
按照文中單片機代碼編譯下載后,P1口LED不閃爍,一直亮。然后通過Keil uVision5軟件仿真,延時時間也不是期望的0.5s。請大家?guī)臀铱纯词窃趺椿厥拢?br />
二:硬件環(huán)境
STC12C2052AD  //12MHz  //P1口外接LED
采用定時器0的工作方式1寫一段延時5ms的函數,然后調用延時函數,使P1口外接的LED每0.5s閃爍一次。

三:軟件環(huán)境
Keil uVision5

四:示例代碼如下(采用查詢方法)
  1. #include <STC12C2052AD.H>

  2. //以下是采用定時器0的 5ms延時函數
  3. void delay(unsigned int i)      //延時程序,i是形式參數
  4. {
  5.         TMOD = 0X01;                 //設定定時器0為工作方式1
  6.         IE    = 0X00;                 //禁止中斷
  7.         TR0 = 1;                    //啟動定時器0
  8.         while(i != 0)               //執(zhí)行i次循環(huán)
  9.         {
  10.                 TH0 = 0XEC;
  11.                 TL0 = 0X78;               //設定計數脈沖為XX次
  12.                 while(TF0 != 1);         //計時時間不到,等待;計時時間到,計數溢出位置1,即TF0=1
  13.                 i--;                      //循環(huán)次數減1
  14.         }
  15.         TR0 = 0;                   //關閉定時器0
  16. }

  17. //以下是主程序
  18. void main()
  19. {
  20.         for(;;)
  21.         {
  22.                 P1 = 0X00;          //P1口LED全亮
  23.                 delay(100);         //延時100*5ms=0.5s
  24.                 P1 = 0XFF;         //P1口LED全滅
  25.                 delay(100);         //延時100*5ms=0.5s
  26.         }
  27. }
復制代碼

五:定時器0的工作方式1初值計算如下:


六:Keil設置如下:


七:軟件仿真如下:


八:自己挖的坑自己填!
仔細對照書中代碼,發(fā)現少了一句,如下:


九:程序重新編譯下載后,雖然LED閃爍了,但是軟件仿真結果還不是期望的0.5s,不知道怎么回事?希望大家?guī)臀铱纯矗《嘀x了!


作者: 人工置頂員    時間: 2023-5-18 17:37
頂一下
作者: tongguan123    時間: 2023-5-18 18:41
頂啥呢,有時間幫我看看嘍,分析一下,我是真沒轍了。先感謝一下!
作者: wulin    時間: 2023-5-18 20:54
tongguan123 發(fā)表于 2023-5-18 18:41
頂啥呢,有時間幫我看看嘍,分析一下,我是真沒轍了。先感謝一下!

樓主這個定時器用法是哪個老師教的?
  1. #include <STC12C2052AD.H>

  2. void Timer0Init(void)                //5毫秒@12.000MHz
  3. {
  4.         AUXR &= 0x7F;                //定時器時鐘12T模式
  5.         TMOD &= 0xF0;                //設置定時器模式
  6.         TMOD |= 0x01;                //設置定時器模式
  7.         TL0 = 0x78;                //設置定時初始值
  8.         TH0 = 0xEC;                //設置定時初始值
  9.         TF0 = 0;                //清除TF0標志
  10.         TR0 = 1;                //定時器0開始計時
  11. }


  12. //以下是主程序
  13. void main()
  14. {
  15.         unsigned char num;
  16.         Timer0Init();
  17.         while(1)
  18.         {
  19.                 if(TF0)
  20.                 {
  21.                         TF0=0;
  22.                         TL0 = 0x78;                //設置定時初始值
  23.                         TH0 = 0xEC;                //設置定時初始值
  24.                         num++;
  25.                         if(num==100)
  26.                         {
  27.                                 num=0;
  28.                                 P1=~P1;//P1口取反
  29.                         }
  30.                 }       
  31.         }
  32. }
復制代碼

作者: ydatou    時間: 2023-5-19 09:14
軟件仿真使用stc芯片有問題,要改用通用芯片。
作者: yzwzfyz    時間: 2023-5-19 09:28
1、定時器的時鐘源是晶振,所以需以根據晶振的頻率不計算時間常數。
2、while(TF0 != 1);         是等待計數溢出位TF=1,是可以等到的,但它不會自動清0,也即從此后一直為1。因為以后的while(TF0 != 1)會被路過。
3、是外話。這種程序方式延時,嚴重占用CPU資源,與DELAY并無二樣,失去了定時器的設計初衷。
4、較好的做法是,將時常數計算并設計到5ms,起動中斷。如此每5ms產生一次中斷,在中斷服務中做個標記B5MS。主程序憑B5MS標記處理事件,完成后清除B5MS標記。如果處理的事件用時不長,如僅開關一個燈?梢圆挥肂5MS標記,而直接在中斷服務程序中處理。
作者: lkc8210    時間: 2023-5-19 10:09
可能是Keil對STC12的速度有點誤會
設定500ms,仿真125ms,快了4倍
把12M改為3Mhz就行了
作者: tongguan123    時間: 2023-5-19 11:40
wulin 發(fā)表于 2023-5-18 20:54
樓主這個定時器用法是哪個老師教的?
你好,大俠:        首先非常感謝你花時間回答我的問題,再次表示衷心的感謝!通過對你提供的代碼進行編譯下載后,P1口的LED燈也確實閃爍了,但我對你的代碼在Keil軟件中仿真,發(fā)現時間好像還不是期望的0.5s,也不知是我仿真方法的問題,還是怎么回事?圖片如下:
   

       其次呢,關于示例代碼我也是參考別的資料的,原本它使用的是AT的單片機,里面沒有這個關于輔助寄存器AUXR的配置,但我確實使用的是STC12C2052AD,我的示例代碼中,沒有對其進行配置,那默認值就是0,即復位后定時器0和定時器1就是傳統(tǒng)8051,即12分頻。所以沒有配置這個寄存器,好像也沒關系,但最好還是進行配置,你說對吧?


      然后你能不能對你的代碼仿真試一下,或編譯下載試試,看看到底是不是期望的0.5s。我這里沒有合適的測量工具,只能寄希望于你了。當然是在你有時間并且愿意的情況下。
      最后,還是要感謝你無私的分享與幫助,無以言表,只能祝你工作順利、開開心心!


作者: tongguan123    時間: 2023-5-19 11:42
ydatou 發(fā)表于 2023-5-19 09:14
軟件仿真使用stc芯片有問題,要改用通用芯片。
Really?這個我還真不知道!
作者: tongguan123    時間: 2023-5-19 11:45
lkc8210 發(fā)表于 2023-5-19 10:09
可能是Keil對STC12的速度有點誤會
設定500ms,仿真125ms,快了4倍
把12M改為3Mhz就行了
這是什么道理?以前有遇到過同類問題嗎???
作者: tongguan123    時間: 2023-5-19 11:48
ydatou 發(fā)表于 2023-5-19 09:14
軟件仿真使用stc芯片有問題,要改用通用芯片。

你以前處理過類似的問題嗎?
作者: tongguan123    時間: 2023-5-19 12:03
yzwzfyz 發(fā)表于 2023-5-19 09:28
1、定時器的時鐘源是晶振,所以需以根據晶振的頻率不計算時間常數。
2、while(TF0 != 1);         是等待 ...
首先感謝分享與幫助!我是最近學習學到定時器這里,想充分理解它,查詢功能和中斷功能都要學習。實際使用中,當然會用定時器的中斷功能,這里使用的查詢功能,產生延時的效果,只是理解寄存器的相關配置。
1:定時功能的計數脈沖選擇的是內部時鐘(或分頻、或不分頻)得到;
     計數功能的計數脈沖當然是外部脈沖信號了。
2:定時器0的計數溢出標志位TF0在計數溢出后,如果要產生延時,需要軟件清零,然后再定義個循環(huán)變量,達到延時效果。

作者: lym_tb_1    時間: 2023-5-19 12:11
STC12C2052AD應該是1T單片機吧,計數初值搞錯了
作者: wulin    時間: 2023-5-19 12:13
tongguan123 發(fā)表于 2023-5-19 11:40
你好,大俠:        首先非常感謝你花時間回答我的問題,再次表示衷心的感謝!通過對你提供的代碼進行編 ...

這個程序在實物上運行沒有任何問題,AUXR &= 0x7F;也可以省略,其默認就是12T。Keil軟件仿真STC1T單片機結果不一定符合實際。
作者: Longan.Wang    時間: 2023-5-19 14:11
好久沒用51了,圍觀一下
作者: tongguan123    時間: 2023-5-19 14:13
lym_tb_1 發(fā)表于 2023-5-19 12:11
STC12C2052AD應該是1T單片機吧,計數初值搞錯了


作者: tongguan123    時間: 2023-5-19 14:15
wulin 發(fā)表于 2023-5-19 12:13
這個程序在實物上運行沒有任何問題,AUXR &= 0x7F;也可以省略,其默認就是12T。Keil軟件仿真STC1T單片機 ...
再次感謝指導!
作者: tongguan123    時間: 2023-5-19 14:59
tongguan123 發(fā)表于 2023-5-19 11:42
Really?這個我還真不知道!
確實如你所說,我將設備改成傳統(tǒng)8051,不管是用我的代碼,還是上面一位大俠提供的代碼,在Keil里面軟件仿真,都是我所期望的0.5S。我的代碼仿真如下:


大俠的代碼仿真如下:






作者: tongguan123    時間: 2023-5-19 15:08
wulin 發(fā)表于 2023-5-18 20:54
樓主這個定時器用法是哪個老師教的?
你好,我聽從上面一位熱心朋友的建議,將STC改成傳統(tǒng)8051單片機,然后使用你的代碼軟件仿真,得到了期望的0.5s.效果如下:




作者: tongguan123    時間: 2023-5-19 15:10
tongguan123 發(fā)表于 2023-5-19 11:42
Really?這個我還真不知道!
再次感謝分享!

作者: tongguan123    時間: 2023-5-19 15:24
ydatou 發(fā)表于 2023-5-19 09:14
軟件仿真使用stc芯片有問題,要改用通用芯片。

不好意思,我剛才自己給自己回復了,沒傳達給你我的謝意,again。首先感謝你的分享與建議!按照你的方法,得到了期望的延時效果(0.5s),
使用我的代碼進行軟件仿真,效果如下:



使用上面一位大俠代碼進行軟件仿真,效果如下:





作者: tongguan123    時間: 2023-5-19 16:01
ydatou 發(fā)表于 2023-5-19 09:14
軟件仿真使用stc芯片有問題,要改用通用芯片。
感謝你的話不知被我回復到哪里去了?我暈!根據你的方法,問題解決了。再次感謝!





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1