目录
矩阵键盘就是开发板上右下角的这个模块
这一节的代码是基于上一节讲的LCD1602液晶显示屏驱动代码进行的
矩阵键盘的介绍
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式
采用逐行或逐列的"扫描",就可以读出任何位置按键的状态。
数码管扫描(输出扫描)
原理:显示第1位→显示第2位→显示第3位→......,然后快速循环这个过程,最终实现所有数码管同时显示的效果
矩阵键盘扫描(输入扫描)
原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ......,然后快速循环这个过程,最终实现所有按键同时检测的效果
以上两种扫描方式的共性:节省I/O口
独立按键和矩阵按键的相同之处:
独立按键是把按键公共的一端直接接地(低电平0),另一端接在IO口上
然后我们发现矩阵键盘和独立按键有个相似的地方就是如果只看一种一行,将这一整行接地的话,只看这一行两节IO口时,和独立按键的连接方式其实是一样的。
所以矩阵按键可以说是独立按键的复杂版,而独立按键是简单化的版本。
矩阵按键的扫描
比如想要判断第二行,那P16就给0,其他的给1
然后如果P13给0,就是S5按下了,如果P12给0,就是S6按下了,如果P11给0,就是S7按下了,如果P10给0,就是S6按下了。
其实这个和数码管的操作原理差不多,可以理解为上面4个引脚为使能,下面四个为读取,也可以说上面四个是位选,后四个事段选。
同理,如果想要判断第三行,和第四行,那就是P15和P14分别给0
就是这样一行一行读下来,就相当于把键盘扫描一遍。
要注意的一点是,这个P15口会连接到步进电机上,它相当于驱动器(增大输出电流能力的)
然后BZ就连接到蜂鸣器上
我们这个开发板上的蜂鸣器是无源蜂鸣器,所以这个BZ口以一定的频率高低变化,蜂鸣器就会响。
所以我们逐行扫描矩阵按键出现的问题就是蜂鸣器会自己响,并且关不掉,是引脚冲突造成的。
为了避免这个问题,我们可以采用逐列扫描。
怎么逐列扫描呢?
就是反过来,给下面四个IO口赋值,然后读取上面四个IO口
比如我们要判断第一行,就给P13口0,然后其余给1,然后如果P17口给0,就是S1按下了,如果P16给0,就是S5按下了,如果P15给0,就是S9按下了,如果P14给0,就是S13按下了。同理,其他列是一样的方式。
代码演示
接下来开始代码演示:
新建一个工程,写上框架
代码模块化移植
本节用到的所有程序源码文件可以到评论区自取!
我们把上一节用到的四个文件拷贝过来放进这节的工程文件夹中
这个过程就叫做模块化移植
然后我们把这四个文件添加进来
这样我们就可以引用这几个模块化的程序了。
然后我们需要再创建一个矩阵按键的.c和.h文件
这个时候发现只出现了MatrixKey的.c文件,.h文件我们要自己再添加
这样就能看到它的.h文件了
然后双击MatrixKey.h文件,写上防止重复定义的程序
如果嫌每次都写#ifndef这个框架很麻烦的话,可以把它做成一个templates模板
Keil自定义模板步骤:
左栏点击函数模板
可以看到一些已经被定义好的模板,我们也可以自己添加一个
点击右键-构建模板
点击新建模板
填写模板名称
填写模板内容
点击OK
这样就可以使用了
试一下,双击模板名称
框架就自动出来了!
把它补充完整:
.h文件的框架写好之后,可以写.c文件了
代码编写
根据原理图,我们在MatrixKey.c文件上编写一个程序扫描矩阵按键上的每一个按键,实现的效果是:当我们按下某个按键的时候,屏幕上就给我们提示所按下的按键的编号
写好之后在MatrixKey.h文件里面声明一下
然后我们在main.c上调用一下这些函数
编译无错误后看看效果:
按下S2键后松手后,的确是在第2行,第1列显示按键序号02
按下S3键后松手后,的确是在第2行,第1列显示按键序号03
我们可以添加这样一行代码,显示"MatrixKey:"
这样就可以自动在第一行显示"MatrixKey:"提示的按键序号在第二行显示
以上就是本节要实现的效果。
本节用到的所有程序源码文件可以到评论区自取!