|
發布時間: 2017-9-12 21:44
正文摘要:數碼管的原理我都懂,另外,重點強調,我這個是用138譯碼器控制數碼管顯示的,不是P1口;謝謝; 準備用8個數碼管顯示二進制累加的過程的,結果程序寫下來提示控制數碼管顯示的代碼沒意義;不知道問題出在哪了。請大 ... |
| 主要問題是沒理解138譯碼原理,從上述文字來看,現在可能還理解得不夠! |
| 樓主為什么要用delay呢??這樣寫的額程序很容易出問題,特別是對時序要求高的地方,建議用查詢的方法來控制時序動作。 |
GOD丿小男孩 發表于 2017-9-13 15:20 也可能是軟件差別,我用protues8.6,keil3.8a沒問題 |
GOD丿小男孩 發表于 2017-9-13 15:20 我仿真了下沒問題呀,很完美。可能仿真電路有些差別 |
18707072428 發表于 2017-9-13 21:00 沒有問題的!對照真值表寫的。 |
看來被人解決了啊![]() |
| 138譯碼器對應的程序有問題,數字顯示錯亂 |
|
我現在會了,代碼發在上面,有什么不懂的盡管問 |
| 不會啊 |
|
犯了一個基本錯誤。每一行的table沒有賦值給P0端,只是寫出來而已;另外if語句中應該是等于2時為真,還有最后一個if語句內容也稍作修改,才能加滿后循環,感謝大家的幫助;下面把代碼附上,親測可用; #include<reg52.h> sbit A=P2^2; //定義控制數碼管管腳 sbit C=P2^3; sbit D=P2^4; typedef unsigned char u16; typedef unsigned int u8; unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e, 0x79,0x71,0x00}; void delay(u16 z) //延時函數 { u16 x,y; for(x=z;x>0;x--) for(y=100;y>0;y--); } void main() //數碼管顯示二進制累加函數 { u16 k,j,i,g; u16 h,f,m,a,l; //定義變量 j=0;i=0;g=0;h=0;f=0;m=0;l=0; while(1) //大循環 { for(k=0;k<3;k++) //控制1數碼管顯示 { for(a=50;a>0;a--) //使數碼管顯示時間足夠人眼識別 { A=0;C=0;D=0;P0=table[k];delay(3); //1數碼管顯示0或1 if(k==2){j++;k=0;} //當1數碼管顯示1后,使二數碼管顯示1; A=1;C=0;D=0;P0=table[j];delay(3); //控制2數碼管顯示0或1; if(j==2){i++;j=0;} //以下相同; A=0;C=1;D=0;P0=table[i];delay(3); if(i==2){g++;i=0;} A=1;C=1;D=0;P0=table[g];delay(3); if(g==2){h++;g=0;} A=0;C=0;D=1;P0=table[h];delay(3); if(h==2){f++;h=0;} A=1;C=0;D=1;P0=table[f];delay(3); if(f==2){m++;f=0;} A=0;C=1;D=1;P0=table[m];delay(3); if(m==2){l++;m=0;} A=1;C=1;D=1;P0=table[l];delay(3); if(l==2){k=3;l=0;} //退出循環 } } } } |
漫步經心 發表于 2017-9-13 08:54 那樣是好一點,不過我前面按照你這種方式寫了一個十進制累加的,發現其實都一樣的,因為后面是相同的,錯誤都是一樣的,很方便改 |
mengzhixinheng 發表于 2017-9-13 01:34 嗯,多謝提醒。我寫的時候是對照真值表寫的,所以不會出錯 |
mengzhixinheng 發表于 2017-9-13 01:25 感謝的你幫助,不是電路問題,犯了一個最基本的錯誤 |
mengzhixinheng 發表于 2017-9-13 01:24 非常感謝你的幫助,不過你這個代碼出來后是不顯示1的,只有0或者不顯示,應該是該顯示1的時候數碼管沒點亮。看了你的代碼才知道我錯在哪了,是每一行的table沒有賦值給P0;顯示才沒有意義,現在已經改過來了,并且稍作修改后能正常顯示,待會我會放下面,謝謝你了,你這個比較高端一點,我的代碼就是最簡單的邏輯來寫的 |
| 我個人建議你先讓數碼管顯示一個數字,然后再動態刷新。循序漸進這樣比較穩妥。一次性寫那么多,出錯了你都找不到北。否則也就沒有那么多人說模塊化了。 |
| 自己改程序匹配你的電路 |
|
#include<reg51.h> typedef unsigned int uint; typedef unsigned char uchar; sbit A1=P1^4; sbit B1=P1^3; sbit C1=P1^2; unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delayms(uchar x) { uint i,j; for(i=x;i>0;i--) for(j=120;j>0;j--); } /*void display() { uchar X,Y; for(X=0;X<16;X++) for(Y=0;Y<100;Y++) { A1=0;B1=0;C1=0;P2=table[X];delayms(3); A1=0;B1=0;C1=1;P2=table[X];delayms(3); A1=0;B1=1;C1=0;P2=table[X];delayms(3); A1=0;B1=1;C1=1;P2=table[X];delayms(3); A1=1;B1=0;C1=0;P2=table[X];delayms(3); A1=1;B1=0;C1=1;P2=table[X];delayms(3); A1=1;B1=1;C1=0;P2=table[X];delayms(3); A1=1;B1=1;C1=1;P2=table[X];delayms(3); } } */ void hex() { uchar m,su; for(m=0x00;m<0xff;m++) for(su=0;su<50;su++) { A1=1;B1=1;C1=1; if(m&0x01)P2=table[1];else P2=table[0];delayms(3); A1=1;B1=1;C1=0; if(m&0x02)P2=table[1];else P2=table[0];delayms(3); A1=1;B1=0;C1=1; if(m&0x04)P2=table[1];else P2=table[0];delayms(3); A1=1;B1=0;C1=0; if(m&0x08)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=1;C1=1; if(m&0x10)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=1;C1=0; if(m&0x20)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=0;C1=1; if(m&0x40)P2=table[1];else P2=table[0];delayms(3); A1=0;B1=0;C1=0; if(m&0x80)P2=table[1];else P2=table[0];delayms(3); } } void main() { while(1) { // display(); hex(); } } 16進制輸出到一個完整的端口用led亮滅直接就可以表示出二進制狀態。你要用數碼管0和1表示,只需要判斷哪個數碼管該顯示什么就行。這個由你的累加數決定 |