51单片机矩阵键盘线反转法体会
独立式键盘扫描只需读取IO口状态,而矩阵式键盘描通常有两种实现方法:逐行扫描法和线反转法。
(1) 逐行扫描法
依次从第一至最末行线上发出低电平信号, 如果该行线所连接的键没有按下的话, 则列线所接的端口得到的是全“1”信号, 如果有键按下的话, 则得到非全“1”信号。 (2) 线反转法
线反转法比行扫描速度快,原理是先将行线作为输出线, 列线作为输入线, 行线输出全“0”
信号, 读入列线的值, 那么在闭合键所在的列线上的值必为0;然后从列线输出全“0”信号,再读取行线的输入值,闭合键所在的行线值必为 0。这样,当一个键被按下时, 必定可读到一对唯一的行列值。再由这一对行列值可以求出闭合键所在的位置。
/*在TX-1C实验板上实现如下描述:实验板上电时,数码管不显示,顺序 按下矩阵键盘后,在数码管上依次显示0~F,6个数码管同时显示。这里 用“线反转”的方法写,可以代替郭天祥书上例【4.2.1】该书上使用逐 行扫描的方式。*/
#include
#define uchar unsigned char #define uint unsigned int
sbit duan=P2^6; //打开位选和段选 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;
P0=0; 示
duan=1; duan=0;
//毫秒级延时函数
//段选显示函数
//矩阵键盘扫描函数
//定义行、列值中间变量 //列线输出全为0 //读入行线 //检测有无按键按下 //延时去抖 //如果确实按下 //再次读入行线 //输出当前列线值,行线反转 //读入列线值 //键盘最后组合编码值,也就是键值 //其余情况返回该值 //关闭所有数码管段选,实验板上电数码管不显
P0=0xc0; //选中6位数码管 wei=1; wei=0;
while(1) { key=keyscan(); //用key读取keyscan()的值 switch(key) { case 0xee: key=0; while(keyscan()!=0xff); xianshi(key); break; //while(keyscan()!=0xff)是松手检测语句,松手时检测
case 0xde: 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; case 0xbb: key=10; while(keyscan()!=0xff); xianshi(key); break; case 0x7b: key=11; while(keyscan()!=0xff); xianshi(key); break; case 0xe7: key=12; while(keyscan()!=0xff); xianshi(key); break; case 0xd7: key=13; while(keyscan()!=0xff); xianshi(key); break; case 0xb7: key=14; while(keyscan()!=0xff); xianshi(key); break; case 0x77: key=15; while(keyscan()!=0xff); xianshi(key); break; default: break; } } }
/*后记*/
/*刚开始写这个程序时我把主函数里面的switch—case语句这样写的, while(1) { key=keyscan(); //用key读取keyscan()的值 switch(key) { case 0xee: key=0; break; case 0xde: key=1; break; case 0xbe: key=2; break;
break;