
这个矩阵按键也是我们这个开发版上最后一个GPIO的一个应用,如果对1O回的输入跟输出还有什么问题的话, 一定要回过头去看一下我们之前的程序理清楚思路。 之前的按键电路图:
1个按键占用一个IO口的。 在按键数量较多时,为了减少I/O口的占用,将按键排列成矩阵排列的形式的按键阵列我们称位矩阵按键。
电路图:
按键识别原理:端口默认为高电平,实时读取到引脚为低电平是表示按下。再次读取到高电平,表示松开。
第一步:现将P0.0-P0.3输出低电平,P0.6-P0.7输出高电平,如果有按键按下,按下的那一列的IO就会变成低电平,就可以判断出哪一列按下了。
第二步:现将P0.0-P0.3输出高电平,P0.6-P0.7输出低电平,如果有按键按下,按下的那一行的IO就会变成低电平,就可以判断出哪一行按下了。
第三步:行列组合一下就可以判断出是哪个按键按下了。
按键按下后导线导通,哪条线上有高电平,就会被拉低为低电平,从而检测出是哪条线路,二次检查,交叉节点就是有按键按下的按键位置。
先完成矩阵按键的功能编写。 复制9.TIM多任务为10.矩阵按键,用到P0端口,还是在之前的KEY模块基础上进行修改: 在key.h中定义:#define MateixKEY P0 //矩阵按键的引脚 定义函数MateixKEY_Read: u8 MateixKEY_Read(void); //矩阵按键读取当前是哪一个按钮按下,返回值是按键序号 在key.c中实现函数MateixKEY_Read: 先增加函数头,并把实现思路复制过来作为编写依据,围绕这三步,编写矩阵按键的读取程序: MateixKEY = 0XC0; //1100 0000 P0.6-P0.7输出高电平,
增加延时函数MateixKEY_delay留反应时间: MateixKEY_delay(); //留反应时间 MateixKEY_delay的实现,并添加函数头:
第一步:假设P0.7按下, 则为0100 0000,如果想实现哪路按下哪位变成1,可以采用异或运算。 即:0100 0000 ^1100 0000 = 1000 0000 则有:keystate = MateixKEY^0XC0;
第二步:第二次扫描,高位输出低电平,低位输出高电平:MateixKEY = 0X0f; //0000 1111 保存按键状态,假设P0.0按下, 则为0000 1110^0000 1111 = 0000 0001,这里要采用|=,0000 0001 | 1000 0000 = 1000 0001 = 0x81
keystate |= (MateixKEY^0X0f);是为了避免把之前的数值覆盖。 第三步:keystate中已经保存了行、列的状态,行列组合一下就可以判断出是哪个按键按下了。 printf("%02x\r\n",keystate); //强制变为2位,以16进制显示。 return keystate; 在demo.c中调用: 将10ms扫描按键的代码部分注释掉,只检测MateixKEY_Read,加入该函数,编译,运行。按动按键,串口打印对应的16进制数值。
u8 key_val = 0; //表示按键的键码 这里采用switch关键词,直接有模板插入,编写switch函数:
关闭数码管初始化显示,main函数中新建变量:u8 KEY_NUM = 0; //保存矩阵按键的键码 读取矩阵按键的键码保存在KEY_NUM中,并在数码管最后1位显示:
编译下载,按动按键就可以判断是哪个按键按下了。
由于KEY_NUM = MateixKEY_Read();执行后,会持续输出1,需要修改,3s内只输出1次即可,让它符合今天的主题。 先定义一个静态变量,这是一个很常见的用法,static u8 keystate_Last; //表示当前的按钮上一次的状态值 增加判断条件:
1.通过LED0模拟门锁状态,LED点亮表示门锁打开,熄灭表示门锁锁上; 增加横线显示值,SEG_Tab[22]= 默认显示横线:u8 Show_Tab[8] = {21,21,21,21,21,21,21,21}; 新增变量:u8 KEY_Str = 0; //表示当前输入了几个密码 2.增加8位数码管,可以动态显示8位的密码,无密码时显示 “- - - - - - - -”; 3.通过矩阵按键可以输入1-8的数字表示密码,并依次显示在数码管上; 4.每输入一个数字,蜂鸣器响20ms表示有数字按下; 5.密码正确打开LED0,密码错误蜂鸣响2秒; 根据条件,修改demo.c中的main函数代码如下:
编译下载,发现按键后均显示0:KEY_NUM = 0;位置有误,应该放在调用以后再置0. 重新测试,8位输入后不能自动清空,应该添加代码,到达长度后回到初始值显示横杠:SEG0 = SEG1 = SEG2 = SEG3 = SEG4 = SEG5 = SEG6 = SEG7 = 21; 重新测试,输入错误后,复位,再按键输入,显示有问题:KEY_Str ==8后忘记归0了。 经过修改,功能已正常实现。
完整代码请参考:《STC单片机原理-教学视频配套附件-20230731.zip
1.了解矩阵按键的工作原理和代码编写的过程
给今天的门锁增加如下功能:
1.LED0(门锁)打开后,5秒后自动关闭;
2.增加门内的手动开门按钮,按下按钮门锁打开;
3.10秒内没有输入密码自动数码管熄灭省电;有按键按下时再显示。
4.用for去改写一下密码判断的地方。
