矩阵键盘——按下矩阵按键,数码管显示出位置对应的字符(0123 4567 89Ab CdEF)

时间:2025-03-15 08:45:33
/*按下矩阵按键,数码管显示出位置对应的字符(0123 4567 89Ab CdEF)*/ #include <> #define uchar unsigned char #define uint unsigned int sbit dula=P2^6;//数码管段显 sbit wela=P2^7;//数码管位显 uchar disnum,temp,key,num; //段显编码的下标(返回值),临时变量,键值,段显编码的下标(调用值) uchar code table_du[]={//共阴极8段数码管段显编码 0x3f,0x06,0x5b,0x4f,0x66,0x6d, //012345 0x7d,0x07,0x7f,0x6f,0x77,0x7c, //6789Ab 0x39,0x5e,0x79,0x71,0x00}; //CdEF无 void delay(uchar);//声明 延时函数 uchar keyscan();//声明 矩阵键盘扫描函数 void main() { disnum=16;//没有按键按下时,默认段显为“无”(不显示) wela=1;//位显允许写入 P0=0xfe;//1111 1110,仅点亮第一位数码管 wela=0;//位显锁存 while(1) { P0=table_du[keyscan()];//预写入段显 /************************************************************** 其实此语句可由以下段落的语句替代: keyscan(); //获取 段显编码的下标(返回值) num=disnum; //段显编码的下标(调用值) P0=table_du[num]; //预写入段显 **************************************************************/ dula=1;//段显允许写入 dula=0;//段显锁存 } } /*【我们记 由左到右数第x行,由上到下数第y列 的按键为 key[x,y]】*/ uchar keyscan()//矩阵键盘扫描函数;检测 矩阵按键 中被按下的 按键 的位置信息 { P3=0xf0;//1111 0000,初始化,令高四位(列)=1,低四位(行)=0 /*********************************************************** 如果 某列中有按键被按下,行列接通而短路, 那么 对应列的 P3口高四位 就会 强制 变为0,比如: 若 key[2,3](即S12)被按下,则 P3=1011 0000 ************************************************************/ temp=P3;//取此时P3的值(此时的temp仅包含了列的位置信息) temp=temp&0xf0;//按位与,取高四位(列),低四位(行)置0 if(temp!=0xf0)//如果高四位不全为1,说明为P3口高四位为0的列有按键被按下 { delay(5);//等10ms,消除 按前 抖动 if(temp!=0xf0)//如果高四位真的不全为1,说明该列真的有按键被按下 { temp=P3;//取此时P3的值(此时的temp仅包含了列的位置信息) temp=temp|0x0f;//按位或,保留高四位(列)的值,低四位(行)置1 P3=temp;//P3口输出这个数(对应的高低电平) /*由于P3高四位中对应该按键的列为0,此时按键还未松开, 行列接通而短路,那么其对应行的P3口低四位就会 强制 为0*/ key=P3;//记录此时P3的值(此处key的值已经包含行列的全部位置信息) switch(key) {//不同的key代表着不同的按键被按下 //那么,就可以根据key来确定要输出的字符的段显编码的下标 case 0xee:disnum=0;//key[1,1](S6) 1110 1110 break; /*列 行*/ case 0xde:disnum=1;//key[1,2](S7) 1101 1110 break; case 0xbe:disnum=2;//key[1,3](S8) 1011 1110 break; case 0x7e:disnum=3;//key[1,4](S9) 0111 1110 break; case 0xed:disnum=4;//key[2,1](S10) 1110 1101 break; case 0xdd:disnum=5;//key[2,2](S11) 1101 1101 break; case 0xbd:disnum=6;//key[2,3](S12) 1011 1101 break; case 0x7d:disnum=7;//key[2,4](S13) 0111 1101 break; case 0xeb:disnum=8;//key[3,1](S14) 1110 1011 break; case 0xdb:disnum=9;//key[3,2](S15) 1101 1011 break; case 0xbb:disnum=10;//key[3,3](S16) 1011 1011 break; case 0x7b:disnum=11;//key[3,4](S17) 0111 1011 break; case 0xe7:disnum=12;//key[4,1](S18) 1110 0111 break; case 0xd7:disnum=13;//key[4,2](S19) 1101 0111 break; case 0xb7:disnum=14;//key[4,3](S20) 1011 0111 break; case 0x77:disnum=15;//key[4,4](S21) 0111 0111 break; } } } return disnum;//返回要输出的字符的段显编码的下标 } void delay(uchar x)//延时函数 { uchar a,b; for(a=x;a>0;a--) for(b=200;b>0;b--); }