9.17键盘的操作
键盘的应用和分类:
键盘分为编码键盘和非编码键盘,键盘上闭合键的识别是由专门的硬件编码器实现,并产生键编码号或者是键值的成为编码键盘,如计算机的键盘
靠软件编程来识别的称为非编码键盘;
在单片机组成的各种系统中,用的最多的是非编码键盘,也有用到编码键盘的
非编码键盘又有独立键盘和矩阵键盘。
要先像键盘里面先写1;在读取操作
示例代码:
#include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit ld1 = P1^0; sbit key1 = P3^4; sbit dula = P2^6; sbit wela = P2^7; uchar num; uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void display(num); main() { P3 = 0xff; while(1) { display(num); if(key1==0) { ld1 = 0; num++; if(num==10) num = 0; while(key1!=1);//松手检测 } else ld1 = 1; } } void display(num) { wela = 1; P0 = 0xfe; wela = 0; P0 = 0x0; dula = 1; P0 = table[num]; dula = 0; dula = 1;//关灯操作 P0 = 0x0; dula = 0; } View Code
这个程序看上去无懈可击,但是在实际过程中,有一个相当大打bug,那就是,你按住键盘的时候,数码管不显示数字,这不是很坑爹,所以,位选信号是开始就要打开的正确的代码是
#include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit ld1 = P1^0; sbit key1 = P3^4; sbit dula = P2^6; sbit wela = P2^7; uchar num; uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void display(num); main() { P3 = 0xff; wela = 1; P0 = 0xfe;//打开位选线 wela = 0; while(1) { if(key1==0) { ld1 = 0; num++; if(num==10) num = 0; while(key1!=1);//松手检测 } else ld1 = 1; dula = 1; P0 = table[num];//在循环中不断送入段选 dula = 0; } }
去抖:由于按键接触的时候会出现抖动,所以,要进行去抖操作
去抖有硬件消抖和软件消抖
硬件消抖要用专门的硬件消抖电路,导致外部电路复杂,在单片机中用不着
软件消抖,一般是延时5毫秒检测
#include<reg52.h> #define uint unsigned int #define uchar unsigned char sbit ld1 = P1^0; sbit key1 = P3^4; sbit dula = P2^6; sbit wela = P2^7; uchar num; uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void delay(uint x); main() { P3 = 0xff; wela = 1; P0 = 0xfe;//打开位选线 wela = 0; while(1) { if(key1==0) { delay(10);//延时十毫秒 if(key1 == 0)//确实按下去了 { ld1 = 0; num++; if(num==10) num = 0; while(key1!=1);//松手检测 delay(10); //检测是否松手 while(!key1); } } else ld1 = 1; dula = 1; P0 = table[num];//在循环中不断送入段选 dula = 0; } } void delay(uint x) { uint y,z; for(y=x;y>0;y--) for(z=110;z>0;z--); }
矩阵键盘:无论是矩阵键盘还是独立键盘,单片机检测其是否被按下去的依据都是一样的,也就是检测该键盘对应的I/O口是否为低电平,独立键盘有一段固定是低电平,单片机写程序时检测比较方便,电路时矩阵键盘的两端都与单片机deI/O口相连,因此在检测时,先送入一列为低电平,其余的全部为高电平,此时我们确定了列数,然后立即轮流检测一次各行是否有低电平,检测到某一行为低电平(这是我们有确定了行数),着我们便可确定是哪一行哪一列的按键被按下去。
示例代码:
#include<reg52.h> sbit wela =P2^6; sbit dula = P2^7; #define uchar unsigned char #define uint unsigned int void delay(uint z); uchar num,num1,temp; uchar keyscan(); uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71,0x0}; main() { wela = 1; P0 = 0x0; wela = 0; while(1) { num1 = keyscan(); dula =1; P0 = table[num1]; dula = 0; } } void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } uchar keyscan() { P3 = 0xfe;//1111 1110 temp = P3; temp = temp&0xf0;//11110000 while(temp!=0xf0)//如果有键摁下 { delay(5);//再次检测P3口 temp = P3; temp = temp&0xf0; while(temp!=0xf0) { temp = P3; switch(temp) { case 0x7e:num = 1; break; case 0xbe:num = 2; break; case 0xde:num = 3; break; case 0xee:num = 4; break; } while(temp!=0xf0)//松手检测 { temp = P3; temp = temp&0xf0; } } } P3 = 0xfd;//1111 1101 temp = P3; temp = temp&0xf0;//11110000 while(temp!=0xf0)//如果有键摁下 { delay(5);//再次检测P3口 temp = P3; temp = temp&0xf0; while(temp!=0xf0) { temp = P3; switch(temp) { case 0x7d:num = 5; break; case 0xbd:num = 6; break; case 0xdd:num = 7; break; case 0xed:num = 8; break; } while(temp!=0xf0)//松手检测 { temp = P3; temp = temp&0xf0; } } } P3 = 0xfb;//1111 1011 temp = P3; temp = temp&0xf0;//11110000 while(temp!=0xf0)//如果有键摁下 { delay(5);//再次检测P3口 temp = P3; temp = temp&0xf0; while(temp!=0xf0) { temp = P3; switch(temp) { case 0x7b:num = 9; break; case 0xbb:num = 10; break; case 0xdb:num = 11; break; case 0xeb:num = 12; break; } while(temp!=0xf0)//松手检测 { temp = P3; temp = temp&0xf0; } } } P3 = 0xf7;//1111 0111 temp = P3; temp = temp&0xf0;//11110000 while(temp!=0xf0)//如果有键摁下 { delay(5);//再次检测P3口 temp = P3; temp = temp&0xf0; while(temp!=0xf0) { temp = P3; switch(temp) { case 0x77:num = 13; break; case 0xb7:num = 14; break; case 0xd7:num = 15; break; case 0xe7:num = 16; break; } while(temp!=0xf0)//松手检测 { temp = P3; temp = temp&0xf0; } } } return num; }
按键操作的数字有规律,第一行为0xfe,那么其次的数是7bde,加上e,0x7e,0xbe,0xde,0xee
第二行是0xfd,那么其次的数是7bde,加上d,0x7d,0xbd,0xdd,0xed
第三行是0xfb,那么其次的数是7bde,加上b,0x7b,0xbb,0xdb,0xeb,
第四行是0xf7,那么其次的数是7bde,加上7,0x77,0xb7,0xd7,,0xe7
版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3327186.html