⑴ 想在51單片機上用矩陣鍵盤實現四位數的顯示 可是鍵盤根本沒用 直接顯示的數
你提問過,四位數碼管的顯示程序,現在又增加了矩陣鍵盤。現在的功能增加了,可主程序卻沒有變,那怎麼可能行呢?你這些程序在編譯時,就沒有提示你有錯誤嗎?或者警告什麼的?
原來只是四位數碼管顯示固定的 數,可現在即有鍵盤了,又要隨時改變顯示的數了,主程序要重寫了。
void main()
{
while(1) //必須要這么寫了
{ //這才是主循環程序開始
DigDisplay(); //要把顯示程序放在第一行
qian=; //這樣,四位數碼管顯示的數,像計算器一樣,從右向左移動
=shi;
shi=ge;
ge=display();
//以後再增加程序功能,要在這下面增加
}//最後必須要有兩個大括弧
}
unsigned char display() //掃描次數,這數據類型要改
{
unsigned char i,b; //不要用int 型
for(i=0;i<4;i++)
{
b= keydown();
}
return b;
}
⑵ 51單片機C語言程序4個獨立按鍵實現對數碼管數字顯示的加減清零等
#include<reg52.h>
//P0是數碼管。P1是LED.P2是按鍵
sbitKEY_OUT_1=P2^3;
sbitKEY_OUT_2=P2^2;
sbitKEY_OUT_3=P2^1;
sbitKEY_OUT_4=P2^0;
#defineucharunsignedchar
#defineulintunsignedlong
#defineFrequency10//定時器中斷時間=f*T
#defineTime1//一個周期1ms
#defineTubeNumber6//數碼管個數
#defineKeyLine4//矩陣按鍵行數
#defineKeyColumn4//矩陣按鍵列數
//數碼管真值表
ucharcodeLED_Number[]={0x0C,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//ucharcodeLED_Alphabet[]={0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0x8C,0xC1,0x91,0x9C};
/*0~9
A~F(b、d為小寫)HLPUyo*/
ucharLED_Buff[TubeNumber]={0xff,0xff,0xff,0xff,0xff,0xff};
/*數碼管顯示緩沖區,0xff確保初始時都不亮.
不可寫成ucharcodeLED_Buff[]。code定義變數寫入room,不可修改*/
//矩陣按鍵編號到標准盤碼的映射表
ucharcodeKeyCodeMap[4][4]={
(0x31,0x32,0x33,0x26),//數字鍵1、數字鍵2、數字鍵3、向上鍵
(0x34,0x35,0x36,0x25),//數字鍵4、數字鍵5、數字鍵6、向左鍵
(0x37,0x38,0x39,0x28),//數字鍵7、數字鍵8、數字鍵9、向下鍵
(0x30,0x1B,0x0D,0x27)};//數字鍵0、ESC鍵、回車鍵、向右鍵
ucharStaFlag[KeyLine][KeyColumn]={(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按鍵是否穩定標志
voidStartTime0();
voidTubeDisplay(ulintsec);
ulintpow(x,y);
voidTubeScan();
voidKeyAction(ucharkeycode);
voidKeyDriver();
voidKeyScan();
voidmain()
{
P1=0x08;//使能U3,選擇數碼管。
StartTime0();
while(1)KeyDriver();
}
//定時器0啟動函數
voidStartTime0()
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-Time*100)/256;
TL0=(65536-Time*100)%256;
PT0=1;
/*定時器0優先中斷控制位。
IP這個寄存器的每一位,表示對應中斷的搶占優先順序,每一位的復值都是0,當我們把某一位設置為1的時候,這一位優先順序就比其它位的優先順序高了。
比如我們設置了PT0位為1後,當單片機在主循環或其他中斷程序執行時,一旦TO發生中斷,作為更高優先順序,程序馬上執行T0.若在T0程序執行時,
其他中斷程序發生中斷,仍執行TO直到T0中斷結束後再執行其他程序。
*/
}
//中斷服務函數
voidTo_time0()interrupt1using0
{
staticucharcnt;//記錄TO中斷次數
// staticulintsec;//記錄經過秒速
//判斷是否溢出
if(TF0==1)
{
TF0=0;
TH0=(65536-Time*100)/256;
TL0=(65536-Time*100)%256;
}
if(cnt>=Frequency)
{
cnt=0;
//sec++;
// Tube_Display(sec);
TubeScan();
KeyScan();
}
}
//數碼管顯示函數
voidTubeDisplay(ulintnom)
{
ucharm=2;//小數部分位數
uchari;//傳輸索引
//秒速達到上限清零
if(nom>pow(10,TubeNumber-m))nom=0;
//分別傳輸小數部分和整數部分
for(i=0;i<m;i++)
LED_Buff[i]=LED_Number[nom/pow(10,i)%10];
for(i=0;i<(TubeNumber-m);i++)
LED_Buff[i+m]=LED_Number[nom/pow(10,i)%10];
//點亮小數點
LED_Buff[m]&=0x7f;
}
//平方運算函數
ulintpow(x,y)//x為底,為冪
{
ulintp,i=1;
//平方運算
for(i=1;i<=y;i++)
p*=x;
//輸出結果
returnp;
}
//數碼管動態函數
voidTubeScan()
{
staticuchari=0;//動態掃描索引
//關閉所有段選位,數碼管消隱
P0=0xff;
//for(i=0;i<Tube_number;i++)
P1=(P1&0xf8)|i;//位選索引賦值到P1口低3位
P0=LED_Buff[i];//緩沖區中的索引位置數據傳輸到P0口
if(++i>=TubeNumber)i=0;//索引遞增循環,遍歷整個緩沖區
}
//矩陣按鍵動作函數
voidKeyAction(ucharkeycode)
{
staticulintresult;
ulintnom=0;
//輸入數字0~9
if((keycode>=0x30)&&(keycode<=39))
{
nom=(nom*10)+(keycode-0x30);//十進制整體左移,新數進入各位
TubeDisplay(nom);
}
//輸入方向鍵
if((keycode>=0x25)&&(keycode<=28))
switch(keycode)
{
case0x26:result+=nom;nom=0;TubeDisplay(result);
case0x28:result-=nom;nom=0;TubeDisplay(result);
case0x25:result=1;result*=nom;nom=0;TubeDisplay(result);
case0x27:result=1;result/=nom;nom=0;TubeDisplay(result);
}
elseif(keycode==0x0d)TubeDisplay(result);//輸入回車鍵,輸出最終結果
elseif(keycode==0x1b)//輸入ESC鍵,清零
{
nom=result=0;
TubeDisplay(nom);
}
}
//矩陣按鍵驅動函數
voidKeyDriver()
{
ucharl,c;
staticucharbackup[KeyLine][KeyColumn]={(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按鍵值備份,保存前一次值
for(l=0;l<KeyLine;l++)
{
for(c=0;c<KeyColumn;c++)
{
if(backup[l][c]!=StaFlag[l][c])
{//檢測按鍵動作
if(backup[l][c]==1)//按鍵按下時執行
KeyAction(KeyCodeMap[l][c]);//調用動作函數
backup[l][c]=StaFlag[l][c];//刷新前一次備份值
}
}
}
}
//矩陣按鍵掃描函數
voidKeyScan()
{
ucharl=0;//矩陣按鍵掃描輸出索引
ucharc=0;//矩陣按鍵掃描列索引
ucharkeybuff[KeyLine][KeyColumn]={(0xff,0xff,0xff,0xff),(0xff,0xff,0xff,0xff),
(0xff,0xff,0xff,0xff),(0xff,0xff,0xff,0xff)};//矩陣按鍵掃描緩沖區
//將一行的四個按鍵移入緩沖區
for(l=0;l<KeyColumn;l++)
keybuff[l][c]=((0xfe|(P2>>(4+l))&0x01));
//按鍵消抖
for(l=0;l<KeyLine;l++)
{
if((keybuff[l][c]&0x0f)==0x00)//連續4次掃描都為0,判斷4*4ms內都是按下狀態,可認為按鍵已穩定按下
StaFlag[l][c]=0;
elseif((keybuff[l][c]&0x0f)==0x0f)//連續4次掃描都為1,判斷4*4ms內都是彈起狀態,可認為按鍵已穩定彈起
StaFlag[l][c]=1;
}
for(c=0;c<KeyColumn;c++)
{
switch(c)//根據索引,釋放當前輸出腳拉低下次的根據索引
{
case0:KEY_OUT_4=1;KEY_OUT_1=0;break;
case1:KEY_OUT_1=1;KEY_OUT_2=0;break;
case2:KEY_OUT_2=1;KEY_OUT_3=0;break;
case3:KEY_OUT_3=1;KEY_OUT_4=0;break;
default:break;
}
}
}
⑶ 51單片機如何利用4個七段數碼管採用動態顯示顯示4位數字,如2035
不停地利用人的視覺暫留,在一個合適的速度下依次顯示1個2,1個0,1個3,1個5.
當顯示一個「2」的時候,其他三位都是空的,以此類推。
但人眼是看不到短時間內這些變化的,假如這個行為不斷循環,那麼人看到的就是「2035」,而不是單個的數字。
比如說吧:
...
P1=num[2];//假設num[2]是0x5b,即"2"
P20=1;//假設使能端是高有效,按實際情況來。
delay();//延長50ms應該可以把,不能太長(過0.1秒就能看出來了),最好也不要太短
P1=num[0];
P21=1;
delay();
...
⑷ 運用51單片機實現4位8段LED數碼管的動態數字顯示,寫出C語言程序
#include<reg51.h>
#define uchar unsigned char;
uchar distab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; //0到f
uchar number,nn=0;
uchar dat[]={2,0,1,2,1,1,4,5,8,2};
void t0isr() interrupt 1
{
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
number++;
number%=4;
switch(number)
{
case 0:P2=0x08;P0=distab[nn];
break;
case 1:P2=0x04;P0=distab[nn+1];
break;
case 2:P2=0x02;P0=distab[nn+2];
break;
case 3:P2=0x01;P0=distab[nn+3];
break;
default:break;
}
nn++;
nn%=7;
}
main()
{
TMOD=0x01;
TH0=(65536-5000)/256;
TL0=(65536-5000)%256;
TR0=1;
ET0=1;
EA=1;
while(1);
}