熱門: 51單片機(jī) | 24小時(shí)必答區(qū) | 單片機(jī)教程 | 單片機(jī)DIY制作 | STM32 | Cortex M3 | 模數(shù)電子 | 電子DIY制作 | 音響/功放 | 拆機(jī)樂園 | Arduino | 嵌入式OS | 程序設(shè)計(jì)
![]() |
發(fā)布時(shí)間: 2016-6-7 15:17
正文摘要:編寫的一個(gè)8個(gè)數(shù)碼管顯示的數(shù)字時(shí)鐘可調(diào)鬧鐘 但不能正常運(yùn)行 程序還沒編完! #include<reg51.h> sbit KEY1=P1^0; sbit KEY2=P1^1; sbit KEY3=P1^2; sbit LED=P2^2; ... |
讀懂了別人正確有效的電路和程序,才能找出自己電路和程序的錯(cuò)誤 |
wc86110 發(fā)表于 2016-6-10 00:58 這個(gè)當(dāng)然!電路與程序是相配的,程序是根據(jù)電路和功能編寫的,任何案例都是如此。 |
yzwzfyz 發(fā)表于 2016-6-9 11:40 請(qǐng)看一下我的回復(fù)。 |
你的仿真圖只能使用采用的數(shù)碼管段碼。 |
時(shí)鐘動(dòng)態(tài)顯示電路,并保留時(shí)鐘修正及修正位快速閃爍功能,我下一次編一個(gè)。 |
若僅僅是6位時(shí)鐘,沒有修正及修正位快速閃爍功能,電路可簡(jiǎn)單的多。 |
實(shí)際電路應(yīng)該加限流電阻,不過(guò)無(wú)論是595、還是80C51,實(shí)際流不出很大電流的,長(zhǎng)期工作也不會(huì)使芯片過(guò)熱。 |
至于沒有限流電阻,那是為了電路圖面簡(jiǎn)潔,連晶振和復(fù)位電路都沒畫。 |
本帖最后由 zl2168 于 2016-6-9 17:58 編輯 "驅(qū)動(dòng)用了P1,P3兩個(gè)口,不利于程序編寫",完全沒有這個(gè)問(wèn)題,看你程序怎么編寫。P3口是串行傳送數(shù)據(jù),P1口是位控加修正位快速閃爍。 |
本帖最后由 zl2168 于 2016-6-9 18:00 編輯 用6片595的另一好處是,便于修正時(shí)鐘參數(shù)。而且修正位是快速閃爍(每秒亮暗各5次),修正期間時(shí)鐘繼續(xù)正常運(yùn)行 。你Proteus仿真一下,試試效果。 |
若用動(dòng)態(tài)顯示,7段加6位位控,需13根I/O端口線。因?yàn)椴慌懦S喽丝诰還需其他用途。 |
本電路設(shè)計(jì)為靜態(tài)顯示,雖然用了6片595,但595價(jià)格低廉。用595的好處是串行傳送,節(jié)省了I/O端口。 |
有人與我討論電路,很高興,首先表示感謝,并希望能交個(gè)朋友。有關(guān)問(wèn)題我的看法如下: |
寫書的人不一定認(rèn)真。 U2-U7驅(qū)動(dòng)的LED 7個(gè)段,都未限流,都是錯(cuò)誤的做法。 |
上圖的設(shè)計(jì)不是很好的:缺點(diǎn)如下: 1、用了6個(gè)(U2-U7),不經(jīng)濟(jì)。 改進(jìn),用一個(gè)晶體管陣列(一個(gè)IC里集成有7個(gè)三極管),驅(qū)動(dòng)LED的陽(yáng)極(共陽(yáng))。 2、LED的選擇驅(qū)動(dòng)用了P1,P3兩個(gè)口,不利于程序編寫。 改進(jìn),只用P1口驅(qū)動(dòng),這里軟件編寫方便許多。 3、四個(gè)發(fā)光二極管,兩兩串并,一般紅色壓降為1.4V,兩只2.8V,未經(jīng)限流直接接到IO口,使得2.2V電壓(5V-2.8V)加在CPU的芯片上,CPU發(fā)熱大。 改進(jìn):設(shè)LED是10mA一只。兩組并為20mA,串入一只電阻[R=(5V-2.8V-0.3V)/20=100歐,0.3V是IO口的壓降]。 |
先Proteus仿真一下![]() 以上摘自張志良編著《單片機(jī)實(shí)驗(yàn)實(shí)訓(xùn)100例》 ISBN 978-7-5124-1603-1,北航社出版 |
你的程序沒有定義標(biāo)記和注釋,別人需花多少時(shí)間才能讀懂理順,然后再幫你尋找錯(cuò)誤,可能嗎? |
張志良編著《單片機(jī)實(shí)驗(yàn)實(shí)訓(xùn)100例》每個(gè)案例程序均有詳細(xì)分析,每條語(yǔ)句均有注釋。 |
讀懂了別人正確有效的電路和程序,才能找出自己電路和程序的錯(cuò)誤。 |
樓上的5種電子鐘摘自張志良編著《單片機(jī)實(shí)驗(yàn)實(shí)訓(xùn)100例》 ISBN 978-7-5124-1603-1,北航社出版 |
參考一下樓上的5種電子鐘電路、程序和仿真 |
linlin2222 發(fā)表于 2016-6-7 17:55 已經(jīng)標(biāo)注了 大神幫我看看吧 |
yzwzfyz 發(fā)表于 2016-6-8 10:50 我上傳了標(biāo)注的程序和電路圖了 他上面不是定義了 StrTab[0]=tab[hour/10]; StrTab[1]=tab[hour%10]; StrTab[2]=0x40; StrTab[3]=tab[minute/10]; StrTab[4]=tab[minute%10]; StrTab[5]=0x40; StrTab[6]=tab[second/10]; StrTab[7]=tab[second%10]; 改變NUM就好了 |
#include<reg51.h> sbit KEY1=P1^0; //定義端口參數(shù) sbit KEY2=P1^1; sbit KEY3=P1^2; sbit LED=P2^2; //定義指示燈 code unsigned char tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共陰極數(shù)碼管0-9 unsigned char StrTab[8]; //定義緩沖區(qū) unsigned char minute=19,hour=23,second; //定義初始化 void delay(unsigned int cnt) { while(--cnt); } void displaypro(void) { StrTab[0]=tab[hour/10]; //顯示小時(shí) StrTab[1]=tab[hour%10]; StrTab[2]=0x40; //顯示- StrTab[3]=tab[minute/10]; //顯示分鐘 StrTab[4]=tab[minute%10]; StrTab[5]=0x40; //顯示- StrTab[6]=tab[second/10]; //顯示秒 StrTab[7]=tab[second%10]; } main() { TMOD |=0x01; //定時(shí)器0 10ms 用于計(jì)時(shí) TH0=0xd8; //初始值 TL0=0xf0; ET0=1; TR0=1; TMOD |=0x10; //定時(shí)器1 動(dòng)態(tài)掃描 TH1=0xf8; TL1=0xf0; ET1=1; TR1=1; EA=1; displaypro(); //調(diào)用顯示處理函數(shù) while(1) { if(!KEY3) { delay(10000); if(!KEY3) //按鍵3去抖以及動(dòng)作 { hour++; if(hour==24) hour=0; displaypro(); } } if(!KEY2) //按鍵2去抖以及動(dòng)作 { delay(10000); if(!KEY2) { minute++; if(minute==60) minute=0; displaypro(); } } if(!KEY1) { delay(10000); if(!KEY1) //按鍵1去抖以及動(dòng)作 { second++; if(second==60) second=0; displaypro(); } } } } //定時(shí)器1中斷// void time1_isr(void)interrupt 3 using 0 //定時(shí)器1動(dòng)態(tài)掃描 { static unsigned char num; TH1=0xf8; TL1=0xf0; switch(num) { case 0:P3=0xfe;P0=StrTab[num];break; //分別調(diào)用緩沖區(qū)的值進(jìn)行掃描 case 1:P3=0xfd;P0=StrTab[num];break; case 2:P3=0xfb;P0=StrTab[num];break; case 3:P3=0xf7;P0=StrTab[num];break; case 4:P3=0xef;P0=StrTab[num];break; case 5:P3=0xdf;P0=StrTab[num];break; case 6:P3=0xbf;P0=StrTab[num];break; case 7:P3=0x7f;P0=StrTab[num];break; default:break; } num++; //掃描8次,使用8個(gè)數(shù)碼管 if(num==8) num=0; } //定時(shí)器0// void time(void)interrupt 1 using 1 { static unsigned char count; //定義內(nèi)部局部變量 TH0=0xd8; TL0=0xf0; count++; switch(count) { case 0: case 20: case 40: case 60: case 80:displaypro();break; //隔一定時(shí)間調(diào)用顯示處理顯示處理 case 50:P1=~P1;break; //半秒 LED 閃爍 default:break; } if(count==100) { count=0; second++; if(second==60) { second=0; minute++; if(minute==60) { minute=0; hour++; if(hour==24) hour=0; } } } } |
case 0:P3=0xfe;P0=StrTab[num];break; case 1:P3=0xfd;P0=StrTab[num];break; case 2:P3=0xfb;P0=StrTab[num];break; case 3:P3=0xf7;P0=StrTab[num];break; case 4:P3=0xef;P0=StrTab[num];break; case 5:P3=0xdf;P0=StrTab[num];break; case 6:P3=0xbf;P0=StrTab[num];break; case 7:P3=0x7f;P0=StrTab[num];break; 這是T1中斷所做的事,雖然每次切換了LED,但顯示的內(nèi)容卻是相同的StrTab[num],這就必須保證,在每次中斷之前,StrTab[num]已被刷新,僅改變num是不夠的,因?yàn)轱@示的不是num,而是StrTab[num]! 如果某一次中斷前未刷新,則輪顯示的LED必定是上一輪的LED值,如此就混淆了。 你用兩個(gè)時(shí)間中斷的目的是什么?能保證正確地刷新LED數(shù)據(jù)么? |
要點(diǎn):每次中斷只顯示一個(gè)LED,且先關(guān)后顯示!! |
先將各行的注釋加上去,讓別人知道你的目的,再看你錯(cuò)在哪里。 也許:當(dāng)你完成注釋時(shí),自己就已經(jīng)明白了。 |
yzwzfyz 發(fā)表于 2016-6-7 17:40 能不能幫我修改下程序 看哪里錯(cuò)了 |
重點(diǎn)需要強(qiáng)調(diào)出來(lái), 別人能夠很容易看懂 |
1、取8個(gè)RAM單元(編號(hào)X0至X7)對(duì)應(yīng)存放8個(gè)LED的顯示內(nèi)容(譯碼后的LED段顯示值)。 2、取一個(gè)單元做計(jì)數(shù)器K,從0至7循環(huán)計(jì)數(shù),分別對(duì)應(yīng)指示顯示8個(gè)LED。 3、時(shí)間中斷只用一個(gè),考慮到8個(gè)LED掃描顯示,中斷時(shí)常數(shù)取5ms,中斷后做下列事件: 3.1、處理一下計(jì)數(shù)器(屏上顯示的數(shù)字,如時(shí)間年月日時(shí)分秒,或計(jì)數(shù)值等)…… 3.2、先關(guān)所有LED顯示,防止切換閃動(dòng); 3.3、將K+1(注:當(dāng)K=8時(shí)清K=0。),將K所指示的Xn(當(dāng)然需要將對(duì)應(yīng)需要顯示的時(shí)鐘位,譯成LED碼后再送入Xn)送入顯示數(shù)據(jù)口,再打開K所指定的LED。 要點(diǎn):每次中斷只顯示一個(gè)LED,且先關(guān)后顯示。 |
寫程序習(xí)慣不好,沒有注釋。 |
圖不清楚 |
而且也不能正常計(jì)時(shí) |
Powered by 單片機(jī)教程網(wǎng)