第第13章章 单片机实现单片机实现4*4矩阵键矩阵键盘控制项目盘控制项目 学习内容•13.1 项目需求•13.2 项目工作原理分析•13.3 项目硬件电路设计•13.4 项目软件程序设计•13.5系统调试结果总结13.1 项目需求项目需求•矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成矩阵键盘在行线和列线的每个交叉点上设置一个按键这样键盘上按键的个数就为4*4个这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率•项目要求:设定矩阵键盘编号,按下键盘中的某个按键,可以通过数码管看到显示对应的键盘编号值 (4*4)矩阵键盘实物图 13.2 项目工作原理分析项目工作原理分析•4*4矩阵键盘的行信号分别接P2.0—P2.3,列信号分别接P2.4—P2.7,无按键闭合时,P2.0—P2.3与 P2.4—P2.7开路当有键闭合时,与闭合键相连的两条I/O口线之间短路判断矩阵键盘有按键按下方法如下:先让P2.0—P2.3输出低电平,监测P2.4—P2.7的状态,如果P2.4—P2.7输出为高电平则没有按键闭合,如果检测到P2.4—P2.7输出为低电平则表示有按键按下发生闭合状态,以上只是说明有按键闭合,具体是哪个按键闭合好需要进一步检测。
•一旦确定有按键已经稳定闭合后,接着判断为哪一个按键闭合,采用对按键进行扫描的方式,依次给每一条列线送低电平,其余各列都为高电平,并检测每次扫描的行状态每当扫描输出某一列为低电平时,相继读入行线状态若全为高电平,表示为低电平的这列没有按键闭合否则行线不全部为高电平,表示为低电平的这列上有按键闭合确定闭合按键的位置后,计算出按键值,产生按键码•在矩阵按键处理过程中,一旦检测到有按键闭合与确认按键已经稳定闭合期间,通过调用10-20ms延时子程序避开按键抖动问题由于按键是机械器件,按下或者松开时有固定的机械抖动,抖动图如图所示•按键去抖分为硬件去抖和软件去抖,硬件去抖最简单的是按键两端并联电容,容量根据实验而定软件去抖使用方便不增加硬件成本,容易调试,所以现在处理按键抖动问题大部分选择软件去抖软件去抖操作步骤如下: ① 检测到按键按下后进行10-15ms延时,用于跳过这个抖动区域 ② 延时后再检测按键状态,如果没有按下表明是抖动或者干扰造成,如果仍旧按下,可以认为是真正的按下并进行对应的操作 ③ 同样按键释放后也要进行去抖动延时,延时后检测按键是否真正松开•采用单片机控制矩阵按键实现按键键码值显示的电路结构由51单片机最小系统、数码显示电路、数码驱动电路、矩阵键盘电路和电源供电电路组成。
单片机控制矩阵键盘电路结构图 13.3 项目硬件电路设计项目硬件电路设计•矩阵键盘电路的行信号分别接P2.0—P2.3,列信号分别接P2.4—P2.7,进行按键检测时,假设查询到P25为低电平,P24 P26 P27为高电平,那么可能按下的按键为S2 S6 S10 S14进一步探测,先把P20设置为低电平,P21 P22 P23为高电平,如果此时P25一直为低电平,就是S2按键被按下如果P25为高电平,令其P21设为低电平,P20 P22 P23为高电平,如果此时P25为低电平,表明S6按键被按下依此类推,可以确定S1-S16中哪个按键被按下单片机控制矩阵键盘硬件电路原理图 13.4 项目软件程序设计项目软件程序设计•矩阵键盘行线P20~P23为输出线,列线P24~P27为输入线单片机将行线(P20~P23)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下,再来进一步确定键值 系统软件设计流程图 程序代码•#include //包含头文件,头文件包含特殊功能寄存器的定义•#define uchar unsigned char•#define uint unsigned int•unsigned char const table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, • 0x80,0x90,0x88,0x83,0xa7,0xa1,0x86,0x8e};//定义共阳数码管段码表0-F•uchar keyscan(void);//键盘扫描函数声明•void delay(void); //延时函数声明•uchar keyscan(void) //键盘扫描函数•{• uchar key_h,key_l;//行列值中间变量• P2=0xf0; //行线输出全为0• key_h=P2&0xf0; //读入列线值• if(key_h!=0xf0) //先检测有无按键按下• {• delay(); //去抖• if(key_h!=0xf0)• {• key_h=P2&0xf0; //读入列线值• P2=key_h|0x0f; //输出当前列线值• key_l=P2&0x0f; //读入行线值• return(key_h+key_l);//键盘最后组合码值• }• }•return(0xff); //返回该值•} void delay(void) //延时函数{unsigned char i,j;for(i=0;i<20;i++)for(j=0;j<250;j++);}•void main() //定义主函数•{• uchar key;• P1=0xff; //设置数码管位码端电平,显示按键上的按键码• while(1)•{• key=keyscan(); //调用键盘扫描,• switch(key)• {• case 0xee:P0=table[0];break; //显示按键码“0” • case 0xde:P0=table[1];break; //显示按键码“1” • case 0xbe:P0=table[2];break; //显示按键码“2” • case 0x7e:P0=table[3];break; //显示按键码“3” • case 0xed:P0=table[4];break; //显示按键码“4” • case 0xdd:P0=table[5];break; //显示按键码“5” • case 0xbd:P0=table[6];break; //显示按键码“6” • case 0x7d:P0=table[7];break; //显示按键码“7” • case 0xeb:P0=table[8];break; //显示按键码“8” • case 0xdb:P0=table[9];break; //显示按键码“9” • case 0xbb:P0=table[10];break; //显示按键码“a” • case 0x7b:P0=table[11];break; //显示按键码“b” • case 0xe7:P0=table[12];break; //显示按键码“c” • case 0xd7:P0=table[13];break; //显示按键码“d” • case 0xb7:P0=table[14];break; //显示按键码“e” • case 0x77:P0=table[15];break; //显示按键码“f” • }• }•}•void send_char(unsigned char txd) // 传送一个字符•{•SBUF = txd;•while(!TI);// 等特数据传送•TI = 0;// 清除数据传送标志•}•void send_str() // 传送字串•{•unsigned char i = 0;•uint j;•while(str[i] !=0x00)•{•SBUF = str[i];•while(TI==0);// 等特数据传送•TI = 0;// 清除数据传送标志•i++;// 下一个字符•}•for(j=0;j<50000;j++); //延迟•}13.5系统调试结果总结系统调试结果总结•采用单片机控制矩阵键盘实现对应按键值在数码管上显示,其系统的硬件电路和软件程序在单片机开发板上进行调试,将13.4节Keil编译完成后产生的.hex文件结合2.4节ISP程序烧写知识,将.hex文件烧写到51单片机中。
通过给开发板上电,按动矩阵键盘的S13按键(对应的按键码为“d”),则对应的4位集成数码管直接显示对应的按键值“d”,实现项目要求。