|
基于c语言,状态机实现键盘矩阵0~f
- 功能:状态机实现矩阵键盘 (从0~F的显示)
- 说明: P2^0-P2^3接行,P2^4-P2^7接列,10ms中断扫描
- 单片机: AT89S52
- ******************************************************/
- #include<reg52.h>
- #define KEY P2
- #define NO_KEY 0xff //无按键按下
- #define KEY_STATE0 0 //判断按键按下
- #define KEY_STATE1 1 //确定按键按下
- #define KEY_STATE2 2 //按键释放状态
- #define V_TH0 0Xd8
- #define V_TL0 0Xf0
- #define V_TMOD 0X01
- #define uint unsigned int
- #define uchar unsigned char
- sbit DAT=P0^3;
- sbit CLK=P0^2;
- uint flag=0; //按键扫描标志
- uchar code tab[]={
- 0xed,0x09,0xbc,0x9d,0x59,0xd5,
- 0xf5,0x0d,0xfd,0xdd,0x7d,0xf1,
- 0xe4,0xb9,0xf4,0x74,0x00} ; //0-F, 全灭
- void sendbyte(uchar byte) //这个是数码管的驱动
- {
- uchar num,c;
- num=tab[byte];
- for(c=0;c<8;c++)
- {
- CLK=0;
- DAT=num&0x01;
- CLK=1;
- num>>=1; //右移位赋值
- }
- }
- unsigned char KeyScan()
- {
- static unsigned char key_state=KEY_STATE0;
- uchar key_value,key_temp;
- uchar key1,key2;
-
- KEY=0xf0;
- key1=KEY&0xf0; //确定哪一行的按键按下
- KEY=0x0f;
- key2=KEY&0x0f; //确定哪一列的按键按下
- key_temp=key1|key2; //确定按键位置
-
- switch(key_state) //检测当前状态
- {
- case KEY_STATE0:
- if(key_temp!=NO_KEY)
- {
- key_state=KEY_STATE1; //转换状态
- }
- break;
- case KEY_STATE1:
- if(key_temp==NO_KEY)
- {
- key_state=KEY_STATE0;
- }
- else
- {
- switch(key_temp) //当确定按键按下后,列举所有的按键情况
- {
- case 0x7e: key_value=0;break;
- case 0xbe: key_value=1;break;
- case 0xde: key_value=2;;break;
- case 0xee: key_value=3;break;
- case 0x7d: key_value=4;break;
- case 0xbd: key_value=5;break;
- case 0xdd: key_value=6;break;
- case 0xed: key_value=7;break;
- case 0x7b: key_value=8;break;
- case 0xbb: key_value=9;break;
- case 0xdb: key_value=10;break;
- case 0xeb: key_value=11;break;
- case 0x77: key_value=12;break;
- case 0xb7: key_value=13;break;
- case 0xd7: key_value=14;break;
- case 0xe7: key_value=15;break;
- }
- key_state=KEY_STATE2;
- }
- break;
- case KEY_STATE2:
- if(key_temp==NO_KEY)
- {
- key_state=KEY_STATE0;
- }
- break;
- }
- return key_value;
- }
-
-
- main(void)
- {
- uchar readkey=NO_KEY;
- P2=0xff;
- TMOD=V_TMOD;
- TH0=V_TH0; //12MHz 10Ms
- TL0=V_TL0;
- ET0=1;
- EA=1;
- TR0=1;
- while(1)
- {
- if(flag)
- {
- flag=0;
- readkey=KeyScan();
- switch(readkey) //switch语句里面的case判断后,接着的语句为相应的需要做的事情,
- { //这里只是在数码管显示相应的数值。
- case 0: sendbyte(0);break;
- case 1: sendbyte(1);break;
- case 2: sendbyte(2);break;
- case 3: sendbyte(3);break;
- case 4: sendbyte(4);break;
- case 5: sendbyte(5);break;
- case 6: sendbyte(6);break;
- case 7: sendbyte(7);break;
- case 8: sendbyte(8);break;
- case 9: sendbyte(9);break;
- case 10: sendbyte(10);break;
- case 11: sendbyte(11);break;
- case 12: sendbyte(12);break;
- case 13: sendbyte(13);break;
- case 14: sendbyte(14);break;
- case 15: sendbyte(15);break;
- }
- }
- }
- }
- void timer0() interrupt 1
- {
- TH0=V_TH0; //10Ms
- TL0=V_TL0;
- flag=1;
- }
复制代码
|
评分
-
查看全部评分
|