蓝桥杯STM32G431RBT6学习——按键

news2024/11/26 20:47:23

蓝桥杯STM32G431RBT6学习——按键

前言

按键同样为每年的必考考点,国信长天开发板中的按键电路如下:
在这里插入图片描述
芯片的PA0、PB0、PB1、PB2作为按键输入引脚,并采用外部上拉连接,当对应引脚检测到低电平时,即按键被按下。

STM32CubeMX配置

时钟配置不变,将以上引脚配置为输入模式,并设置其上拉模式。
在这里插入图片描述

Keil代码编写

关于按键的常用API如下:
读取IO口电平

GPIO_PinState     HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);

参数1:IO口所在组;
参数2:IO口引脚号

整体控制
关于按键的使用,主要使用的方式有单击、长按,众所周知硬件按键按下时都会产生一定的抖动,因此需要延时消抖处理。为了程序重复执行,可以在代码算法上将其分为两个状态进行判断,即按键按下与按键松开。
(1)单击
对于单击而言,只需要区分一次按键按下松开即可,在程序中设置一个标志位用于判断按键的状态(初始化为0),当按键按下时,判断读取电平是否为低电平,同时标志位需要为0,方才认为按键按下,并将标志位置1;当按键松开时,判断读取电平为高电平,同时标志位需要为1(曾经按下过),方才认为按键松开了,并将标志位置0。
代码如下:

/****************
函数功能:按键单击读取函数
函数参数:无
函数返回值:按下的按键键值,KeyB1~KeyB4->a~d
****************/
uchar key_Scan(void)
{
	static uchar K1_flag,K2_flag,K3_flag,K4_flag;
	
	if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
	{
		HAL_Delay(5);
		if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
		{
			K1_flag = 1;
			return 'a';	
		}
	}
	else if(KeyB1 == GPIO_PIN_SET && K1_flag == 1)
		K1_flag = 0;
		
	if(KeyB2 == GPIO_PIN_RESET && K2_flag == 0)
	{
		HAL_Delay(5);
		if(KeyB2 == GPIO_PIN_RESET && K2_flag == 0)
		{
			K2_flag = 1;
			return 'b';
		}
	}
	else if(KeyB2 == GPIO_PIN_SET && K2_flag == 1)
		K2_flag = 0;
		
	if(KeyB3 == GPIO_PIN_RESET && K3_flag == 0)
	{
		HAL_Delay(5);
		if(KeyB3 == GPIO_PIN_RESET && K3_flag == 0)
		{
			K3_flag = 1;
			return 'c';
		}
	}
	else if(KeyB3 == GPIO_PIN_SET && K3_flag == 1)
		K3_flag = 0;
	
	if(KeyB4 == GPIO_PIN_RESET && K4_flag == 0) 
	{
		HAL_Delay(5);
		if(KeyB4 == GPIO_PIN_RESET && K4_flag == 0) 
		{
			K4_flag = 1;
			return 'd';
		}
	}
	else if(KeyB4 == GPIO_PIN_SET && K4_flag == 1)
		K4_flag = 0;
	return 0;
}

通过读取函数返回值即可判断按键是否按下。
(2)长按
对于长按而言,字面意思就是按下按键达到一段时间后才会触发按键的功能,因此毫无疑问最简单粗暴的方法就是当按键按下时用延时进行阻塞,一段时间后再检测按键是否还是按下即可分辨是否属于长按。
代码如下:

	if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
	{
		HAL_Delay(5);
		if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
		{
			HAL_Delay(500);
			if(KeyB1 == GPIO_PIN_RESET && K1_flag == 0)
			{
				K1_flag = 1;
				return 'a';		
			}
		}
	}

但是这种方法存在弊端:1、严重影响系统运行,一般长按的时间都较长(500ms以上),对于单片机而言如此长的时间不干活是严重的资源浪费;2、难以实现多种按键并存,当一个按键既需要长按又需要短按的时候,这种方法就会很尴尬。
解决方法:后续使用定时器进行辅助按键功能的实现。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2293. 极大极小游戏】

来源:力扣(LeetCode) 描述: 给你一个下标从 0 开始的整数数组 nums ,其长度是 2 的幂。 对 nums 执行下述算法: 设 n 等于 nums 的长度,如果 n 1 ,终止 算法过程。否则&#xf…

【自学Docker】Docker环境命令

Docker info命令 Docker info命令概述 用于查看 docker 容器的基本信息。 Docker info命令语法 haicoder(www.haicoder.net)# docker info案例 查看所有信息 使用 docker info 命令,查看当前 docker容器 的所有的信息。 haicoder(www.haicoder.net)# docker …

系分 - 案例分析 - 数据库设计(分布式)

个人总结,仅供参考,欢迎加好友一起讨论 文章目录系分 - 案例分析 - 数据库设计(分布式)分布式数据库系统透明性分类两阶段提交协议2PC分区分表分库分区技术数据库主从复制NoSQL非关系型数据库与关系型数据库对比类型缓存技术Redis…

git恢复误删除的代码模块

git恢复误删除的代码模块前言环境问题描述原先的仓库详情:最新的仓库详情:问题解决注意事项前言 寒假回家边聊天边进行代码上传,出现了冲突之后,不小心删除了一大片代码。这里记录一下解决方案。 环境 IDEA、Git 问题描述 代…

Cesium实战记录(八)三维风场+风速热力图(水平+垂直)

目录 老规矩首先看下效果 一、风场 1、数据 2、原理剖析 首先,第一步就是构造网格数据 然后,撒粒子 再然后,起风吧 二、热力场 老规矩首先看下效果 风场v1.0(平面版,只有U V 方向风速) 三维风场&am…

JS逆向之补环境过瑞数详解

JS逆向之补环境过瑞数详解 “瑞数” 是逆向路上的一座大山,是许多JS逆向者绕不开的一堵围墙,也是跳槽简历上的一个亮点,我们必须得在下次跳槽前攻克它!! 好在现在网上有很多讲解瑞数相关的文章,贴心的一步…

英伟达Flex-unity插件

好像有这么个库,可以用来流体仿真 官网是这个:NVIDIA FleX | NVIDIA 开发者 问题 但是现在好像没了: NVIDIA FleX for Unity (1.0 BETA) | 物理 | Unity Asset Store 百度 Unity 8.Oct.2021 Unfortunately, NVIDIA FleX for Unity (1.0 …

完美Crack:Froala Editor 4.0.16 Patch

基于 Web 的 JavaScript/HTML WYSIWYG 文本编辑器。 Froala Editor 是一个用 JavaScript 编写的轻量级 WYSIWYG HTML 编辑器,可为您的应用程序启用富文本编辑功能。使用简单,许多功能不必用数百个按钮让用户不知所措。编辑器的智能工具栏可以在一个简单的…

ESP-IDF:基于企业链表实现的循环链表实例,实现了初始,插入,循环打印的功能

例程: /* circle链表基于企业链表*/ // 链表节点 typedef struct CIRCLENODE { CIRCLENODE *next; } circleNode; typedef struct CIRCLELIST { circleNode head; int size; } circleList; circleList *Inital_CircleList() { circleList *cp (circleList *)mal…

LeakCanary简要原理

首先需要知道ReferenceQueue&#xff08;引用队列&#xff09;&#xff1a;public static void main(String[] args) {Activity activity new Activity(); // 模拟ActivityReferenceQueue<Activity> queue new ReferenceQueue<>(); // 引用队列WeakReference<…

从汇编的角度了解C++原理——new和malloc的区别

文章目录1、new和malloc的区别1.1、例程1.2、总结本文用到的反汇编工具是objconv&#xff0c;使用方法可以看我另一篇文章https://blog.csdn.net/weixin_45001971/article/details/128660642。 其它文章&#xff1a; 从汇编的角度了解C原理——类的储存结构和函数调用 从汇编的…

【索引】引用A survey on pickup and delivery problems的文章

1. Dynamic container drayage with uncertain request arrival times and service time windows⭐️ 具有不确定请求到达时间和服务时间窗口的动态集装箱运输 Container drayage plays a critical role in intermodal global container transportation, as it accomplishes th…

hud 1846巴什博弈(简单的解法 或 Sprague-Grundy解法)

各位勇敢者要玩的第一个游戏是什么呢&#xff1f;很简单&#xff0c;它是这样定义的&#xff1a; 1、 本游戏是一个二人游戏; 2、 有一堆石子一共有n个&#xff1b; 3、 两人轮流进行; 4、 每走一步可以取走1…m个石子&#xff1b; 5、 最先取光石子的一方为胜&#xff1b; 如…

不懂Token,就是别说自己是中级测试工程师

官方回答&#xff1a; Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证&#xff0c;服务端认证成功&#xff0c;那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。 基于工程师的理解&#xff1a; token就相当于客户…

Go语言初始

"当我回头&#xff0c;妄想找到幸福的线索&#xff0c;那束光拉长我的影子&#xff0c;逃离我。"一、Go简介Go&#xff08;又称 Golang&#xff09;是 Google 的 Robert Griesemer&#xff0c;Rob Pike 及 Ken Thompson 开发的一种静态强乐西、编译型语言。Go 语言语…

Unicorn反混淆:恢复被OLLVM保护的程序(一)

一、目标 现在很多程序利用ollvm的控制流平坦化来增加逆向分析的难度。 控制流平坦化 (control flow flattening)的基本思想主要是通过一个主分发器来控制程序基本块的执行流程&#xff0c;例如下图是正常的执行流程 1:show1 经过控制流平坦化后的执行流程就如下图: 1:show2 …

RT-Thread系列--启动过程

一、目的RT-Thread是一个小而美的RTOS&#xff0c;所有的RTOS的都有一个特点&#xff0c;那就是存在调度器&#xff0c;像RT-Thread的调度器是一个实时抢占式调度器&#xff08;同优先级任务使用时间片调度方式&#xff09;。本篇不讲调度器相关的内容&#xff0c;着重讲解调度…

【博客591】LVS的DR和NAT模式下要注意的缺陷

LVS的DR和NAT模式下要注意的缺陷 1、DR模式和NAT模式的转发原理 2、LVS的DR和NAT模式下要注意的缺陷 缺陷1&#xff1a;DR模式下的realserver和 lvs的vip提供服务的端口必须一致。 例如vip的端口对外端口为 80&#xff0c;但后端服务的真实端口为8080&#xff0c;通过lvs的D…

SpringBoot快速上手

SpringBoot 概述 Spring Boot 可以轻松创建独立的、生产级的基于 Spring 的应用程序&#xff0c;您可以“直接运行”。 特征 创建独立的 Spring 应用程序 直接嵌入Tomcat&#xff0c;Jetty或Undertow&#xff08;无需部署WAR文件&#xff09; 提供固执己见的“入门”依赖项…

初始C语言 - 函数(2)

目录 1.函数的嵌套调用和链式访问 1&#xff09;函数嵌套调用 2&#xff09;函数的链式访问 - 函数的返回值作为另一个函数的参数 2. 函数的声明和定义 1&#xff09;变量的声明和定义 2&#xff09;函数的声明和定义 //函数必须先声明后使用//函数的声明写在头文件里 3.…