![]() |
總的看來,問題比較多。 簡單改法: 掃描顯示的意義在于無論如何,顯示代碼在循環中都需要跑一次,這才是掃描。所以 //顯示兩位數碼管 這段代碼 需要放在 while(1)中長期運行,而不能放在 if(tj==0) //設置輸出電壓 里 這樣在輸出電壓時,就只能顯示一位了。 所以 按鍵判斷 while(P3_6==0) // 等待按鍵松開 也是不合適的,這樣鍵盤按下不放時,只會顯示一位。 建議做法: 主循環while(1)不能存在卡循壞的代碼。 按鍵在while(1)里取值,連續5次一致,認可此次按鍵有效(用于消抖),去掉while(P3_6==0);這類代碼。然后比較此次按鍵與上次按鍵的不同,用于判斷按下或是松開按鍵。這樣寫法還可加入按鍵時長的計算,便于代碼的擴展。 //顯示兩位數碼管 代碼放于主循環中,保證一直運行。 |
lkc8210 發表于 2022-4-20 14:33 搞錯了 ,這個才是 #include<math.h> #include <reg51.h> #define uchar unsigned char #define uint unsigned int char led[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; char led1[]={0x3f,0x06,0x5b,0x4f,0xe66,0x6d,0x7d,0x07,0x7f,0x6f}; sbit P3_7=P3^7; //加鍵 sbit P3_6=P3^6; //減鍵 sbit P3_1=P3^1; sbit P3_0=P3^0; sbit P3_4=P3^4; //模式選擇(設置輸出電壓值模式or電壓輸出模式) uchar set=50,tj=0; void delay (unsigned int time) { unsigned j; for (;time>0;time--) for(j=0;j<125;j++) ; } void main () { while (1) { if(P3_4==0) { tj=!tj; while(P3_4==0) ; } if(tj==0) //設置輸出電壓 { //掃描按鍵1 if(P3_7==0) { delay(10); // 摁鍵消抖 if(P3_7==0) { set++; if(set>99) set=99; // 設置顯示最大值 while(P3_7==0) // 等待按鍵松開 ; } } //掃描按鍵2 if(P3_6==0) { delay(10); // 摁鍵消抖 if(P3_6==0) { set--; if(set<0) set=0 ; // 設置顯示最小值 while(P3_6==0) // 等待按鍵松開 ; } } //顯示兩位數碼管 P3_0=0; P3_1=1; P0=led[set/10]; delay(50) ; P3_0=1; P3_1=0; P0=led1[set%10]; delay(50) ; } else{ P2=(float)set*2.56 ; //輸出算法 // P2=25.6; } } } |
lkc8210 發表于 2022-4-20 14:33 #include<reg52.h> #define uchar unsigned char #define uint unsigned int uint aa,b,bb; sbit p1=P2^7; sbit p2=P2^6; sbit p3=P2^5; sbit p4=P2^4; sbit dp=P0^7; sbit an1=P1^4; sbit an2=P1^5; sbit an3=P1^6; sbit CLK=P1^2;/*定義DAC控制端口*/ sbit CS=P1^1; sbit DIN=P1^3; uchar code SegCode[12] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1}; int moshi=0; void DelayMs(uchar n) { uchar j; while (n--) { for (j = 0; j < 113; j++); } } void keyscan1() /*復位*/ { if(an1==0) { aa=0; bb=0; } while(an1==0); } void keyscan2() /*按鍵1進行加1*/ { if(an2==0) { if(aa<99) { aa=aa+1; bb++; } } while(an2==0); } void keyscan3() /*按鍵2進行減1*/ { if(an3==0) { if(aa>0) { aa=aa-1; bb--; } } while(an3==0); } /*顯示函數*/ void display(void) { p1=0;p2=0; if(bb/10%10==0) P0=SegCode[1]; else P0=SegCode[bb/10%10]; p1=1;p2=0; DelayMs(1); p1=0;p2=0; P0=SegCode[bb/1%10]; dp=0; p1=0;p2=1; DelayMs(1); p1=0;p2=0; } void DA_Conver(unsigned int DAValue) { unsigned char i; DAValue <<= 6; CS = 0; CLK = 0; for(i = 0; i < 12; i++) { DIN = (bit)(DAValue & 0x8000); CLK = 1; DAValue <<= 1; CLK = 0; } CS = 1; CLK = 0; } float zh (float k) { float DA; DA=k*1024/500; /*2.5v參考電壓!*/ return DA; } void init_timer() { TMOD=0x01; TH0=(65536-3500)/256; TL0=(65536-3500)%256; EA=1; ET0=1; TR0=1; } void main() {long DAValue=0; aa=0; init_timer(); while(1) { DAValue=zh(aa); /*輸出電壓*/ DA_Conver(DAValue); keyscan1(); keyscan2(); keyscan3(); } } void time0() interrupt 1 { TH0=(65536-3500)/256; TL0=(65536-3500)%256; b++ ; if(b==2) {b=0; display(); } } 這是我的代碼,如果想顯示的話,該怎么改才行 |
你的延時時間可能有問題,一般這個延時時間幾個毫秒。 |
代碼只給一部份如瞎子摸象 問題現象加上現有代碼 可退敲出幾個問題可能 1. 沒有消影 2. 延時不足 3. 其他代碼耗時太長 |
xianfajushi 發表于 2022-4-19 21:04 不行啊,還是只亮各位 |
munuc_w 發表于 2022-4-20 08:48 該怎么寫,求指導, |
這個代碼運行到個位顯示就結束了,當然只有個位在顯示了。要想兩位都顯示,需要不停的循環運行顯示代碼部分,這是動態顯示電路工作的基本原理。 |
P0=~led1[set%10]; 試看 |