|
我已經(jīng)調(diào)試了好多天了,因?yàn)榘滋焐习啵砩喜庞袝r(shí)間,但是連續(xù)4,5個(gè)晚上都發(fā)現(xiàn)不了原因,目前已經(jīng)可以做到加法了,但是我只要一按鍵,比如按1,按一下馬上彈起,就會(huì)有N個(gè)1出現(xiàn)在8位數(shù)碼管上,出現(xiàn)多少根據(jù)按的時(shí)間決定,求好心人幫幫我。。我仿佛是知道因?yàn)槌绦蛴涗浟宋叶啻芜M(jìn)行了按1的操作,可是我在按鍵檢測(cè)的時(shí)候用了if(keysta[j]==0),相當(dāng)于按鍵彈起的時(shí)候才顯示1。我用的兩個(gè)74HC573接的8位數(shù)碼管,DUAN WEI兩個(gè)IO扣控制鎖存器的,拜謝了。。拜謝了。。
單片機(jī)源程序:
- #include<reg52.h>
- sbit L0=P1^0; //定義L0-L7小燈IO口
- sbit L1=P1^1;
- sbit L2=P1^2;
- sbit L3=P1^3;
- sbit L4=P1^4;
- sbit L5=P1^5;
- sbit L6=P1^6;
- sbit L7=P1^7;
- sbit o4=P3^0; //定義矩陣鍵盤(pán)IO口
- sbit o1=P3^1;
- sbit o2=P3^2;
- sbit o3=P3^3;
- sbit i1=P3^4;
- sbit i2=P3^5;
- sbit i3=P3^6;
- sbit i4=P3^7;
- sbit DUAN=P2^0; //定義段選開(kāi)關(guān)
- sbit WEI=P2^1; //定義位選開(kāi)關(guān)
- unsigned char ledbuff[8]={ //數(shù)碼管顯示緩沖區(qū)
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- unsigned char duanma[]={ //定義單個(gè)數(shù)碼管段位,顯示0-F
- 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71
- };
- unsigned char weima[]={ //定義單個(gè)數(shù)碼管位,顯示第幾個(gè)數(shù)碼管
- 0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe
- };
- unsigned char keysta[4][4]={ //定義矩陣按鍵的當(dāng)前狀態(tài)
- {1,1,1,1},
- {1,1,1,1},
- {1,1,1,1},
- {1,1,1,1}
- };
- unsigned char code keycodemap[4][4]={ //矩陣鍵盤(pán)標(biāo)準(zhǔn)鍵碼映射表
- {0x31,0x32,0x33,0x26}, //數(shù)字鍵1、數(shù)字鍵2、數(shù)字鍵3、加號(hào)
- {0x34,0x35,0x36,0x25}, //數(shù)字鍵4、數(shù)字鍵5、數(shù)字鍵6、減號(hào)
- {0x37,0x38,0x39,0x28}, //數(shù)字鍵7、數(shù)字鍵8、數(shù)字鍵9、乘號(hào)
- {0x30,0x1b,0x0d,0x27} //數(shù)字鍵0、ESC鍵、 等號(hào)、 除號(hào)
- };
- void keydriver();
- unsigned char o=0;
- unsigned char cnt=0;
- void main()
- {
- TMOD=0x01; //計(jì)時(shí)器模式選擇為01,16位計(jì)時(shí)器
- TH0=0xfc; //為T(mén)0賦初值0xFC67,定時(shí)1ms
- TL0=0x67;
- TR0=1; //打開(kāi)計(jì)時(shí)器
- EA=1; //打開(kāi)中斷總開(kāi)關(guān)
- ET0=1; //打開(kāi)中斷T0
- ledbuff[0]=duanma[0];
- while(1)
- {
- keydriver(); //調(diào)用按鍵驅(qū)動(dòng)函數(shù)
- }
- }
- void shownumber(unsigned long num) /* 將一個(gè)無(wú)符號(hào)長(zhǎng)整型的數(shù)字顯示到數(shù)碼管上,num-待顯示數(shù)字 */
- {
- signed char i;
- unsigned char buf[8];
- for(i=0;i<8;i++)
- {
- buf[i]=num%10;
- num=num/10;
- }
- L1=1;
- for(i=7;i>=1;i--) //從最高位起,遇到0轉(zhuǎn)換為空格,遇到非0則退出循環(huán)
- {
- if(buf[i]==0x00)
- {
- ledbuff[i]=0x00;
- }
- else
- break;
- }
- for(;i>=0;i--) //剩余低位都如實(shí)轉(zhuǎn)換為數(shù)碼管顯示字符
- {
- ledbuff[i]=duanma[buf[i]];
- }
- }
- void keyaction(unsigned char keycode)
- {
- static unsigned long result=0; //用于保存運(yùn)算結(jié)果
- static unsigned long addend=0; //用于保存輸入的加數(shù)
- if((keycode>=0x30)&&(keycode<=0x39)) //輸入0-9的數(shù)字
- {
- addend=(addend*10)+(keycode-0x30); //整體十進(jìn)制左移,新數(shù)字進(jìn)入個(gè)位
- shownumber(addend); //運(yùn)算結(jié)果顯示到數(shù)碼管
- }
- else if(keycode==0x26) //按下加號(hào)
- {
- result+=addend;
- addend=0;
- shownumber(result);
- }
- else if(keycode==0x0d) //按下等號(hào)
- {
- result+=addend;
- addend=0;
- shownumber(result);
- }
- else if(keycode==0x1b) //按下ESC
- {
- addend=0;
- result=0;
- shownumber(addend);
- }
- }
- void keydriver()
- {
- unsigned char i,j;
- unsigned char backup[4][4]={ //按鍵值備份,保存前一次的值
- {1,1,1,1},
- {1,1,1,1},
- {1,1,1,1},
- {1,1,1,1}
- };
-
- for(i=0;i<4;i++) //循環(huán)檢測(cè)4*4的矩陣按鍵
- {
- for(j=0;j<4;j++)
- {
- if(keysta[i][j]!=backup[i][j]) //檢測(cè)按鍵動(dòng)作
- { //按鍵按下時(shí)執(zhí)行動(dòng)作
- if(keysta[i][j]==0)
- {
- keyaction(keycodemap[i][j]); //調(diào)用按鍵動(dòng)作函數(shù)
- }
- backup[i][j]=keysta[i][j]; //刷新前一次的備份值
- }
- }
- }
- }
- void keyscan() //鍵盤(pán)消抖,檢測(cè)鍵盤(pán)是否按下
- {
- static unsigned char keyout=0;
- unsigned char j;
- static unsigned char keybuf[4][4]={
- {0xff,0xff,0xff,0xff},
- {0xff,0xff,0xff,0xff},
- {0xff,0xff,0xff,0xff},
- {0xff,0xff,0xff,0xff}
- };
- keybuf[keyout][0]=(keybuf[keyout][0]<<1)|i1; //消抖功能,對(duì)第一列鍵盤(pán)將keybuf[][]賦值為1111 1111或者0000 0000
- keybuf[keyout][1]=(keybuf[keyout][1]<<1)|i2;
- keybuf[keyout][2]=(keybuf[keyout][2]<<1)|i3;
- keybuf[keyout][3]=(keybuf[keyout][3]<<1)|i4;
- for(j=0;j<4;j++)
- {
- if((keybuf[keyout][j])==0x00) //如果keybuf為0000 0000 則視為按下按鍵
- {
- keysta[keyout][j]=0;
- }
- else if((keybuf[keyout][j])==0xff) //如果keybuf為1111 1111 則視為彈起按鍵
- {
- keysta[keyout][j]=1;
- }
- }
- switch(keyout) //對(duì)鍵盤(pán)進(jìn)行行掃描
- {
- case 0:o4=1;o1=0;break;
- case 1:o1=1;o2=0;break;
- case 2:o2=1;o3=0;break;
- case 3:o3=1;o4=0;break;
- default:break;
- }
- keyout++;
- keyout=keyout&0x03; //keyout到4清0
-
- }
- void ledscan() //鍵盤(pán)顯示函數(shù)
- {
- static unsigned char i = 0; //動(dòng)態(tài)掃描的索引
- P0 = 0xFF; //顯示消隱
- switch(i)
- {
- case 0:
- WEI=1;P0=weima[0];WEI=0;DUAN=1;P0=ledbuff[0];i++;DUAN=0;break; //顯示個(gè)位
- case 1:
- WEI=1;P0=weima[1];WEI=0;DUAN=1;P0=ledbuff[1];i++;DUAN=0;break; //顯示十位
- case 2:
- WEI=1;P0=weima[2];WEI=0;DUAN=1;P0=ledbuff[2];i++;DUAN=0;break; //顯示百位
- case 3:
- WEI=1;P0=weima[3];WEI=0;DUAN=1;P0=ledbuff[3];i++;DUAN=0;break;
- case 4:
- WEI=1;P0=weima[4];WEI=0;DUAN=1;P0=ledbuff[4];i++;DUAN=0;break;
- case 5:
- WEI=1;P0=weima[5];WEI=0;DUAN=1;P0=ledbuff[5];i++;DUAN=0;break;
- case 6:
- WEI=1;P0=weima[6];WEI=0;DUAN=1;P0=ledbuff[6];i++;DUAN=0;break;
- case 7:
- WEI=1;P0=weima[7];WEI=0;DUAN=1;P0=ledbuff[7];i++;DUAN=0;break;
- default:i=0;break;
- }
- }
- void interrupttimer0() interrupt 1 //定時(shí)中斷檢測(cè)鍵盤(pán),刷新數(shù)碼管
- {
- TH0=0xfc;
- TL0=0x67;
- keyscan(); //調(diào)用按鍵掃描函數(shù)
- ledscan(); //調(diào)用數(shù)碼管顯示掃描函數(shù)
- }
復(fù)制代碼 |
|