51单片机矩阵键盘线反转法体会
独立式键盘扫描只需读取IO口状态,而矩阵式键盘描通常有两种实现方法: 逐行扫描法和线反转法。 (1)逐行扫描法
依次从第一至最末行线上发出低电平信号,如果该行线所连接的键没有按下的话,则列线所接的端口得到的是全“1”信号,如果有键按下的话,则得到非全“1”信号。
(2)线反转法
线反转法比行扫描速度快,原理是先将行线作为输出线,列线作为输入线,行线输出全“0”信号,读入列线的值,那么在闭合键所在的列线上的值必为0;然后从列线输出全“0”信号,再读取行线的输入值,闭合键所在的行线值必为0。这样,当一个键被按下时,必定可读到一对唯一的行列值。再由这一对行列值可以求出闭合键所在的位置。
/*在TX-1C实验板上实现如下描述:
实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时显示。这里用“线反转”的方法写,可以代替郭天祥书上例【
4.2.1】该书上使用逐 行扫描的方式。*/ #include
#define uchar unsigned char #define uintunsigned int
sbit duan=P2^6;//打开位选和段选
1 / 8
sbit wei=P2^7;
uchar code table[]={//数码管显示数值表 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint x){uint i,j; for(i=x;i>0;i--)
for(j=110;j>0;j--);}void xianshi(uchar num){P0=table[num]; duan=1;
duan=0;}uchar keyscan(void){uchar h,l; P3=0x0f; h=P3&0x0f; if(h!=0x0f) {delay (10);
if(h!=0x0f){h=P3&0x0f; P3=0xf0; l=P3&0xf0; return (h+l);}}
return 0xff;}void main(){uchar key;
2 / 8
P0=0;示duan=1;
duan=0;//毫秒级延时函数 //段选显示函数 //矩阵键盘扫描函数 //定义行、列值中间变量 //列线输出全为0 //读入行线 //检测有无按键按下 //延时去抖 //如果确实按下 //再次读入行线
//输出当前列线值,行线反转 //读入列线值
//键盘最后组合编码值,也就是键值 //其余情况返回该值
//关闭所有数码管段选,实验板上电数码管不显 P0=0xc0;//选中6位数码管 wei=1; wei=0; while
(1){key=keyscan();//用key读取keyscan()的值
3 / 8
switch(key){case 0xee:
key=0;while(keyscan()!=0xff); xianshi(key); break; //while(keyscan()!=0xff)是松手检测语句,松手时检测 case0xde:
key=1;while(keyscan()!=0xff);xianshi(key);//keyscan()函数会得到返回值0xff,!=oxff时表示按下去了
case 0xbe:
key=2;while(keyscan()!=0xff); xianshi(key); break; case 0x7e:
key=3;while(keyscan()!=0xff); xianshi(key); break; case 0xed:
key=4;while(keyscan()!=0xff); xianshi(key); break; case 0xdd:
key=5;while(keyscan()!=0xff); xianshi(key); break; case 0xbd:
key=6;while(keyscan()!=0xff); xianshi(key); break; case 0x7d:
key=7;while(keyscan()!=0xff); xianshi(key); break; case 0xeb:
key=8;while(keyscan()!=0xff); xianshi(key); break; case 0xdb:
key=9;while(keyscan()!=0xff); xianshi(key); break;
4 / 8
相关推荐: