stm32f103c8t6之4x4矩阵按键

基于普中精灵开发板
1、矩阵按键原理

当我们需要使用较多的按键时,单片机的IO口可能不够用,这是就需要使用矩阵按键。

对应IO口如下:

 步骤解析:

1、全部按键都没有按下时,全行IO为低电平(全列对应的IO设置为下拉低电平)。
2、第一行IO口全为高电平,检测对应列的IO口电平,2、3、4行对应IO为电平。
3、第二行IO口全为高电平,检测对应列的IO口电平,1、3、4行对应IO为电平。
4、第三行IO口全为高电平,检测对应列的IO口电平,1、2、4行对应IO为电平。
5、第四行IO口全为高电平,检测对应列的IO口电平,1、2、3行对应IO为电平。

 ---------------------------------------------------------******----------------------------------------------------------------

一、第一行IO口全为高电平,检测对应列的IO口电平,2、3、4行对应的IO为低电平,那么只需要读取列对应的4个IO口电平,就可以判断是第一行第几个按键按下。因为按下时按键连通,则对应的按键的列引脚电平就为高电平(列对应的io为电平)。

注意:行对应的引脚为推挽输出,列对应的引脚为下拉(默认低电平0)

 例如,当第一行第一个按键按下时,KEY_L1对应的IO电平将从0变为1,如下图所示。

 二、第二行IO口全为高电平,检测对应列的IO口电平,1、3、4行对应IO为电平。同样的思路进行编程

三、 按键扫描函数:
u8 KEY_Matrix_Scan(void)
{
    u8 col1,col2,col3,col4;//保存电平状态
	u8 key_value;//保存键值
	
	//1、没有检测到按键按下
	GPIO_SetBits(KEY_MATRIX_H1_PORT,KEY_MATRIX_H1_PIN);
	GPIO_SetBits(KEY_MATRIX_H2_PORT,KEY_MATRIX_H2_PIN);
	GPIO_SetBits(KEY_MATRIX_H3_PORT,KEY_MATRIX_H3_PIN);
	GPIO_SetBits(KEY_MATRIX_H4_PORT,KEY_MATRIX_H4_PIN);	
	//全部都没有按下,返回0
	if((GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN)|
		GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN)|
		GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN)|
	    GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN))==0)
	{
	    return 0;
	}
	//有按下,但没有检测到,同样返回0
	else
	{
	    delay_ms(5);//按键消抖
		if((GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN))==0)
		{
			return 0;
		}
	}
	
	//2、第一行检测
	GPIO_SetBits(KEY_MATRIX_H1_PORT,KEY_MATRIX_H1_PIN);
	GPIO_ResetBits(KEY_MATRIX_H2_PORT,KEY_MATRIX_H2_PIN);
	GPIO_ResetBits(KEY_MATRIX_H3_PORT,KEY_MATRIX_H3_PIN);
	GPIO_ResetBits(KEY_MATRIX_H4_PORT,KEY_MATRIX_H4_PIN);
	//记录电平
	col1=GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN);
	col2=GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN);
	col3=GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN);
	col4=GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN);
	if(col1==1&&col2==0&&col3==0&&col4==0)
	    key_value=1;//第一行第一个按键按下了
	if(col1==0&&col2==1&&col3==0&&col4==0)
	    key_value=2;//第一行第二个按键按下了
	if(col1==0&&col2==0&&col3==1&&col4==0)
	    key_value=3;//第一行第三个按键按下了
	if(col1==0&&col2==0&&col3==0&&col4==1)
	    key_value=4;//第一行第四个按键按下了
	//需判断按键是否松开,当某按键按下时值为1大于0为真,继续等待;当按键松开都没有按下时值为0>0为假,退出等待
	while((GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN))>0);
	
	//3、第二行检测
	GPIO_ResetBits(KEY_MATRIX_H1_PORT,KEY_MATRIX_H1_PIN);
	GPIO_SetBits(KEY_MATRIX_H2_PORT,KEY_MATRIX_H2_PIN);
	GPIO_ResetBits(KEY_MATRIX_H3_PORT,KEY_MATRIX_H3_PIN);
	GPIO_ResetBits(KEY_MATRIX_H4_PORT,KEY_MATRIX_H4_PIN);
	//记录电平
	col1=GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN);
	col2=GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN);
	col3=GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN);
	col4=GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN);
	if(col1==1&&col2==0&&col3==0&&col4==0)
	    key_value=5;//第二行第一个按键按下了
	if(col1==0&&col2==1&&col3==0&&col4==0)
	    key_value=6;//第二行第二个按键按下了
	if(col1==0&&col2==0&&col3==1&&col4==0)
	    key_value=7;//第二行第三个按键按下了
	if(col1==0&&col2==0&&col3==0&&col4==1)
	    key_value=8;//第二行第四个按键按下了
	//需判断按键是否松开,当某按键按下时值为1大于0为真,继续等待;当按键松开都没有按下时值为0>0为假,退出等待
	while((GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN))>0);
	
	//4、第三行检测
	GPIO_ResetBits(KEY_MATRIX_H1_PORT,KEY_MATRIX_H1_PIN);
	GPIO_ResetBits(KEY_MATRIX_H2_PORT,KEY_MATRIX_H2_PIN);
	GPIO_SetBits(KEY_MATRIX_H3_PORT,KEY_MATRIX_H3_PIN);
	GPIO_ResetBits(KEY_MATRIX_H4_PORT,KEY_MATRIX_H4_PIN);
	//记录电平
	col1=GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN);
	col2=GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN);
	col3=GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN);
	col4=GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN);
	if(col1==1&&col2==0&&col3==0&&col4==0)
	    key_value=9;//第三行第一个按键按下了
	if(col1==0&&col2==1&&col3==0&&col4==0)
	    key_value=10;//第三行第二个按键按下了
	if(col1==0&&col2==0&&col3==1&&col4==0)
	    key_value=11;//第三行第三个按键按下了
	if(col1==0&&col2==0&&col3==0&&col4==1)
	    key_value=12;//第三行第四个按键按下了
	//需判断按键是否松开,当某按键按下时值为1大于0为真,继续等待;当按键松开都没有按下时值为0>0为假,退出等待
	while((GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN))>0);
	
	//5、第四行检测
	GPIO_ResetBits(KEY_MATRIX_H1_PORT,KEY_MATRIX_H1_PIN);
	GPIO_ResetBits(KEY_MATRIX_H2_PORT,KEY_MATRIX_H2_PIN);
	GPIO_ResetBits(KEY_MATRIX_H3_PORT,KEY_MATRIX_H3_PIN);
	GPIO_SetBits(KEY_MATRIX_H4_PORT,KEY_MATRIX_H4_PIN);
	//记录电平
	col1=GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN);
	col2=GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN);
	col3=GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN);
	col4=GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN);
	if(col1==1&&col2==0&&col3==0&&col4==0)
	    key_value=13;//第四行第一个按键按下了
	if(col1==0&&col2==1&&col3==0&&col4==0)
	    key_value=14;//第四行第二个按键按下了
	if(col1==0&&col2==0&&col3==1&&col4==0)
	    key_value=15;//第四行第三个按键按下了
	if(col1==0&&col2==0&&col3==0&&col4==1)
	    key_value=16;//第四行第四个按键按下了
	//需判断按键是否松开,当某按键按下时值为1大于0为真,继续等待;当按键松开都没有按下时值为0>0为假,退出等待
	while( (GPIO_ReadInputDataBit(KEY_MATRIX_L1_PORT,KEY_MATRIX_L1_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L2_PORT,KEY_MATRIX_L2_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L3_PORT,KEY_MATRIX_L3_PIN)|
			GPIO_ReadInputDataBit(KEY_MATRIX_L4_PORT,KEY_MATRIX_L4_PIN))>0);
	
	return key_value;
}

实验结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/613932.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

maven mirrorOf的作用

在工作中遇到了一个问题导致依赖下载不了,最后发现是mirror的问题,决定好好去看一下mirror的配置,以及mirrorOf的作用,以前都是直接复制过来使用,看了之后才明白什么意思。 过程 如果你设置了镜像,镜像会匹…

基于Springboot+Vue的Java项目-车辆管理系统开发实战(附演示视频+源码+LW)

大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:Java毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计 &am…

网易云新玩法:教你赚取第一桶金!

在现今的音乐应用市场中,有几款软件备受广大用户的青睐。 其中,QQ音乐、酷狗音乐以及网易云音乐都是大家耳熟能详的名字。 这些平台不仅提供了丰富的音乐资源,还具备了许多便捷的功能,使得用户们能够享受到更为优质的音乐体验。…

Covalent Network(CQT)通过 “新曙光” 计划实现重要里程碑,增强以太坊时光机,提供 30% 的年化质押收益率

Covalent Network(CQT)作为集成超过 280 条区块链,并服务于超过 2.8 亿个钱包的领先结构化数据基础设施层,宣布了其战略计划 “新曙光” 中的一个重要进展。随着网络升级并完成了准备工作的 75%,这将为即将部署的以太坊…

Jsp+Servlet实现图片上传和点击放大预览功能(提供Gitee源码)

前言:在最近老项目的开发中,需要做一个图片上传和点击放大的功能,在Vue和SpringBoot框架都有现成封装好的组件和工具类,对于一些上世纪的项目就没这么方便了,所以需要自己用原生的代码去编写,这里分享一下我…

Nextcloud私有云盘-重新定义云存储体验

Nextcloud私有云盘-重新定义云存储体验 1. 什么是Nextcloud ​ Nextcloud是一个开源的云存储和协作平台,旨在为个人用户、企业和团队提供安全、隐私保护的数据存储和共享解决方案。它允许您在不同设备之间同步、共享文件,提供了强大的协作工具和应用生…

C++初阶之stack,queue,priority_queue的使用和模拟以及仿函数的创建和使用

个人主页:点我进入主页 专栏分类:C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂 目录 一.stack,queue,priority_queue简介以及代码模拟 1.1 stack …

Java | Leetcode Java题解之第74题搜索二维矩阵

题目&#xff1a; 题解&#xff1a; class Solution {public boolean searchMatrix(int[][] matrix, int target) {int m matrix.length, n matrix[0].length;int low 0, high m * n - 1;while (low < high) {int mid (high - low) / 2 low;int x matrix[mid / n][m…

激光雷达在工厂散料体积测量中的经济效益分析

随着市场竞争的加剧&#xff0c;企业对于成本控制和效率提升的需求越来越迫切。激光雷达作为一种高效、准确的测量工具&#xff0c;在工厂散料体积测量中发挥着重要作用。本文将对激光雷达在工厂散料体积测量中的经济效益进行分析。 一、减少人工成本 传统的散料体积测量方法…

人工智能_大模型049_模型微调009_llama2模型训练_代码分析和实现_代码记录---人工智能工作笔记0184

以上是项目的整体结构,其中上一节我们看了chatglm3目录下,对chatglm3模型的训练部分的代码,然后 这里的llama2目录下是对llama2模型进行训练的代码. 然后web_demo目录是,对web浏览器中,使用chatglm3,以及llama2.py进行的封装下一节我们再看这个部分 E:\2024\人工智能\fine-tun…

Stable Diffusion写真完整教程

前言 最近自己对AI非常痴迷&#xff0c;并且今后也会一直在这个领域深耕&#xff0c;所以就想着先入门&#xff0c;因此花时间研究了一番&#xff0c;还好&#xff0c;出了点小成果&#xff0c;接下来给大家汇报一下。 AI绘画 提到AI绘画&#xff0c;大家可能立马会想到made…

JMeter 如何应用于 WebSocket 接口测试

WebSocket: 实时双向通信的探索及利用 JMeter 进行应用性能测试 WebSocket 是一项使客户端与服务器之间可以进行双向通信的技术&#xff0c;适用于需要实时数据交换的应用。为了衡量和改进其性能&#xff0c;可以通过工具如 JMeter 进行测试&#xff0c;但需要先对其进行适配以…

光栅测长机高精度检定量规量具

在制造业中&#xff0c;量规、量具等精密测量工具的准确性直接影响着产品质量和制造效率。为了确保这些测量工具的精准度&#xff0c;光栅测长机应运而生&#xff0c;成为了检定量规量具的利器。 光栅测长机是一种高精度的长度测量设备&#xff0c;它是利用光栅的精密刻度和光…

微信小程序之简单的发送弹幕操作

大家看视频的时候是不是时不时会有弹幕飘过~ 在我们微信小程序当中&#xff0c;我们可以十分简单的实现&#xff0c;接下来为大家介绍一下吧&#xff01; 我们使用微信官方给我们的一个视频链接 "http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey302802…

关于docker network网络

首先,我们来看看Docker默认的网络模式,即docker0网桥。 每当你安装Docker时,它会创建一个名为docker0的虚拟网桥,并设置一个IP地址范围供它进行端口映射等工作。所有Docker容器在创建时,都会自动连接到这个docker0网桥,并分配一个虚拟IP地址。这样,容器与主机之间,以及容器与容…

微信小程序开发【Coffee Shopping】(1)

1.环境准备 微信开发者工具&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html 前端常用网站集合&#xff1a;http://www.wwp666.cn/ 微信小程序开发文档&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/framework/quicksta…

docker部署minio和业务服务因变更minio密码导致访问不到图片的问题

问题起因 业务application和minio都是docker部署。按部署规则minio的环境变量中设置了MINIO_ROOT_USER和MINIO_ROOT_PASSWORD。这样就可以用这套用户名密码登录minio了。而我的application中是通过api访问minio获取资源URL&#xff0c;提供给前端的。所以在application的环境变…

Excel实用技巧持续学习

1、Excel高效设置图标格式&#xff1a; 2、饼图可以统一设置数据标签在图外面&#xff01;&#xff01; 环形图不可以&#xff0c;但是可以中间手动加上白色圆形&#xff0c;将饼图变为圆环。 可以设置标签的文本显示&#xff1a; 3、饼图和环形图最好进行排序&#xff01;显得…

【Qt 学习笔记】Qt常用控件 | 多元素控件 | Tree Widget的说明及介绍

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;Qt 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ Qt常用控件 | 多元素控件 | Tree Widget的说明及介绍 文章编号&#x…

stable diffusion WebUi本地安装

一、stable diffusion 介绍 Stable Diffusion是一种先进的文本到图像的生成模型&#xff0c;它可以根据给定的文本输入生成高度逼真的图像。 Stable Diffusion模型因其高效性和灵活性&#xff0c;在AI图像生成领域引起了广泛关注&#xff0c;并在实际应用中展示了其强大的能力…