【单片机】STM32单片机的矩阵键盘驱动,标准库,无阻塞方式的矩阵键盘读取

原理图:
在这里插入图片描述

从左到右、从上到下,按键是1到16,没有按键返回0:
key.c

#include "key.h"/* 按键初始化函数 */
void KEY_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                          /* 使能时钟 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;       /* key */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;                                                        /* 设置成上拉输入 */GPIO_Init(GPIOB, &GPIO_InitStructure);                                                                /* 初始化GPIO */GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;                 //LED2-->PC13 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;         //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化PC13}#define OUT1 PBout(8)
#define OUT2 PBout(9)
#define OUT3 PBout(10)
#define OUT4 PBout(11)#define IN1  PBin(12)
#define IN2  PBin(13)
#define IN3  PBin(14)
#define IN4  PBin(15)u8 read_key(void) {OUT1 = 0, OUT2 = 1, OUT3 = 1, OUT4 = 1;if (IN1 == 0) {//while (IN1 == 0);return (1);} else if (IN2 == 0) {//while (IN2 == 0);return (5);} else if (IN3 == 0) {//while (IN3 == 0);return (9);} else if (IN4 == 0) {//while (IN4 == 0);return (13);}OUT1 = 1, OUT2 = 0, OUT3 = 1, OUT4 = 1;if (IN1 == 0) {//while (IN1 == 0);return (2);} else if (IN2 == 0) {//while (IN2 == 0);return (6);} else if (IN3 == 0) {//while (IN3 == 0);return (10);} else if (IN4 == 0) {//while (IN4 == 0);return (14);}OUT1 = 1, OUT2 = 1, OUT3 = 0, OUT4 = 1;if (IN1 == 0) {//while (IN1 == 0);return (3);} else if (IN2 == 0) {//while (IN2 == 0);return (7);} else if (IN3 == 0) {//while (IN3 == 0);return (11);} else if (IN4 == 0) {//while (IN4 == 0);return (15);}OUT1 = 1, OUT2 = 1, OUT3 = 1, OUT4 = 0;if (IN1 == 0) {//while (IN1 == 0);return (4);} else if (IN2 == 0) {//while (IN2 == 0);return (8);} else if (IN3 == 0) {//while (IN3 == 0);return (12);} else if (IN4 == 0) {//while (IN4 == 0);return (16);}return (0); /* 无按键按下 */
}//非阻塞型读矩阵键盘按键值
u8 read_key_2(u8 mode) {static u8 key_up = 1; //按键按松开标志if (mode)key_up = 1;  //支持连按if (key_up && (read_key() != 0)) {delay_ms(10); //去抖动key_up = 0;return (read_key());} else if (read_key() == 0)key_up = 1;return 0;
}

key.h

#ifndef __KEY_H
#define __KEY_H	 
#include "sys.h"void KEY_Init(void);//IO初始化u8 read_key(void);  	//按键扫描函数					   
u8 read_key_2(u8 mode);#endif

main.c调用示例:

void main(void)
{while (1) {delay_ms(5);t++;if (t > 50) {t = 0;LED0=!LED0;}key=read_key_2(0);if(key){process_key(key);dis_cnt=0;display_str[dis_cnt++]=key/10+'0';display_str[dis_cnt++]=key%10+'0';display_str[dis_cnt++]=0;OLED_P8x16Str(0,2,display_str,0);//正常显示}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eclipse中的实用工具之JUnit

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于JUnit的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 是什么 为什么要用 怎么用 是什么 JUnit…

UE4/5动画系列(4.足部ik制作)

目录 前期准备 添加虚拟骨骼 ​编辑 腿部函数: 前肢: ​编辑 盆骨函数: 后肢: 进入动画图表: 前期准备 首先准备一个后期处理动画蓝图 然后【因为笔者之前的大象因为不知明原因崩溃,这里就不展示如何…

PostgreSQL中HOT对cluster的作用

PG中cluster的作用是根据表的索引重新构建一张表,并且表根据该索引进行排序,索引必须提前建好。 注意:cluster操作加ACCESS EXCLUSIVE锁,会阻塞其它任何操作。 我们为什么要运行cluster? PG中的表是堆表,表中行的顺…

青少年机器人技术一级核心知识点:机械结构及模型(四)

随着科技的不断进步,机器人技术已经成为了一个重要的领域。在这个领域中,机械结构是机器人设计中至关重要的一部分,它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说,了解机械结构的基础知识,掌…

简述环保用电监管云平台

1、概述 推进打赢蓝天保卫战,打好碧水保卫战,打胜净土保卫战,加快生态环境保护、建设美丽中国,各省市结合物联网和大数据政策,也相继颁布有关污染治理设施用电监管平台等相关政策。针对企业内的环保设施、设备运行状况…

GitHub下载破千万!这份Java大厂面试指南,竟是阿里面试官上传的

前言 本以为在大厂可以逃过35岁的坎儿,结果还没到35就遇上了大裁员。。。被裁的那一个月,我拿着公司给的2N在家躺了大半个月,刚开始是不甘,到后面每个月一万多的房贷催着我不得不重新审视自己,随后踏上了海投之路。 …

【Spring Cloud系列】-Eureka服务端高可用详解

【Spring Cloud系列】-Eureka服务端高可用详解 文章目录 【Spring Cloud系列】-Eureka服务端高可用详解一. 序言二. 什么是高可用性三. 什么是CAP一致性(Consistency)可用性(Availability)分区容错(Partition-toleranc…

Kubernetes-Ingress、Ingress Controller、Ingress Class

概念 1.Ingress 是对K8S集群中服务的外部访问进行管理的 API 对象。Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。 2.Ingress Controller 通常负责通过负载均衡器来实现 Ingress。 3.必须拥有一个 Ingress Controller…

vue(typescript)项目在vs中打开出现的各种问题

目录 vue3 报错解决:找不到模块或其相应的类型声明。(Vue 3 can not find module) (TS) 未知的编译器选项“allowImportingTsExtensions”。 TS6046 (TS) “--moduleResolution”选项的参数必须为 node, classic, node16, nodenext。…

使用 Sigstore 签名的 Elastic Stack 容器镜像!

作者:Maxime Greau 软件供应链攻击不断增加。 这就是为什么这个主题是安全领导者的首要任务。 在这方面,这篇博文重点介绍了使用 Sigstore 对 Elastic Stack 容器镜像进行签名的新功能,以便: 保护 Elastic 软件供应链工作流程为…

6月份读书学习好文记录

看看CHATGPT在最近几个月的发展趋势 https://blog.csdn.net/csdnnews/article/details/130878125?spm1000.2115.3001.5927 这是属于 AI 开发者的好时代,有什么理由不多去做一些尝试呢。 北大教授陈钟谈 AI 未来:逼近 AGI、融进元宇宙,开源…

Nginx(4)nginx的反向代理

反向代理 正向代理反向代理的常用指令反向代理实战 Nginx的安全控制使用SSL对流量进行加密nginx添加SSL的支持Nginx的SSL相关指令生成证书 反向代理系统调优 正向代理代理的对象是客户端,反向代理代理的是服务端,这是两者之间最大的区别。Nginx即可以实现…