久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4680|回復: 20
收起左側

STC單片機定時器延時用官方程序快約5倍是什么原因?

  [復制鏈接]
ID:970121 發表于 2021-10-28 09:51 | 顯示全部樓層 |閱讀模式
STC單片機定時器延時用官方程序快約5倍是什么原因?
運行是正常的,就是延時快約5倍,定時器是1ms,中斷1000次就應該是1秒了,但LED燈閃爍很快,我將中斷修改到5000次,閃爍才象是1秒閃1次的樣子,是那里出錯了?

  1. unsigned int t;

  2. sbit led=P2^0;


  3. void Timer0Init(void)                //1毫秒@18.432MHz
  4. {
  5.         AUXR |= 0x80;                //定時器時鐘1T模式
  6.         TMOD &= 0xF0;                //設置定時器模式
  7.         TL0 = 0x00;                //設置定時初始值
  8.         TH0 = 0xB8;                //設置定時初始值
  9.         TF0 = 0;                //清除TF0標志
  10.         TR0 = 1;                //定時器0開始計時

  11.       
  12.   ET0=1;//打開定時器1中斷允許
  13.   EA=1;//打開總中斷
  14.                   
  15. }
  16. void main()
  17. {      
  18.         Timer0Init();//定時器0初始化
  19.         while(1)
  20.         {
  21.                 if(t == 1000)    //中斷1000*1ms=1s
  22.                 {
  23.                         t=0;
  24.                         led=~led;
  25.                 }
  26.         }               
  27. }
  28. void Timer0() interrupt 1
  29. {
  30.         TL0 = 0x00;                //設置定時初始值
  31.         TH0 = 0xB8;                //設置定時初始值
  32.         t++;
  33. }
復制代碼



回復

使用道具 舉報

ID:624769 發表于 2021-10-28 13:27 | 顯示全部樓層
你往機器里燒的時候,晶振選的是18.432么?
回復

使用道具 舉報

ID:161164 發表于 2021-10-28 14:42 | 顯示全部樓層
和我遇到的情況差不多STC 1T單片機的奇怪情況
中斷打斷了比較邏輯
提早進入了if( t == 0)
這樣改看看

  1. unsigned int t;

  2. sbit led=P2^0;
  3. bit t_DN;

  4. void Timer0Init(void)                //1毫秒@18.432MHz
  5. {
  6.         AUXR |= 0x80;                //定時器時鐘1T模式
  7.         TMOD &= 0xF0;                //設置定時器模式
  8.         TL0 = 0x00;                //設置定時初始值
  9.         TH0 = 0xB8;                //設置定時初始值
  10.         TF0 = 0;                //清除TF0標志
  11.         TR0 = 1;                //定時器0開始計時

  12.       
  13.   ET0=1;//打開定時器1中斷允許
  14.   EA=1;//打開總中斷
  15.                   
  16. }
  17. void main()
  18. {      
  19.         Timer0Init();//定時器0初始化
  20.         while(1)
  21.         {
  22.                 if(t_DN)
  23.                 {
  24.                         t_DN=0;
  25.                         led=~led;
  26.                 }
  27.         }               
  28. }
  29. void Timer0() interrupt 1
  30. {
  31.         //TL0 = 0x00;                //設置定時初始值
  32.         //TH0 = 0xB8;                //設置定時初始值
  33.                 //TMOD &= 0xF0; 是自動重裝
  34.         if(++t == 1000)    //中斷1000*1ms=1s
  35.                 {
  36.                         t = 0;
  37.                         t_DN = 1;
  38.                 }
  39. }
復制代碼



回復

使用道具 舉報

ID:970121 發表于 2021-10-28 14:45 | 顯示全部樓層
188610329 發表于 2021-10-28 13:27
你往機器里燒的時候,晶振選的是18.432么?

板載晶振,沒有用內置的,示波器測過,晶振頻率很準,
回復

使用道具 舉報

ID:123289 發表于 2021-10-28 14:47 | 顯示全部樓層
加一個標記:BJ。
在中斷服務程序,判斷:當t=1000時,置位BJ=1。并將t回0。
在主程序中:以BJ=1,決定LED燈的反轉,并將BJ清0。
如果成功了,下次告訴你為什么。
回復

使用道具 舉報

ID:213173 發表于 2021-10-28 16:28 | 顯示全部樓層
本帖最后由 wulin 于 2021-10-28 16:47 編輯
  1. #include <reg51.H>

  2. sfr AUXR = 0x8e;

  3. sbit led=P2^0;

  4. unsigned int t;

  5. void Timer0Init(void)    //1毫秒@18.432MHz
  6. {//下載用戶程序時去掉選擇內部時鐘的勾
  7.         AUXR |= 0x80;         //定時器時鐘1T模式
  8.         TMOD &= 0xF0;         //設置定時器自動重裝模式!!!
  9.         TL0 = 0x00;           //設置定時初始值
  10.         TH0 = 0xB8;           //設置定時初始值
  11.         TF0 = 0;              //清除TF0標志
  12.         TR0 = 1;              //定時器0開始計時
  13. //        ET0=1;//打開定時器1中斷允許
  14. //        EA=1;//打開總中斷
  15. }
  16. void main()
  17. {      
  18.         Timer0Init();//定時器0初始化
  19.         while(1)
  20.         {
  21.                 if(TF0==1)
  22.                 {
  23.                         TF0=0;
  24.                         if(++t>=1000)    //中斷1000*1ms=1s
  25.                         {
  26.                                 t=0;
  27.                                 led=~led;
  28.                         }
  29.                 }
  30.         }               
  31. }
  32. /*
  33. void Timer0() interrupt 1
  34. {
  35.         TL0 = 0x00;                //設置定時初始值
  36.         TH0 = 0xB8;                //設置定時初始值
  37.         t++;
  38. }
  39. */
復制代碼
回復

使用道具 舉報

ID:970121 發表于 2021-10-28 17:08 | 顯示全部樓層
lkc8210 發表于 2021-10-28 14:42
和我遇到的情況差不多STC 1T單片機的奇怪情況
中斷打斷了比較邏輯
提早進入了if( t == 0)

這樣改真的可以了!有個小插曲,測下測下,可能有靜電,下載板燒壞了,剛修好才驗證,的確正常了。
回復

使用道具 舉報

ID:970121 發表于 2021-10-28 17:11 | 顯示全部樓層
yzwzfyz 發表于 2021-10-28 14:47
加一個標記:BJ。
在中斷服務程序,判斷:當t=1000時,置位BJ=1。并將t回0。
在主程序中:以BJ=1,決定LE ...

你這個是對的,二樓也是這樣做,經過驗證,是能正確延時了!問題隨然解決,但還不了解發生的原因,等大師科普知識!
回復

使用道具 舉報

ID:975745 發表于 2021-10-28 17:25 | 顯示全部樓層
中斷模式設置12T試試
回復

使用道具 舉報

ID:401564 發表于 2021-10-28 20:49 | 顯示全部樓層
絲瓜偵探 發表于 2021-10-28 17:11
你這個是對的,二樓也是這樣做,經過驗證,是能正確延時了!問題隨然解決,但還不了解發生的原因,等大師 ...

if(t == 1000)
這個邏輯本身就是錯的
t是在中斷中增加
如果程序還沒有跑到if(t == 1000) 之前,t的值就已經大于1000了,那就錯過了,t就會在1000的基礎之上一直向上加,結果如何不知道,也不想知道,就知道是不對的
應該是比大小,不是求相等,if(t == 1000) 是查找,不是比較
回復

使用道具 舉報

ID:123289 發表于 2021-10-29 09:39 | 顯示全部樓層
如果你了解匯編語句,會對你的理解有幫助。所以不懂匯編是不能稱為精通單片機的。
C語言t=1000中的t,在CPU中必須用兩個字節來表示,不妨起個名子叫NH和NL。t=NH,NL
你的主程序一直在等t=1000,也就等(NH,NL,16進制)=03E8H,但是CPU指令只能一個一個的判斷,假設先判斷NH=03,而后再判斷NL=E8,邏輯上是沒有毛病的。
你的中斷是每1ms一次,中斷發生時,你的程序運行到什么地方了呢?不太好確定吧,你的程序一直在等t=1000,估計多半會在此處中斷。
注意,有個關鍵的特殊事件發生了,而且發生的概率還不了(程序不長)。
中斷發生在CPU已判斷了NH,還未判定NL。而中斷服務程序會做t++,也即(NH,NL)+1,這就修改NL的值,問題來了。
例如:原先(NH,NL)=1000 = 03E8H,程序已確定NH=03,如果NL=E8,就反轉LED燈。
但是中斷發生在NH=03判斷之后,而NL還未判定,中斷時你將t++,也即(NH,NL)++,變成了 03E9H,中斷返回后,再判斷NL卻不是E8,而是E9了。
如此,程序不會再做LED反轉了。t將=1001,此后被加到65535,再回0,下次再加到1000。
也即,只要t=1000時發生中斷,如果中斷發生在主程序判斷:NH=03與NL=E8之間。則本次LED的顯示,就會超出你的預期!而且t會走向65535,再回0。

評分

參與人數 1黑幣 +15 收起 理由
dalaoshi + 15 很給力!

查看全部評分

回復

使用道具 舉報

ID:964308 發表于 2021-10-29 11:00 來自觸屏版 | 顯示全部樓層
晶振選對了嗎
回復

使用道具 舉報

ID:970121 發表于 2021-10-29 14:07 | 顯示全部樓層
哈尼小可愛 發表于 2021-10-28 17:25
中斷模式設置12T試試

一樣的
回復

使用道具 舉報

ID:970121 發表于 2021-10-29 14:09 | 顯示全部樓層
Y_G_G 發表于 2021-10-28 20:49
if(t == 1000)
這個邏輯本身就是錯的
t是在中斷中增加

有道理!在程序大時的確可能會產生問題,但現在就這一個1ms中斷測試,不會影響它判斷,是別的問題
回復

使用道具 舉報

ID:970121 發表于 2021-10-29 14:13 | 顯示全部樓層
yzwzfyz 發表于 2021-10-29 09:39
如果你了解匯編語句,會對你的理解有幫助。所以不懂匯編是不能稱為精通單片機的。
C語言t=1000中的t,在CP ...

理是這個理,但那應該是慢一倍以上,而不是快呀,搞得我現在還弄不明白那里的問題。
回復

使用道具 舉報

ID:970121 發表于 2021-10-29 14:13 | 顯示全部樓層

對的,外部晶振,用示波器測過,正確!
回復

使用道具 舉報

ID:959346 發表于 2021-10-29 14:51 | 顯示全部樓層
絲瓜偵探 發表于 2021-10-29 14:13
理是這個理,但那應該是慢一倍以上,而不是快呀,搞得我現在還弄不明白那里的問題。

一個可能是在判斷到一半時中斷了,另一個可能是在清零到一半時中斷了,具體看一下編譯后的匯編代碼,再分析一下就知道了。
回復

使用道具 舉報

ID:401564 發表于 2021-10-29 15:25 | 顯示全部樓層
絲瓜偵探 發表于 2021-10-29 14:09
有道理!在程序大時的確可能會產生問題,但現在就這一個1ms中斷測試,不會影響它判斷,是別的問題

邏輯是跟定時器時間長短沒有關系的
我把你的代碼完全復制到STC8A4K上運行,并沒有你說的快5倍
實際閃燈的頻率是大概1秒左右,因為沒有儀器,只能是個大概
那么,我有理由認為,你代碼的其它地方有問題,把完整的上傳看一下
單片機是很少有問題的,絕大多數的問題是代碼的問題
回復

使用道具 舉報

ID:123289 發表于 2021-10-30 11:17 | 顯示全部樓層
只是舉了一個特例是這樣,CPU判定t=1000的方式也可能是采用的是其它方案。
這里強調的是:會在t=1000的判定上,因中斷的介入而出現非常的情況。
如果你要窮盡原因,就去分析編譯后的匯編語句!
這一點也不難辦到,好在程序也不長,就看你愿不愿意去分析了。
回復

使用道具 舉報

ID:160500 發表于 2021-10-30 11:35 | 顯示全部樓層
同一個全局變量在中斷和主程序里都要改變它的值,如果考慮不全面非常容易出現數據錯誤。一般不建議這樣使用。
回復

使用道具 舉報

ID:881715 發表于 2021-10-30 11:51 來自觸屏版 | 顯示全部樓層
yzwzfyz 發表于 2021-10-29 09:39
如果你了解匯編語句,會對你的理解有幫助。所以不懂匯編是不能稱為精通單片機的。
C語言t=1000中的t,在CP ...

大神,您能提供點與單片機編程相關的匯編基礎的書或資料嗎?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美在线成人影院 | 欧美视频免费 | 亚洲欧洲精品在线 | 亚洲毛片在线 | 日韩精品免费视频 | 国产美女在线观看 | 一区二区三区四区av | 国产97久久 | 亚洲视频中文字幕 | 国产精品视频网站 | 久久久久国产精品一区三寸 | 欧美黑人国产人伦爽爽爽 | 国产一区二区影院 | 国产91精品久久久久久久网曝门 | 久久不卡视频 | 精品一区二区在线观看 | 欧美一级欧美一级在线播放 | 欧美激情在线观看一区二区三区 | 91视频进入 | 国产区在线 | 在线一级片 | 91色在线| 在线日韩欧美 | 爱爱视频日本 | 精品欧美一区二区三区久久久 | 亚洲日韩欧美一区二区在线 | 久草电影网 | 日本淫视频 | 日本精品一区二区三区在线观看视频 | 亚洲一区在线观看视频 | 黄色成人国产 | 久久日韩粉嫩一区二区三区 | 81精品国产乱码久久久久久 | 国产一区二区久久 | 欧美一级片在线看 | 国产一级淫片免费视频 | 97精品国产97久久久久久免费 | 人人九九精 | 人人爱干| 日韩中文字幕一区 | 综合久久99 |