亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

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

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:683645 發(fā)表于 2020-1-8 16:07 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
我有個(gè)疑問:當(dāng)cnt=1000時(shí),執(zhí)行循環(huán)中的語句,當(dāng)中斷觸發(fā)時(shí)進(jìn)入中斷,執(zhí)行動(dòng)態(tài)刷新數(shù)碼管程序,但是萬一跳出去時(shí),LedBuff[5]這個(gè)數(shù)組沒有計(jì)算更新完的話,那么進(jìn)入中斷時(shí)位選數(shù)碼管但是賦給P0的值沒有更新到最新的值豈不是會有數(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í)長長達(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)過的秒數(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í)長大概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次掃描就不會感覺到頻閃。也就是40ms一次。這個(gè)時(shí)間夠長的了。如果有長延時(shí)循環(huán),就要用定時(shí)器,不可以讓單片機(jī)“當(dāng)”在那兒。
回復(fù)

使用道具 舉報(bào)

板凳
ID:213173 發(fā)表于 2020-1-8 21:36 | 只看該作者
你這不是中斷,是查詢中斷請求標(biāo)志。如果執(zhí)行if內(nèi)語句超過1ms會造成計(jì)時(shí)不準(zhǔn),超時(shí)過多還會引起數(shù)碼管閃爍。數(shù)碼管動(dòng)態(tài)顯示一輪時(shí)間不得超過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ò)代碼了,我貼一下中斷的代碼,這段代碼說是解決了之前第一段代碼的抖動(dòng)問題,但是我覺得利用中斷也就是下面這段代碼會有我上面說的疑問:當(dāng)cnt=1000時(shí)也就是到了1s時(shí),執(zhí)行循環(huán)中的if語句,當(dāng)中斷觸發(fā)時(shí)進(jìn)入中斷也就是1s+1ms時(shí),執(zhí)行switch動(dòng)態(tài)刷新數(shù)碼管程序,但是跳出去時(shí),LedBuff[5]這個(gè)數(shù)組沒有計(jì)算完,我調(diào)試了代碼發(fā)現(xiàn)這段32位整型數(shù)的除法運(yùn)算程序運(yùn)行時(shí)長長達(dá)6.8ms,也就是當(dāng)?shù)?s時(shí)sec++,然后開始計(jì)算那6行32位運(yùn)算,需要6.8ms,但是6.8ms還沒到還沒算完時(shí)在1s+1ms時(shí)觸發(fā)中斷,進(jìn)入switch給P0賦值,那么進(jìn)入中斷時(shí)P0的值沒有更新到那6行32位運(yùn)算完的值豈不是會有數(shù)碼管秒數(shù)顯示錯(cuò)誤?但是,我把代碼下載到單片機(jī)里面,卻沒有顯示錯(cuò)誤,顯示是正確的,只不過我發(fā)現(xiàn)單片機(jī)的1s要更快,大概單片機(jī)上過了60s時(shí),電腦上過了61s.所以疑問:按理來說第二段代碼解決了抖動(dòng)但應(yīng)該會有數(shù)碼管顯示錯(cuò)誤,但是下載到單片機(jī)上顯示沒有任何問題,只是時(shí)間上有點(diǎn)不準(zhǔn),不知道為什么顯示會沒有問題,應(yīng)該是第7個(gè)ms那6行運(yùn)算全部計(jì)算完之后P0的賦值才應(yīng)該是sec++后的正確秒數(shù)啊?難道原因是7個(gè)ms也就是刷新完一輪數(shù)碼管的時(shí)間太短暫了,把錯(cuò)誤的秒數(shù)顯示出來肉眼看不到嗎,麻煩各位大佬再幫我看一下,小弟初學(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;                //段選信號的鎖存器控制
  9. sbit wela=P2^7;                //位選信號的鎖存器控制

  10. void main()
  11. {         
  12.         unsigned long sec = 0;  //記錄經(jīng)過的秒數(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次掃描就不會感覺到頻閃。也就是40ms一次。這個(gè)時(shí)間夠長的了。如果有長延時(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
你這不是中斷,是查詢中斷請求標(biāo)志。如果執(zhí)行if內(nèi)語句超過1ms會造成計(jì)時(shí)不準(zhǔn),超時(shí)過多還會引起數(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.你想象的沒錯(cuò),中斷會打斷主程序的運(yùn)行。緩存數(shù)組每秒更新一次,顯示函數(shù)1ms刷新1位,6ms刷新1輪。如果恰巧中斷發(fā)生時(shí),緩存數(shù)組更新到一半,數(shù)碼管顯示可能出錯(cuò),這種狀態(tài)是完全可能發(fā)生,但這個(gè)過程非常短暫,肉眼根本察覺不到。
2.《if(cnt == 1000)  //判斷 T0 溢出是否達(dá)到 1000 次》這句有缺陷。如果完成if內(nèi)語句需要6.8ms,那么假設(shè)某一次判斷時(shí)cnt = 999,等到下一次判斷時(shí)cnt已經(jīng)是1005,這樣就會丟秒,一直加到溢出。所以計(jì)時(shí)會慢許多。正確寫法是: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.你想象的沒錯(cuò),中斷會打斷主程序的運(yùn)行。緩存數(shù)組每秒更新一次,顯示函數(shù)1ms刷新1位,6ms刷新1輪。如果 ...

謝謝大佬,原來的問題我現(xiàn)在清楚了,只是因?yàn)槿庋鄄煊X不到。但是您指出的cnt=999時(shí),為什么等到下一次判斷時(shí)cnt為1005了呢,這里我不太明白,cnt=999時(shí),if語句里面的程序沒有執(zhí)行啊,所以那6.8ms在cnt=999時(shí)沒有執(zhí)行,所以下一次判斷cnt還是為1000吧?而且我覺得盡管這里有6.8ms,但是每隔1ms進(jìn)入中斷cnt++,所以我覺得這6.8ms影響不到這個(gè)1000次1ms的計(jì)時(shí),也就是說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ù) 返回頂部 返回列表