![]() |
發布時間: 2018-9-24 10:50
正文摘要:今天在做用計時器代替delay函數的數碼管程序,從99開始倒計時。剛開始的時候99能正常顯示,98開始后面的大多數都不能正常顯示,偶爾個別數有可以正常顯示,這是為什么?下面是代碼和proteus仿真圖。順便問一下,做項 ... |
#include<reg51.h> #define LEDData P0 unsigned char code LEDCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; unsigned char minit,second,count,count1; unsigned char set_minit=12,set_second=0; sbit add1=P1^0; sbit dec1=P1^1; sbit exchange=P1^2; sbit add2=P1^3; sbit dec2=P1^4; sbit secondpoint=P0^7; sbit led1=P2^7; sbit led2=P2^6; sbit led3=P2^5; sbit led4=P2^4; sbit led5=P2^3; sbit led6=P2^2; sbit led7=P2^1; sbit led8=P2^0; sbit led9=P3^7; sbit led10=P3^6; sbit alam=P1^7; bit playon=0; bit timeover=0; bit AorB=0; bit halfsecond=0; unsigned int scoreA; unsigned int scoreB; void Delay5ms(void) { unsigned int i; for(i=100;i>0;i--); } void display(void) { LEDData=LEDCode[minit/10]; led1=0; Delay5ms(); led1=1; LEDData=LEDCode[minit%10]; led2=0; Delay5ms(); led2=1; if(halfsecond==1) LEDData=0x80; else LEDData=0x00; led2=0; Delay5ms(); led2=1; secondpoint=0; LEDData=LEDCode[second/10]; led3=0; Delay5ms(); led3=1; LEDData=LEDCode[second%10]; led4=0; Delay5ms(); led4=1; if(AorB==0) LEDData=LEDCode[scoreA/100]; else LEDData=LEDCode[scoreB/100]; led5=0; Delay5ms(); led5=1; if(AorB==0) LEDData=LEDCode[(scoreA%100)/10]; else LEDData=LEDCode[(scoreB%100)/10]; led6=0; Delay5ms(); led6=1; if(AorB==0) LEDData=LEDCode[scoreA%10]; else LEDData=LEDCode[scoreB%10]; led7=0; Delay5ms(); led7=1; if(AorB==1) LEDData=LEDCode[scoreA/100]; else LEDData=LEDCode[scoreB/100]; led8=0; Delay5ms(); led8=1; if(AorB==1) LEDData=LEDCode[(scoreA%100)/10]; else LEDData=LEDCode[(scoreB%100)/10]; led9=0; Delay5ms(); led9=1; if(AorB==1) LEDData=LEDCode[scoreA%10]; else LEDData=LEDCode[scoreB%10]; led10=0; Delay5ms(); led10=1; } void keyscan(void) { if(playon==0) { if(add1==0) { display(); if(add1==0); { if(minit<99) minit++; else minit=99; } do display(); while(add1==0); } if(dec1==0) { display(); if(dec1==0); { if(minit>0) minit--; else minit=0; } do display(); while(dec1==0); } if(add2==0) { display(); if(add2==0); { if(second<59) second++; else second=59; } do display(); while(add2==0); } if(dec2==0) { if(second>0) second--; else second=0; } do display(); while(dec2==0); } if(exchange==0) { display(); if(exchange==0); { TR1=0; alam=1; AorB=~AorB; minit=set_minit; second=0; } do display(); while(exchange==0); } else { if(add1==0) { display(); if(add1==0); { if(AorB==0) { if(scoreA<999) scoreA++; else scoreA=999; } else { if(scoreB<999) scoreB++; else scoreB=999; } } do display(); while(add1==0); } if(dec1==0) { display(); if(dec1==0); { if(AorB==0) { if(scoreA>0) scoreA--; else scoreA=0; } else { if(scoreB>0) scoreB--; else scoreB=0; } } do display(); while(dec1==0); } if(add2==0) { display(); if(add2==0); { if(AorB==1) { if(scoreA<999) scoreA++; else scoreA=999; } else { if(scoreB<999) scoreB++; else scoreB=999; } } do display(); while(add2==0); } if(dec2==0) { display(); if(dec2==0); { if(AorB==1) { if(scoreA>0) scoreA--; else scoreA=0; } else { if(scoreB>0) scoreB--; else scoreB=0; } } do display(); while(dec2==0); } } } void main(void) { TMOD=0x11; TL0=0xb0; TH0=0x3c; TL1=0xb0; TH1=0x3c; minit=set_minit; second=0; EA=1; ET0=1; ET1=1; TR0=0; TR1=0; EX0=1; IT0=1; IT1=1; EX1=1; PX0=1; PX1=1; PT0=0; P1=0xFF; P3=0xFF; while(1) { keyscan(); display(); } } void PxInt0(void) interrupt 0 { Delay5ms(); EX0=0; alam=1; TR1=0; if(timeover==1) { timeover=0; } if(playon==0) { playon=1; TR0=1; } else { playon=0; TR0=0; } EX0=1; } void time0_int(void) interrupt 1 { TL0=0xb0; TH0=0x3c; TR0=1; count++; if(count==10) { halfsecond=0; } if(count==20) { count=0; halfsecond=1; if(second==0) { if(minit>0) { second=59; minit--; } else { timeover=1; playon=0; TR0=0; TR1=1; } } else second--; } } void time1_int(void) interrupt 3 { TL1=0xb0; TH1=0x3c; TR1=1; count1++; if(count1==10) { alam=0; } if(count1==20) { count1=0; alam=1; } 我的程序就是中間的那一橫不能顯示 求幫助 |
1.顯示不正常是因為數碼管動態顯示程序缺少消隱指令。 2.一個定時器中斷只要合理編程可以承擔N項任務。 在你的程序基礎上修改好了,你試試。 #include<reg52.h> #define uint unsigned int #define uchar unsigned char uint n=0; //n:1ms計數變量 char time=99; //time:時間變量 uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共陰極數碼管編碼 uchar table1[]={0xfe,0xfd}; //位選信號 uchar index=0; bit S=0;//秒標志(位變量) void init() { TMOD=0x10; // TH0=(65536-46080)/256; //計時器0計時50ms,20個周期為1s // TL0=(65536-46080)%256; // TH1=0xfc; //計時器1計時1ms,1ms到則顯示下一位數碼管 // TL1=0x66; TH1=0xfc; //計時器1計時1ms,1ms到則顯示下一位數碼管 TL1=0x66; EA=1; // ET0=1; ET1=1; // TR0=1; TR1=1; } void ledscan() { switch(index) { //根據位選變量選擇段選信號 case 0: P0=0x00; //消隱 P2=table1[index]; P0=table[time/10]; break; case 1: P0=0x00; //消隱 P2=table1[index]; P0=table[time%10]; break; default:break; } // P2=table1[index]; //根據位選變量選擇位選信號 index++; if(index>1) //位選只有0,1兩種情況,超過1則清零 index=0; } void main() { init(); while(1) { if(S==1) { S=0; //1秒標志清0 time--; if(time==-1) time=99; } } } /* void timer_0()interrupt 1 { TH0=(65536-46080)/256; //50ms到則50ms計數變量+1 TL0=(65536-46080)%256; n++; }*/ void timer_1()interrupt 3 { //1ms到則顯示下一位 TH1=0xfc; TL1=0x66; n++; if(n>=1000) { n=0; S=1; //1秒標志 } ledscan(); } |
掃描顯示的一個很關鍵點沒處理好,一定要先關閉顯示,再換位,換段碼,再開顯示,否則就顯示錯位了。 可以參考 http://www.zg4o1577.cn/bbs/dpj-135252-1.html 2樓 另外不需要每個延時用一個定時器。整個系統用一個定時器,一般定時1mS。在定時器中斷里面用幾個計數單元,就可以產生10mS, 500mS,1秒等周期狀態,就像時鐘只用一個秒信號,就能產生時、分、一樣。 再定義幾個延時變量,如: u8 delaymS1; u8 delaymS2; 在定時器中斷內,只需加2段語句: if(delaymS1>0) delaymS1--; if(delaymS2>0) delaymS2--; 當需要延時的時候就給變量賦值: delaymS1=10; ..... delaymS2=20; ...... 然后等待變量回“0” if(delaymS1==0) // 10mS延時到 ....... if(delaymS2==0) // 20mS延時到 |