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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3973|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

關(guān)于單片機(jī)定時(shí)器中斷解決數(shù)碼管抖動(dòng)的問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:683645 發(fā)表于 2020-1-8 16:07 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我有個(gè)疑問(wèn):當(dāng)cnt=1000時(shí),執(zhí)行循環(huán)中的語(yǔ)句,當(dāng)中斷觸發(fā)時(shí)進(jìn)入中斷,執(zhí)行動(dòng)態(tài)刷新數(shù)碼管程序,但是萬(wàn)一跳出去時(shí),LedBuff[5]這個(gè)數(shù)組沒(méi)有計(jì)算更新完的話,那么進(jìn)入中斷時(shí)位選數(shù)碼管但是賦給P0的值沒(méi)有更新到最新的值豈不是會(huì)有數(shù)碼管秒數(shù)顯示錯(cuò)誤?除非一個(gè)理由可以解釋,就是程序執(zhí)行那一段32位整型數(shù)的除法運(yùn)算的運(yùn)行時(shí)間小于1ms,但是我調(diào)試了代碼發(fā)現(xiàn)這段32位整型數(shù)的除法運(yùn)算程序運(yùn)行時(shí)長(zhǎng)長(zhǎng)達(dá)3ms,希望大佬指點(diǎn)一下
  1. #include <reg52.h>

  2. sbit ADDR0 = P1^0;
  3. sbit ADDR1 = P1^1;
  4. sbit ADDR2 = P1^2;
  5. sbit ADDR3 = P1^3;
  6. sbit ENLED = P1^4;

  7. unsigned char code LedChar[] =
  8. {  //數(shù)碼管顯示字符轉(zhuǎn)換表     
  9.                 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,     
  10.     0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  11. };
  12. unsigned char LedBuff[6] =
  13. {  //數(shù)碼管顯示緩沖區(qū),初值 0xFF 確保啟動(dòng)時(shí)都不亮     
  14.                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  15. };

  16. void main()
  17. {     
  18.         unsigned char i = 0;    //動(dòng)態(tài)掃描的索引     
  19.         unsigned int  cnt = 0;  //記錄 T0 中斷次數(shù)     
  20.         unsigned long sec = 0;  //記錄經(jīng)過(guò)的秒數(shù)

  21.   ENLED = 0;    //使能 U3,選擇控制數(shù)碼管     
  22.         ADDR3 = 1;    //因?yàn)樾枰獎(jiǎng)討B(tài)改變 ADDR0-2 的值,所以不需要再初始化了     
  23.         TMOD = 0x01;  //設(shè)置 T0 為模式 1     
  24.         TH0  = 0xFC;  //為 T0 賦初值 0xFC67,定時(shí) 1ms     
  25.         TL0  = 0x67;     
  26.         TR0  = 1;     //啟動(dòng) T0         
  27.         while (1)
  28.         {         
  29.                 if (TF0 == 1)         //判斷 T0 是否溢出         
  30.                 {             TF0 = 0;           //T0 溢出后,清零中斷標(biāo)志            
  31.                         TH0 = 0xFC;       //并重新賦初值            
  32.                         TL0 = 0x67;            
  33.                         cnt++;              //計(jì)數(shù)值自加 1            
  34.                         if (cnt >= 1000)  //判斷 T0 溢出是否達(dá)到 1000 次            
  35.                         {                                 
  36.                                 sec++;         //秒計(jì)數(shù)自加 1                 
  37.                                 //以下代碼將 sec 按十進(jìn)制位從低到高依次提取并轉(zhuǎn)為數(shù)碼管顯示字符           //這段運(yùn)行時(shí)長(zhǎng)大概3ms
  38.                                 LedBuff[0] = LedChar[sec%10];                 
  39.                                 LedBuff[1] = LedChar[sec/10%10];                 
  40.                                 LedBuff[2] = LedChar[sec/100%10];                 
  41.                                 LedBuff[3] = LedChar[sec/1000%10];                 
  42.                                 LedBuff[4] = LedChar[sec/10000%10];                 
  43.                                 LedBuff[5] = LedChar[sec/100000%10];     
  44.         cnt = 0;       //達(dá)到 1000 次后計(jì)數(shù)值清零        
  45.                         }             //以下代碼完成數(shù)碼管動(dòng)態(tài)掃描刷新            
  46.                         switch (i)            
  47.                         {                 
  48.                                         case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;                 
  49.                                         case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;                 
  50.                                         case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;                 
  51.                                         case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;                 
  52.                                         case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;                 
  53.                 case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;                 
  54.                 default: break;            
  55.             }         
  56.           }     
  57.         }
  58. }
復(fù)制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:7485 發(fā)表于 2020-1-8 17:05 | 只看該作者
每秒大于25次掃描就不會(huì)感覺(jué)到頻閃。也就是40ms一次。這個(gè)時(shí)間夠長(zhǎng)的了。如果有長(zhǎng)延時(shí)循環(huán),就要用定時(shí)器,不可以讓單片機(jī)“當(dāng)”在那兒。
回復(fù)

使用道具 舉報(bào)

板凳
ID:213173 發(fā)表于 2020-1-8 21:36 | 只看該作者
你這不是中斷,是查詢中斷請(qǐng)求標(biāo)志。如果執(zhí)行if內(nèi)語(yǔ)句超過(guò)1ms會(huì)造成計(jì)時(shí)不準(zhǔn),超時(shí)過(guò)多還會(huì)引起數(shù)碼管閃爍。數(shù)碼管動(dòng)態(tài)顯示一輪時(shí)間不得超過(guò)20ms,6個(gè)數(shù)碼管每個(gè)顯示時(shí)間平均3.33ms。建議不要使用大數(shù)據(jù)運(yùn)算,6位十進(jìn)制數(shù)改成3段2位十進(jìn)制,控制在一個(gè)字節(jié)范圍可以明顯縮短運(yùn)算時(shí)間。使主循環(huán)查詢周期小于1ms。
回復(fù)

使用道具 舉報(bào)

地板
ID:683645 發(fā)表于 2020-1-11 15:20 | 只看該作者
額,不好意思,復(fù)制錯(cuò)代碼了,我貼一下中斷的代碼,這段代碼說(shuō)是解決了之前第一段代碼的抖動(dòng)問(wèn)題,但是我覺(jué)得利用中斷也就是下面這段代碼會(huì)有我上面說(shuō)的疑問(wèn):當(dāng)cnt=1000時(shí)也就是到了1s時(shí),執(zhí)行循環(huán)中的if語(yǔ)句,當(dāng)中斷觸發(fā)時(shí)進(jìn)入中斷也就是1s+1ms時(shí),執(zhí)行switch動(dòng)態(tài)刷新數(shù)碼管程序,但是跳出去時(shí),LedBuff[5]這個(gè)數(shù)組沒(méi)有計(jì)算完,我調(diào)試了代碼發(fā)現(xiàn)這段32位整型數(shù)的除法運(yùn)算程序運(yùn)行時(shí)長(zhǎng)長(zhǎng)達(dá)6.8ms,也就是當(dāng)?shù)?s時(shí)sec++,然后開始計(jì)算那6行32位運(yùn)算,需要6.8ms,但是6.8ms還沒(méi)到還沒(méi)算完時(shí)在1s+1ms時(shí)觸發(fā)中斷,進(jìn)入switch給P0賦值,那么進(jìn)入中斷時(shí)P0的值沒(méi)有更新到那6行32位運(yùn)算完的值豈不是會(huì)有數(shù)碼管秒數(shù)顯示錯(cuò)誤?但是,我把代碼下載到單片機(jī)里面,卻沒(méi)有顯示錯(cuò)誤,顯示是正確的,只不過(guò)我發(fā)現(xiàn)單片機(jī)的1s要更快,大概單片機(jī)上過(guò)了60s時(shí),電腦上過(guò)了61s.所以疑問(wèn):按理來(lái)說(shuō)第二段代碼解決了抖動(dòng)但應(yīng)該會(huì)有數(shù)碼管顯示錯(cuò)誤,但是下載到單片機(jī)上顯示沒(méi)有任何問(wèn)題,只是時(shí)間上有點(diǎn)不準(zhǔn),不知道為什么顯示會(huì)沒(méi)有問(wèn)題,應(yīng)該是第7個(gè)ms那6行運(yùn)算全部計(jì)算完之后P0的賦值才應(yīng)該是sec++后的正確秒數(shù)啊?難道原因是7個(gè)ms也就是刷新完一輪數(shù)碼管的時(shí)間太短暫了,把錯(cuò)誤的秒數(shù)顯示出來(lái)肉眼看不到嗎,麻煩各位大佬再幫我看一下,小弟初學(xué)乍道,勞煩各位了
  1. #include <reg52.h>

  2. //數(shù)碼管顯示字符轉(zhuǎn)換表
  3. unsigned char code LedChar[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};  //0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
  4. unsigned char LedBuff[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //數(shù)碼管顯示緩沖區(qū),初值 0xFF 確保啟動(dòng)時(shí)都不亮
  5. unsigned char code wei[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf}; //數(shù)碼管各位的碼表
  6. unsigned char i = 0;    //動(dòng)態(tài)掃描的索引     
  7. unsigned int  cnt = 0;  //記錄 T0 中斷次數(shù)
  8. //sbit dula=P2^6;                //段選信號(hào)的鎖存器控制
  9. sbit wela=P2^7;                //位選信號(hào)的鎖存器控制

  10. void main()
  11. {         
  12.         unsigned long sec = 0;  //記錄經(jīng)過(guò)的秒數(shù)
  13.         EA = 1;        //使能總中斷
  14.         ET0  = 1;     //使能 T0 中斷
  15.         TMOD = 0x01;  //設(shè)置 T0 為模式 1     
  16.         TH0  = 0xFC;  //為 T0 賦初值 0xFC67,定時(shí) 1ms     
  17.         TL0  = 0x67;     
  18.         TR0  = 1;     //啟動(dòng) T0         
  19.         while (1)
  20.         {                    
  21.                 if (cnt == 1000)  //判斷 T0 溢出是否達(dá)到 1000 次            
  22.                 {                                 
  23.                         sec++;         //秒計(jì)數(shù)自加 1                 
  24.                         //以下代碼將 sec 按十進(jìn)制位從低到高依次提取并轉(zhuǎn)為數(shù)碼管顯示字符                 
  25.                         LedBuff[0] = LedChar[sec%10];                 
  26.                         LedBuff[1] = LedChar[sec/10%10];                 
  27.                         LedBuff[2] = LedChar[sec/100%10];                 
  28.                         LedBuff[3] = LedChar[sec/1000%10];                 
  29.                         LedBuff[4] = LedChar[sec/10000%10];                 
  30.                         LedBuff[5] = LedChar[sec/100000%10];     
  31.                         cnt = 0;       //達(dá)到 1000 次后計(jì)數(shù)值清零        
  32.                 }             //以下代碼完成數(shù)碼管動(dòng)態(tài)掃描刷新
  33.         }
  34. }
  35. /* 定時(shí)器 0 中斷服務(wù)函數(shù) */
  36. void InterruptTimer0() interrupt 1
  37. {     
  38.         TH0 = 0xFC;  //重新加載初值     
  39.         TL0 = 0x67;     
  40.         cnt++;        //中斷次數(shù)計(jì)數(shù)值加 1     
  41.         //以下代碼完成數(shù)碼管動(dòng)態(tài)掃描刷新     
  42.         P0 = 0x00;   //顯示消隱     
  43.         switch (i)            
  44.         {                 
  45.                 case 0: wela=0;P0=wei[5];wela=1;wela=0;i++;P0=LedBuff[0]; break;                 
  46.                 case 1: wela=0;P0=wei[4];wela=1;wela=0;i++;P0=LedBuff[1]; break;                 
  47.                 case 2: wela=0;P0=wei[3];wela=1;wela=0;i++;P0=LedBuff[2]; break;                 
  48.                 case 3: wela=0;P0=wei[2];wela=1;wela=0;i++;P0=LedBuff[3]; break;                 
  49.                 case 4: wela=0;P0=wei[1];wela=1;wela=0;i++;P0=LedBuff[4]; break;                 
  50.                 case 5: wela=0;P0=wei[0];wela=1;wela=0;i=0;P0=LedBuff[5]; break;                 
  51.                 default: break;            
  52.         }                                           
  53. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

5#
ID:683645 發(fā)表于 2020-1-11 15:21 | 只看該作者
ahshmj 發(fā)表于 2020-1-8 17:05
每秒大于25次掃描就不會(huì)感覺(jué)到頻閃。也就是40ms一次。這個(gè)時(shí)間夠長(zhǎng)的了。如果有長(zhǎng)延時(shí)循環(huán),就要用定時(shí)器, ...

大佬,我這段代碼貼錯(cuò)了,后面進(jìn)行了補(bǔ)充,勞煩再幫我看看指點(diǎn)一下小弟
回復(fù)

使用道具 舉報(bào)

6#
ID:683645 發(fā)表于 2020-1-11 15:21 | 只看該作者
wulin 發(fā)表于 2020-1-8 21:36
你這不是中斷,是查詢中斷請(qǐng)求標(biāo)志。如果執(zhí)行if內(nèi)語(yǔ)句超過(guò)1ms會(huì)造成計(jì)時(shí)不準(zhǔn),超時(shí)過(guò)多還會(huì)引起數(shù)碼管閃爍 ...

大佬,我這段代碼貼錯(cuò)了,后面進(jìn)行了補(bǔ)充,勞煩再幫我看看指點(diǎn)一下小弟
回復(fù)

使用道具 舉報(bào)

7#
ID:213173 發(fā)表于 2020-1-11 22:16 | 只看該作者
1997肖 發(fā)表于 2020-1-11 15:21
大佬,我這段代碼貼錯(cuò)了,后面進(jìn)行了補(bǔ)充,勞煩再幫我看看指點(diǎn)一下小弟

1.你想象的沒(méi)錯(cuò),中斷會(huì)打斷主程序的運(yùn)行。緩存數(shù)組每秒更新一次,顯示函數(shù)1ms刷新1位,6ms刷新1輪。如果恰巧中斷發(fā)生時(shí),緩存數(shù)組更新到一半,數(shù)碼管顯示可能出錯(cuò),這種狀態(tài)是完全可能發(fā)生,但這個(gè)過(guò)程非常短暫,肉眼根本察覺(jué)不到。
2.《if(cnt == 1000)  //判斷 T0 溢出是否達(dá)到 1000 次》這句有缺陷。如果完成if內(nèi)語(yǔ)句需要6.8ms,那么假設(shè)某一次判斷時(shí)cnt = 999,等到下一次判斷時(shí)cnt已經(jīng)是1005,這樣就會(huì)丟秒,一直加到溢出。所以計(jì)時(shí)會(huì)慢許多。正確寫法是:if(cnt >= 1000),或者放在中斷里判斷清0cnt并輸出一個(gè)標(biāo)志。
回復(fù)

使用道具 舉報(bào)

8#
ID:683645 發(fā)表于 2020-1-12 14:12 | 只看該作者
wulin 發(fā)表于 2020-1-11 22:16
1.你想象的沒(méi)錯(cuò),中斷會(huì)打斷主程序的運(yùn)行。緩存數(shù)組每秒更新一次,顯示函數(shù)1ms刷新1位,6ms刷新1輪。如果 ...

謝謝大佬,原來(lái)的問(wèn)題我現(xiàn)在清楚了,只是因?yàn)槿庋鄄煊X(jué)不到。但是您指出的cnt=999時(shí),為什么等到下一次判斷時(shí)cnt為1005了呢,這里我不太明白,cnt=999時(shí),if語(yǔ)句里面的程序沒(méi)有執(zhí)行啊,所以那6.8ms在cnt=999時(shí)沒(méi)有執(zhí)行,所以下一次判斷cnt還是為1000吧?而且我覺(jué)得盡管這里有6.8ms,但是每隔1ms進(jìn)入中斷cnt++,所以我覺(jué)得這6.8ms影響不到這個(gè)1000次1ms的計(jì)時(shí),也就是說(shuō)1s的時(shí)間按我的想法也應(yīng)該是準(zhǔn)確的吧?只是前7ms每隔1ms進(jìn)入一次中斷之后繼續(xù)執(zhí)行6.8ms的代碼然后再進(jìn)入中斷再執(zhí)行6.8ms的代碼直到這段代碼運(yùn)算結(jié)束,前7ms同時(shí)完成了6.8ms的程序運(yùn)算也完成了7次中斷掃描數(shù)碼管。這是我的分析和想法,有什么錯(cuò)誤或者考慮不全的地方還希望前輩不吝賜教,謝謝
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 午夜一区 | 中文字幕一区二区三区不卡在线 | 四虎影视1304t | 99热激情| 久久久久久久国产精品 | 精品久久国产 | 国产电影一区二区 | 日本不卡免费新一二三区 | 亚洲成人福利视频 | 一区二区三区视频免费观看 | 2021狠狠干| 日韩精品一区二区三区在线播放 | 国产免费播放视频 | 精品欧美一区二区三区 | 成人一区二区三区视频 | 成人在线视频网 | 久久精品亚洲一区 | 久久丝袜| 特级做a爰片毛片免费看108 | 毛片免费看 | 一区二区三区成人 | 久草精品视频 | 91精品亚洲 | 欧美国产精品 | 亚洲黄色片免费观看 | 欧美一级在线 | 日本视频在线 | 日屁视频 | 嫩草视频免费 | 日韩一区在线播放 | 午夜影院在线观看 | 免费在线国产视频 | 色欧美综合 | 国产精品久久久久久久久久尿 | 国产免费一区二区三区免费视频 | 久久久久久久久91 | 日韩专区中文字幕 | 97精品超碰一区二区三区 | 中文天堂在线一区 | 亚洲福利一区二区 | 久久久久久久久久一区 |