- #include <REGX52.H>
- #define KeybufSize 16 //键盘缓存大小
- unsigned char KeyBuf[KeybufSize]; //键盘缓存数组,先进先出
- unsigned char KeybufWp = 0; //缓存写键值
- unsigned char KeybufRp = 0; //缓存读键值
- unsigned char keyHit(void); //函数判断是否有键按下
- unsigned char keyGet(void); //函数取键值
- void keyPut(unsigned char ucKeyVal); //
- const unsigned char code seg7code[] ={0x3f, 0x06, 0x5b, 0x4f,
- 0x66, 0x6d,0x7d, 0x07,
- 0x7f, 0x6f, 0x77,0x7c,
- 0x39, 0x5e, 0x79, 0x71,0x00}; //seg7 com cathod
- unsigned char keyScan(void); //键盘扫描,行列反转法
- /*******************************************************************
- p1口接7段LED,p2接键盘输入,p2.0~2.3接KEYPAD-SMALLCALC的行a,b,c,d脚
- p2.4~2.7接4个列脚 ,单片机AT89C51,晶振频率12MHz
- ********************************************************************/
- void main(void)
- {
-
- TMOD = (TMOD & 0XF0) | 0X01; //定时器0,工作方式1
- EA = 1; //开中断允许
- ET0 = 1;
- TH0 = (-20000)>>8; //定时器0计时20ms
- TL0 = -20000;
- TR0 = 1;
- while(1)
- {
- if(keyHit() != 0) //有键按下,输出显示。
- P1 = seg7code[keyGet()];
- }
- }
- /***********************************************************
- 利用T0内部中断来扫描键盘,20ms扫描一次,如有键按下,扫描键盘,
- 并存键盘缓存,如果按键松开,再判断有没有键按下。
- ************************************************************/
- void timer0intr(void) interrupt 1
- {
- static unsigned char sts = 0;
- TH0 = (-20000)>>8;
- TL0 = -20000;
- P2_0 = 1;
- switch(sts)
- {
- case 0: if(keyScan() != 0) //判断有无键按下,有则转入状态1
- sts = 1;break;
- case 1: if(keyScan() == 0) //如果按错,转回状态0
- sts = 0;
- else
- {
- sts = 2;
- keyPut(keyScan()); //确认有键按下,转入状态2,并把键号写入缓存
- }
- break;
- case 2: if(keyScan() == 0)
- sts = 3; break; //判断按键松开,转入状态3
- case 3: if(keyScan() != 0)
- sts = 2;
- else
- sts = 0; //确认按键已经松开,会状态0,否则回状态2,重新判断
- break;
- }
- }
- /***********************************************************
- 行列反转键盘扫描
- ************************************************************/
- unsigned char keyScan( void ) //返回0表示无按键,或无效按键,其它值为按键编码值
- {
- code unsigned char keyCode[16]=
- //0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF
- { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 4, 0 };
- unsigned char x, y, retVal;
- P1=0x0f; //低四位输入,高四位输出0
- x=P1&0x0f; //P1输入后,清高四位,作为X值
- P1=0xf0; //高四位输入,低四位输出0
- y=(P1 >> 4) & 0x0f; //P1输入后移位到低四位,并清高四位,作为Y值
- retVal = keyCode[x]*4 + keyCode[y]; //根据本公式倒算按键编码
- if( retVal==0 ) return(0);
- else return( retVal-4 );
- }
- unsigned char keyHit(void) //判断是否有键按下。
- {
- if(KeybufWp == KeybufRp)
- return 0;
- else return 1;
- }
- unsigned char keyGet(void) //读取键值
- {
- unsigned char retVal;//暂存读出键值
- while(!keyHit());
- retVal = KeyBuf[KeybufRp];
- if(++KeybufRp >= KeybufSize)
- KeybufRp = 0;
- return retVal;
- }
- void keyPut(unsigned char ucKeyVal)
- {
- KeyBuf[KeybufWp] = ucKeyVal;//键值存入数组
- if(++KeybufWp >= KeybufSize)
- KeybufWp = 0;
- }
哎,问题又来了,突然发现按下键盘之后显示的值完全不对,并且只能按一个键,
并且再也无法输入,不知道是哪的问题,大家帮忙看看吧。谢谢了。