若单片机需要连接多个按键,每个按键与单片机的i/o端口单独连接的方式就不太适用了,因为单片机的i/o端口是单片机系统与外界设备交互的重要资源,如果采用按键与i/o端口独立连接的方式,就会占用过多的i/o端口资源,导致单片机与其它外部设备无法连接。在这种情况下,可以使用矩阵键盘,实现多个按键与单片机的连接,而且不浪费单片机的i/o端口资源。
矩阵键盘是一种很好地节约i/o端口资源的技术方法,矩阵键盘将多个按键排列成矩阵形式。例如:将16个按键排成4行4列,每行将按键的一端连接在一起构成行线,每列将按键的另一端连接在一起构成列线,这样一共有4行4列8根线,将这8根线连接到单片机的8个i/o端口上,通过检测程序扫描矩阵键盘就可以检测16个按键。通过这种连接方式,可以实现3行3列9个键,5行5列25个键,6行6列36个键等多个按键的检测。
上图为设计的4 x 4矩阵键盘,每行4个按键,每列4个按键,可以检测16个按键。每列按键的右端连接在一起,分别连接p3.4 ~ p3.7,每行按键的左端连接在一起,分别连接p3.0~p3.3,这样可以使用8个i/o端口检测16个按键。
虽然矩阵键盘充分利用了i/o端口资源,但增加了检测程序的复杂性。因为独立按键有一端固定为低电平,编写单片机键盘检测程序比较方便,而矩阵键盘两端都与i/o端口相连,因此检测程序需要向i/o端口人为送出低电平。具体检测方法:先送一行低电平,其余各行为高电平,现在已经确定了行数(送入低电平的行),然后循环检测与该行相交的各列是否有低电平,若检测到某列有低电平,说明与该行相交的某列按键被按下,即确定了当前按下的按键属于哪一行哪一列。同理,使用同样的方法轮流送各行一次低电平,再轮流检测各列是否有低电平,即可完成所有按键的检测。当然也可以先送各列为低电平,然后再循环检测各行是否有低电平。
矩阵键盘应用案例:应用16个独立按键构成4行4列的矩阵键盘,行线接p3.0 ~ p3.3,列线接p3.4~p3.7。按键排列顺序为:1行1列为第1个按键,1行2列为第2个按键,……,2行1列为第5个按键,2行2列为第6个按键,……,4行4列为第16个按键。要求用户按下按键1后,数码管显示数字1,按下按键2后,数码管显示数字2,……,依次显示3,4,5,6,7,8,9,a,b,c,d,e,f。
下图是矩阵键盘案例电路设计图:
数码管采用7seg-mpx1-ca,为共阳极数码管,独立按键采用spst push button,请同学们参考上图使用proteus绘制电路设计图。
单片机内运行的完整c程序如下:
#include#includeunsigned char led[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x8,0x3,0xc6,0x21,0x6,0xe};unsigned char key[] = {0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};unsigned char rowscan[] = {0xfe,0xfd,0xfb,0xf7};void delay(unsigned int millisecond){ unsigned int i,j; for(i=millisecond;i >0;i--) for(j=120;j >0;j--);}void show_keyvalue(int keynum){ p0 = led[keynum]; delay(100);}void marix_keyscan(){ unsigned int i,j; unsigned char temp; for( i = 0; i< 4; i++ ) { p3 = rowscan[i]; temp = p3; temp = temp & 0xf0; if( temp != 0xf0 ) { delay(10); temp = p3; temp = temp & 0xf0; if( temp != 0xf0 ) { temp = p3; for( j = 0; j < 16; j++ ) { if( temp == key[j] ) break; } while(temp != 0xf0) { temp = p3; temp = temp & 0xf0; } show_keyvalue(j); } } }}void main(void){ while(1) { marix_keyscan(); } }程序设计思路:
按矩阵键盘的行线和列线顺序对16个按键进行编码,编码值是矩阵键盘某按键被按下后p3端口的值。例如:行1列1按键被按下后,p3端口的值为0xee,行2列1按键被按下后,p3端口的值为0xed。对所有按键进行编码后,可以通过p3端口的值来确定哪个按键被按下。
扫描矩阵键盘需要对4条行线循环送出低电平,然后再判断列线是否有低电平。在电路设计中矩阵键盘的4条行线接p3口的低4位p3.0 ~ p3.3,因此在行线循环中为p3口赋不同的值,即可完成对4条行线循环送出低电平的操作,1~4条行线送入低电平p3口的值分别为0xfe、0xfd、0xfb、0xf7。
矩阵键盘扫描程序需要一个循环结构,循环次数为矩阵键盘的行线数量,在循环体内依次为4条行线送入低电平,然后读取p3口的值,将p3口与0xf0进行与运算,若运算结果不为0xf0,说明有按键被按下(有列线为低电平),延迟10ms后再次检测有按键是否被按下,若确认有按键被按下,使用for循环遍历已定义16个按键编码值的数组,定位被按下按键的索引,最后调用数码管显示函数将按键索引对应的字符显示出来。
代码说明:
数组led[]定义了数码管显示的字符编码值,数组长度为16。数组key[]定义了16个按键的编码值,数组长度为16。数组rowscan[]定义了4条行线送入低电平p3口的值,数组长度为4。
delay()函数为时间延迟函数,show_keyvalue()为数码管显示字符的函数,参数keynum为字符led数组元素的索引,该索引与key数组元素的索引对应。marix_keyscan()为矩阵键盘扫描函数,用于检测按键是否被按下。
Type-C接口与传统安卓接口相比哪个性能好
废旧铅酸蓄电池无损修复技术解析
华为Mate9热度还未减,搭载麒麟970的华为Mate10就来了!
WiFi已连接但无法访问互联网是出现是问题?应该如何解决
华为做了什么让传统FPGA开发被颠覆
基于单片机的矩阵键盘检测案例
预约量破10万台 保千里打令V10S获用户关注
Intel的独显将对独立显卡市场造成什么影响
Style2paints V4版本来了!这是目前最好的线稿上色AI工具
贸泽电子开售用于汽车信息娱乐系统等用途的Molex Easy-On FFC/FPC One-Touch连接器
电子产业向更智能化系统转型_两个方面详细解析
微星MEGX399CREATION创世板评测 供电方面简直就是地表最强
指纹密码锁安全性能高低,怎么区分?
什么是上位机_上位机软件介绍
多用户电表的作用和用途
SNR G106.3+2.7成为银河系候选的“拍电子伏特宇宙线加速器”
行业 | 英特尔已经计划出售基带芯片业务,但苹果已放弃?
乐华车间工位机数字化工厂的应用
Maxim最新Go-IO平台将智能化推向数字工厂前沿
使用单片机实现一键多功能按键识别的设计实验说明