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

QQ登錄

只需一步,快速開(kāi)始

搜索

51單片機(jī)四位數(shù)碼管計(jì)時(shí)器代碼有嚴(yán)重的重影?

查看數(shù): 2576 | 評(píng)論數(shù): 34 | 收藏 0
關(guān)燈 | 提示:支持鍵盤翻頁(yè)<-左 右->
    組圖打開(kāi)中,請(qǐng)稍候......
發(fā)布時(shí)間: 2023-11-19 11:41

正文摘要:

遇到的問(wèn)題是: 仿真結(jié)果運(yùn)行異常,數(shù)碼管不能正常顯示。

回復(fù)

ID:332444 發(fā)表于 2023-11-21 10:46
借助這帖就說(shuō)說(shuō)阻塞與查詢延時(shí)的轉(zhuǎn)換,把代碼if(++sy==0)修改while(++sy)就是阻塞延時(shí),阻塞延時(shí)放前后都可以.
ID:1100331 發(fā)表于 2023-11-21 00:06
鵜鶘 發(fā)表于 2023-11-20 15:53
你這個(gè)程序?qū)嶋H上是兩個(gè)錯(cuò)誤,第一個(gè)是我12樓說(shuō)的那個(gè),第二個(gè)我昨天晚上沒(méi)看出來(lái)。第一個(gè)錯(cuò)誤會(huì)導(dǎo)致這個(gè)計(jì) ...

謝謝你,目前所有的問(wèn)題已經(jīng)解決。確實(shí)有位選碼(顯示掩碼)邏輯顛倒的問(wèn)題。詳情見(jiàn)我最新的置頂樓。
另外,我的中斷函數(shù)里除了”timer==20“這一句有錯(cuò)誤,也忘了令timer=0;所以后來(lái)無(wú)論怎么改timer都不影響速度(因?yàn)槎际菑?到255再到0)(哭笑)
ID:1100331 發(fā)表于 2023-11-20 18:54
yzwzfyz 發(fā)表于 2023-11-20 09:32
"掃屏顯示的切換應(yīng)當(dāng)用最少的指令完成,在不多于8個(gè)LED的情況下:三條指令即可完成,對(duì)于STC的單片機(jī),10us ...

謝謝你的分享。你講的這個(gè)技巧看起來(lái)很驚艷,我會(huì)下來(lái)仔細(xì)琢磨并實(shí)踐的
ID:1100331 發(fā)表于 2023-11-20 18:51
ydatou 發(fā)表于 2023-11-20 09:09
仿真結(jié)果和實(shí)驗(yàn)結(jié)果應(yīng)該相差不大。
這種現(xiàn)象表示仿真模型和實(shí)驗(yàn)硬件不符。

問(wèn)題已經(jīng)解決了,您說(shuō)得真對(duì),確實(shí)是硬件有一些問(wèn)題沒(méi)注意到或者是沒(méi)法注意到(哭笑)
ID:1100331 發(fā)表于 2023-11-20 18:48
tyrl800 發(fā)表于 2023-11-20 08:31
你這個(gè)消隱程序錯(cuò)了,改成P3=0xff,你應(yīng)該把電路板原理圖發(fā)上來(lái)才能解決下載后的問(wèn)題

謝謝你的回復(fù),消隱程序正反邏輯顛倒確實(shí)是問(wèn)題之一
ID:1100331 發(fā)表于 2023-11-20 18:46
tyrl800 發(fā)表于 2023-11-19 19:49
板子與仿真原理圖肯定不一樣才這樣

謝謝你的回復(fù),我已經(jīng)解決了這個(gè)問(wèn)題。板子與仿真原理圖不一致確實(shí)是問(wèn)題之一
ID:397054 發(fā)表于 2023-11-20 15:53
你這個(gè)程序?qū)嶋H上是兩個(gè)錯(cuò)誤,第一個(gè)是我12樓說(shuō)的那個(gè),第二個(gè)我昨天晚上沒(méi)看出來(lái)。第一個(gè)錯(cuò)誤會(huì)導(dǎo)致這個(gè)計(jì)時(shí)器快10倍,我以為你所說(shuō)的“重影”實(shí)際是走的快引起來(lái)顯示8的原因,但早上起來(lái)我想想即使快10倍也不至于引起“重影”現(xiàn)象,即充其量秒的個(gè)位會(huì)因?yàn)樽兓炜雌饋?lái)像8,其他的就不會(huì)了,秒的10位肯定看得清楚因?yàn)榭?0倍也就是1秒一變,分鐘就更加不會(huì)了。中午吃完飯沒(méi)事就把你的程序復(fù)制下來(lái)稍加修改適合我的板子,上電一看果然4個(gè)8字,但憑經(jīng)驗(yàn)看明顯的不是因?yàn)樘兛煲鸬,這跟我前一段時(shí)間碰到的一個(gè)故障非常像,因?yàn)橛羞@個(gè)經(jīng)驗(yàn)仔細(xì)看了一下你的有關(guān)顯示的代碼,看出了問(wèn)題所在,跟我的那個(gè)故障的原因雖然不完全一樣,但現(xiàn)象確實(shí)會(huì)很像——是你把顯示掩碼(顯示掩碼,很多書上稱為“位碼”)的正負(fù)邏輯弄顛倒了,你的顯示掩碼電路肯定是負(fù)邏輯,一般的都是,而你把它當(dāng)正邏輯來(lái)處理了,即display_time()函數(shù)中P3=,,,那4行右面是正邏輯01、02、04、08,這樣該亮的不亮不該亮的3個(gè)同時(shí)亮,這么個(gè)掃描循環(huán)當(dāng)然就亂七八糟了,所以正確的數(shù)值應(yīng)該是這4個(gè)數(shù)的反碼才對(duì),或者你把他們的反碼替代他們比如FE替代01等或者懶得算的話就在每個(gè)數(shù)字前面加個(gè)非號(hào)“~”即可。

之所以兩個(gè)數(shù)碼管時(shí)正常,那是假象,是因?yàn)橹挥袃蓚(gè)數(shù)碼管,它仍然遵循該亮的不亮其它都亮的規(guī)則,但這時(shí)的“其它”只有1個(gè)了,所以看上去就正常了,但這時(shí),兩位是顛倒的,即秒的10位顯示的是個(gè)位數(shù)值,而個(gè)位顯示的是十位。

第一個(gè)錯(cuò)誤也要改否則的話根本就談不上準(zhǔn)確,且錯(cuò)誤還不止那一句,雖然都是同一個(gè)錯(cuò)誤。
ID:34149 發(fā)表于 2023-11-20 15:17
你的位驅(qū)動(dòng)是I0口直接驅(qū)動(dòng)嗎?
沒(méi)有原理圖,確實(shí)挺難幫你分析的
ID:57657 發(fā)表于 2023-11-20 14:18
51單片機(jī)8位并行IO口一組,段碼和位碼不是并行發(fā)送的,所以需要消隱,16位以上不需要,新的位碼送出去了,段碼還是舊的,所以就出現(xiàn)影子了。
ID:1073939 發(fā)表于 2023-11-20 14:00
小小小初學(xué)者 發(fā)表于 2023-11-20 13:26
謝謝各位的回復(fù),學(xué)業(yè)繁忙,我等晚上或者明天再一一回復(fù)。不過(guò)目前我越來(lái)越感覺(jué)問(wèn)題不是代碼,而是板子。因 ...

把板子的原理圖發(fā)出來(lái)。
ID:1100331 發(fā)表于 2023-11-20 13:30
這個(gè)是老師發(fā)的原理圖,單片機(jī)型號(hào)是STC 89C51RC

DIY_MCU_51_REV1.0(2015.11.06)原理圖.pdf

1.08 MB, 下載次數(shù): 3

ID:1100331 發(fā)表于 2023-11-20 13:26
謝謝各位的回復(fù),學(xué)業(yè)繁忙,我等晚上或者明天再一一回復(fù)。不過(guò)目前我越來(lái)越感覺(jué)問(wèn)題不是代碼,而是板子。因?yàn)槲抑槐A糨敵雒雮(gè)位的代碼后,在調(diào)試中,拔掉了四個(gè)位選線。接下來(lái)按道理,其中只有一個(gè)位選線能讓對(duì)應(yīng)的數(shù)碼管閃亮,但實(shí)際情況是:每條位選線都能讓數(shù)碼管閃亮
這可能意味著位選線4個(gè)端總是0xff。。醋寯(shù)碼管生效)
我換了我兩個(gè)舍友的板子重新燒,結(jié)果是一樣的,感覺(jué)同時(shí)焊錯(cuò)的可能性比較小....

ID:332444 發(fā)表于 2023-11-20 10:39
忘記打括號(hào)了,加的要括號(hào),或者刪除+(ls==8||ls==32?SmZiFu[10]:0)加小數(shù)點(diǎn),另外6位的話刪除最后2位即64和128,修改條件 if(ls==0||ls==32)
ID:272119 發(fā)表于 2023-11-20 10:10
應(yīng)該很好調(diào)試的,我沒(méi)有仔細(xì)看樓主的程序只看了圖片,如果不是消隱反向的話,建議樓主先不要忙那么多位顯示,首先調(diào)試最后一位顯示1->9正常后輻射4位就簡(jiǎn)單的多,如果連一位都不能正常顯示那仔細(xì)磨驅(qū)動(dòng)代碼吧.
ID:332444 發(fā)表于 2023-11-20 09:39
數(shù)碼管動(dòng)態(tài)驅(qū)動(dòng)是最基本的,它的原則:消隱-送段值-送位值-延時(shí),按這樣的順序執(zhí)行和編寫代碼.
看仿真圖片數(shù)碼管應(yīng)該是共陽(yáng),我這里有個(gè)簡(jiǎn)單的荔枝,顯示固定的日期小數(shù)點(diǎn)分割,修改了一下,仿真和下載開(kāi)發(fā)板試看.
  1. #include "reg52.h"
  2. unsigned char code SmZiFu[]={63,6,91,79,102,109,125,7,127,111,128,0};//共陰0-9.
  3. void main()
  4. {
  5.         unsigned char sy=0,my=0,ls=0;
  6.         while(1)
  7.         {
  8.                 if(++sy==0)
  9.                 {
  10.                         P0=255;P3=0;
  11.                         if(ls==0||ls==8)ls=1;else ls*=2;//控制4位數(shù)碼管顯示
  12.                         P0=255-(SmZiFu[ls==1?2
  13.                         :ls==2?0
  14.                         :ls==4?2
  15.                         :ls==8?3
  16.                         :ls==16?1
  17.                         :ls==32?1
  18.                         :ls==64?0
  19.                         :ls==128?7
  20.                         :11]+(ls==8||ls==32?SmZiFu[10]:0));
  21.                         P3=ls;
  22.                 }
  23.         }
  24. }
復(fù)制代碼



ID:123289 發(fā)表于 2023-11-20 09:32
"掃屏顯示的切換應(yīng)當(dāng)用最少的指令完成,在不多于8個(gè)LED的情況下:三條指令即可完成,對(duì)于STC的單片機(jī),10us不到就完成了,例:8個(gè)LED哪個(gè)亮(位選)受P1控制,顯示什么內(nèi)容(段碼)由P0決定。
要點(diǎn):技巧如下!!!
先將哪個(gè)LED需要亮的參數(shù)事先準(zhǔn)備好,放在:P1_OUT變量中,同樣將這個(gè)LED需要顯示的段碼放在P0_OUT中。【這個(gè)做法最關(guān)鍵,不要直接切換操作P0、P1口,而是通過(guò)這兩個(gè)變量來(lái)操作。原因是,無(wú)論你用多長(zhǎng)時(shí)間對(duì)P1_OUT、P0_OUT進(jìn)行操作,操作期間,顯示不受影響。】
切換:
第一條指令:關(guān)斷所有顯示:P1=FFH              ;關(guān)閉所有顯示
第二條指令:切換LED段碼:P0=P0_OUT         ;這時(shí)顯示已關(guān),切換不會(huì)有殘留,重影,閃爍了。
第三條指令:更新顯示的LED管:P1=P1_OUT  ;點(diǎn)亮需要顯示的LED,例如:11101111B
【這個(gè)做法是最優(yōu)秀的掃描顯示切換方法,用時(shí)最短,最合理,沒(méi)有之二。。 
重復(fù)一下關(guān)鍵點(diǎn):事先處理準(zhǔn)備好變量P1_OUT、P0_OUT的值。"
ID:1073939 發(fā)表于 2023-11-20 09:09
仿真結(jié)果和實(shí)驗(yàn)結(jié)果應(yīng)該相差不大。
這種現(xiàn)象表示仿真模型和實(shí)驗(yàn)硬件不符。
ID:275826 發(fā)表于 2023-11-20 08:31
小小小初學(xué)者 發(fā)表于 2023-11-19 21:41
你好,謝謝你的回復(fù),首先我很抱歉我的敘述可能有些混亂,因?yàn)檫@東西搞得我有些焦頭爛額。接下來(lái)我來(lái)回復(fù) ...

你這個(gè)消隱程序錯(cuò)了,改成P3=0xff,你應(yīng)該把電路板原理圖發(fā)上來(lái)才能解決下載后的問(wèn)題
ID:1100331 發(fā)表于 2023-11-19 21:41
鵜鶘 發(fā)表于 2023-11-19 20:30
我根本就沒(méi)法理解你的敘述,牛頭不對(duì)馬嘴的,數(shù)碼管如何重影呢,它要么亮要么就不亮,總是清晰的,它就是個(gè) ...

你好,謝謝你的回復(fù),首先我很抱歉我的敘述可能有些混亂,因?yàn)檫@東西搞得我有些焦頭爛額。接下來(lái)我來(lái)回復(fù)你的質(zhì)疑:
1.重影或者說(shuō)殘影,這個(gè)是我最原本代碼確實(shí)存在的問(wèn)題,因?yàn)闆](méi)有消影。這個(gè)問(wèn)題在大家的幫助下解決了,F(xiàn)在在仿真上是一切正常的。
2.我在1樓說(shuō)的現(xiàn)象是真實(shí)的,只不過(guò)造成那個(gè)現(xiàn)象的代碼和我在9樓說(shuō)的現(xiàn)象所使用的代碼相比,做了很多修改,兩者代碼不一樣,現(xiàn)象也不一樣,不是一回事。
現(xiàn)在的問(wèn)題是,即時(shí)添加了消影,數(shù)碼管仍然不能正確顯示(大部分時(shí)間是8,9這種多個(gè)段接通的數(shù)字)。
我嘗試在代碼中刪除顯示分鐘的,保留顯示秒鐘的,那么燒錄到機(jī)子后,將有這樣的現(xiàn)象:顯示秒鐘的兩位正常顯示,分鐘位也顯示(代碼中已經(jīng)刪去顯示分鐘了),并且顯示的是秒鐘兩位個(gè)位和十位的疊加
  1. void display_time()
  2. {

  3.         P3=0X00;
  4.         DIGIT_O=segCode[seconds/10];
  5.         P3 = 0x04;
  6.         delay(5);

  7.         P3=0X00;
  8.         DIGIT_O=segCode[seconds%10];
  9.         P3 = 0x08;
  10.         delay(5);
  11. }
復(fù)制代碼
ID:213173 發(fā)表于 2023-11-19 21:12
小小小初學(xué)者 發(fā)表于 2023-11-19 19:12
為了深究原因,我嘗試把秒的位選代碼刪去,只保留分鐘。發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象:在仿真里正常,高兩位數(shù)碼管顯 ...


ID:397054 發(fā)表于 2023-11-19 20:30
我根本就沒(méi)法理解你的敘述,牛頭不對(duì)馬嘴的,數(shù)碼管如何重影呢,它要么亮要么就不亮,總是清晰的,它就是個(gè)普通物體怎么個(gè)重影法,,,,但根據(jù)你的程序看,我知道你說(shuō)的“重影”是什么意思,只是用這個(gè)詞實(shí)在是太詞不達(dá)意了;而且另一個(gè)現(xiàn)象更加不可能,【如果只顯示兩位,即秒的部分,那么則不會(huì)出現(xiàn)上述問(wèn)題,】——這根本不可能,4位都都顯示時(shí),決不會(huì)4位都“重影”,左面兩位不“重影”,右面的兩位才“重影”,右面的是秒,而你偏偏說(shuō)秒正常,這完全不可能 。。。。。
ID:397054 發(fā)表于 2023-11-19 19:58
消隱并不重要,display_time函數(shù)中沒(méi)有最后一行也不致引起很大的影響,幾乎看不出來(lái)。
ID:397054 發(fā)表于 2023-11-19 19:54
把這行語(yǔ)句多看幾遍,直到看出問(wèn)題來(lái):

if(timer==20){                  //到達(dá)1s
ID:275826 發(fā)表于 2023-11-19 19:49
板子與仿真原理圖肯定不一樣才這樣
ID:36322 發(fā)表于 2023-11-19 19:26

P3 = 0x00;
DIGIT_O=segCode[seconds/10];
P3 = 0x01;
delay(5);

延時(shí)可適當(dāng)加長(zhǎng)
ID:1100331 發(fā)表于 2023-11-19 18:44
謝謝大家的回復(fù),我重新在每個(gè)數(shù)碼管顯示前都添加了消隱(禁用位選,輸出空段碼兩種方式都嘗試了)
仿真結(jié)果均正常,但是燒錄到機(jī)子里仍然有重影
ID:1100331 發(fā)表于 2023-11-19 18:28
Hephaestus 發(fā)表于 2023-11-19 16:37
在每條
        DIGIT_O=   ;
前面加上

謝謝,我這樣試了。仿真恢復(fù)正常,但是板子仍然有重影好無(wú)奈啊
ID:1100331 發(fā)表于 2023-11-19 18:26
xianfajushi 發(fā)表于 2023-11-19 16:09
每個(gè)數(shù)碼管顯示前都要消隱,是每個(gè)。

謝謝,我試了試后仿真沒(méi)有問(wèn)題,但是燒到板子上仍然有重影,不知道是哪的問(wèn)題了現(xiàn)在(苦),頭大
ID:213173 發(fā)表于 2023-11-19 17:57
核心問(wèn)題是動(dòng)態(tài)掃描數(shù)碼管沒(méi)有消隱。
  1. #include "reg51.h"
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define DIGIT_O P0//設(shè)置P0位數(shù)碼管數(shù)據(jù)輸出端

  6. //定義時(shí)分秒變量
  7. uchar timer,seconds,minutes,hours;        
  8. uchar timer,seconds,minutes,hours = 0;

  9. //共陽(yáng)極數(shù)字碼表
  10. uchar code segCode[]={
  11.                 0xc0,0xf9,0xa4,0xb0,
  12.                 0x99,0x92,0x82,0xf8,
  13.                 0x80,0x90,0x88,0x83,
  14.                 0xc6,0xa1,0x86,0x8e};
  15. //定時(shí)器中斷服務(wù)程序
  16. void timer0_ISR() interrupt 1
  17. {
  18.         TH0 = 0xee;   // 設(shè)置定時(shí)初值,一次中斷為5ms
  19.         TL0 = 0x00;
  20.         timer++;
  21.         if(timer==200) //到達(dá)1s
  22.         {            
  23.                 timer=0;
  24.                 seconds++;
  25.                 if (seconds == 60)
  26.                 {
  27.                         seconds = 0;
  28.                         minutes++;
  29.                         if (minutes == 60)
  30.                         {
  31.                                 minutes = 0;
  32.                                 hours++;
  33.                                 if (hours == 24)
  34.                                 {
  35.                                         hours = 0;
  36.                                 }
  37.                         }
  38.                 }
  39.         }        
  40. }
  41. void delay(uint x)   //延時(shí)xms
  42. {
  43.         uint i,j;
  44.         for(i=x;i>0;i--)
  45.                 for(j=114;j>0;j--);
  46. }

  47. //初始化硬件
  48. void init()
  49. {
  50.         TMOD = 0x01;  // 定時(shí)器0工作在模式1(16位定時(shí)器)
  51.         TH0 = 0xee;   // 設(shè)置定時(shí)初值
  52.         TL0 = 0x00;
  53.         ET0 = 1;      // 允許定時(shí)器0中斷
  54.         EA = 1;       // 允許總中斷
  55.         TR0 = 1;      // 啟動(dòng)定時(shí)器0
  56.         seconds=0;
  57.         minutes=0;
  58.         hours=0;   
  59. }
  60. // 顯示時(shí)間
  61. void display_time()
  62. {
  63.         static uchar data i;
  64.         P3&=0xf0;//消隱
  65.         switch(i)
  66.         {
  67.                 case 0: DIGIT_O=segCode[minutes/10]; break;
  68.                 case 1: DIGIT_O=segCode[minutes%10]&0x7f; break;//加點(diǎn)
  69.                 case 2: DIGIT_O=segCode[seconds/10]; break;
  70.                 case 3: DIGIT_O=segCode[seconds%10]; break;
  71.         }
  72.         P3|=0x01<<i;
  73.         i=++i%4;
  74. }


  75. void main()
  76. {
  77.         init();
  78.         while(1)
  79.         {        
  80.                 display_time();        
  81.                 delay(1);
  82.         }
  83. }
復(fù)制代碼
ID:1064915 發(fā)表于 2023-11-19 17:22
DIGIT_O=0XFF;
再?gòu)?fù)制3個(gè)
ID:883242 發(fā)表于 2023-11-19 16:37
在每條
        DIGIT_O=   ;
前面加上
        P3 = 0x0;
試試。
ID:332444 發(fā)表于 2023-11-19 16:09
每個(gè)數(shù)碼管顯示前都要消隱,是每個(gè)。

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

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

快速回復(fù) 返回頂部 返回列表