【星云 Orbit-F4 开发板】03b. 按键玩法二:独立按键双击双击触发

【星云 Orbit-F4 开发板】03b. 按键玩法二:独立按键双击触发

引言

在嵌入式系统中,按键是常用的输入设备。通过检测按键的状态变化,可以实现多种功能,例如单击、双击、长按等。本文将详细介绍如何使用STM32F103的GPIO引脚检测独立按键的双击事件,并通过HAL库实现模块化设计。通过本教程,读者将能够掌握独立按键的双击检测方法以及模块化编程的基本技巧。


硬件准备

在开始编程之前,确保您已经准备好以下硬件:

  1. STM32F103开发板:板载STM32F103RET6(Cortex-M3/72MHz)作为主控芯片。
  2. 独立按键:1个独立按键。
  3. 限流电阻:1个220Ω至330Ω的电阻,用于保护电路。
  4. 连接线:用于连接按键和开发板。

硬件连接

将独立按键连接到STM32F103的PB0引脚:

  1. 连接按键的正极

    • 按键的正极通过电阻连接到PB0。
  2. 连接按键的负极

    • 按键的负极连接到GND(地)。

GPIO配置

在STM32F103中,GPIO引脚可以配置为多种模式,以适应不同的应用需求。以下是一些常见的GPIO模式:

  1. 输入模式

    • 浮空输入(Floating Input):引脚处于高阻态,适用于不需要上拉或下拉的情况。
    • 上拉输入(Pull-Up Input):引脚内部连接上拉电阻,适用于外部信号为低电平有效的情况。
    • 下拉输入(Pull-Down Input):引脚内部连接下拉电阻,适用于外部信号为高电平有效的情况。
  2. 输出模式

    • 推挽输出(Push-Pull Output):引脚可以输出高电平或低电平,适用于直接驱动小电流负载,如LED灯。
    • 开漏输出(Open-Drain Output):引脚输出低电平或高阻态,适用于需要外部上拉电阻的场合。
  3. 复用模式

    • 用于将GPIO引脚配置为特定的外设功能,如UART、SPI等。

在本教程中,我们将使用上拉输入模式来检测按键的状态,因为这种模式可以直接检测按键的按下和释放状态。

配置GPIO时钟

在使用GPIO引脚之前,需要先使能相应的GPIO时钟。对于PB0引脚,需要使能GPIOB时钟。

// 使能GPIOB时钟
__HAL_RCC_GPIOB_CLK_ENABLE();

配置GPIO引脚

使用GPIO_InitTypeDef结构体配置GPIO引脚的模式、上下拉、速度等参数。

GPIO_InitTypeDef GPIO_InitStruct = {0};// 配置PB0为上拉输入模式
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉输入模式
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

按键控制模块

为了实现模块化设计,我们将按键的控制功能封装到bsp/KEY目录下的bsp_key.cbsp_key.h文件中。

1. 创建KEY目录

  1. 打开文件管理器

    • 导航到STM32F103项目目录下的Drivers/BSP文件夹。
  2. 创建新目录

    • 右键点击空白区域,选择新建文件夹
    • 输入目录名称KEY,并按回车键确认。

2. 创建bsp_key.cbsp_key.h文件

  • 确保bsp_key.cbsp_key.h文件当前位于Drivers/BSP目录下。

3. 更新项目包含路径

  1. 打开Keil MDK

    • 加载当前的STM32F103项目。
  2. 进入项目设置

    • 右键点击工程名称,选择Options for Target
  3. 添加新的包含路径

    • 在弹出的窗口中,选择C/C++选项卡。
    • Include Paths字段中,添加以下路径:
      Drivers/BSP/KEY
      
    • 确保路径正确无误,点击OK保存设置。

4. 更新main.c文件

  1. 打开main.c文件

    • 在Keil MDK的项目资源管理器中,找到并双击main.c文件。
  2. 包含新的头文件

    • 在文件顶部,添加以下包含语句:
      #include "bsp_key.h"
      
    • 确保路径正确,以便编译器能够找到该头文件。

5. 重新编译项目

  1. 编译工程

    • 点击工具栏中的Build按钮(或按F7键)。
    • 确保编译过程中没有错误和警告。
  2. 处理编译错误

    • 如果出现包含路径错误,请检查Include Paths设置是否正确。
    • 确保bsp_key.h文件位于Drivers/BSP/KEY目录下。

6. 更新项目分组

  1. 添加新的文件夹分组

    • 在Keil MDK的项目资源管理器中,右键点击BSP分组,选择Add Group
    • 输入分组名称KEY,点击OK
  2. 添加文件到分组

    • 右键点击新的KEY分组,选择Add New Item to Group
    • 选择Add Existing File,导航到Drivers/BSP/KEY目录,选择bsp_key.cbsp_key.h文件,点击OK
  3. 确保文件可见性

    • 确保bsp_key.cbsp_key.h文件在KEY分组下可见,并且路径正确。

按键控制模块实现

bsp_key.h文件

#ifndef __BSP_KEY_H
#define __BSP_KEY_H#include "stm32f103xx_hal.h"#define KEY_DEBOUNCE_DELAY 20  // 按键消抖延迟时间(单位:ms)
#define KEY_DOUBLE_CLICK_DELAY 500  // 双击延迟时间(单位:ms)/*** @brief 初始化按键*/
void KEY_Init(void);/*** @brief 检测按键状态* @return 按键状态(0:未按下,1:单击,2:双击)*/
uint8_t KEY_GetState(void);#endif /* __BSP_KEY_H */

bsp_key.c文件

#include "bsp_key.h"
#include "stm32f103xx_hal.h"static uint8_t key_state = 0;
static uint32_t key_press_time = 0;
static uint32_t key_release_time = 0;/*** @brief 初始化按键*/
void KEY_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};// 使能GPIOB时钟__HAL_RCC_GPIOB_CLK_ENABLE();// 配置PB0为上拉输入模式GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}/*** @brief 检测按键状态* @return 按键状态(0:未按下,1:单击,2:双击)*/
uint8_t KEY_GetState(void)
{static uint32_t last_press_time = 0;static uint8_t press_count = 0;if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET){// 按键按下if (key_state == 0){// 消抖key_press_time = HAL_GetTick();key_state = 1;}else if (key_state == 1){// 检测是否为双击if ((HAL_GetTick() - key_press_time) > KEY_DEBOUNCE_DELAY){press_count++;last_press_time = HAL_GetTick();key_state = 2;}}}else{// 按键释放if (key_state == 2){// 检测双击if ((HAL_GetTick() - last_press_time) < KEY_DOUBLE_CLICK_DELAY){press_count++;if (press_count >= 2){press_count = 0;return 2; // 双击}}else{press_count = 0;}key_state = 0;}}return 0; // 未按下
}

主程序实现

#include "stm32f103xx_hal.h"
#include "bsp_key.h"int main(void)
{// 系统初始化HAL_Init();SystemClock_Config();// 按键初始化KEY_Init();while (1){uint8_t state = KEY_GetState();if (state == 1){// 单击处理// 在此处添加单击事件的处理代码}else if (state == 2){// 双击处理// 在此处添加双击事件的处理代码}}
}

测试与验证

  1. 编译与下载

    • 将代码编译并下载到STM32F103开发板中。
  2. 观察按键状态

    • 连接好硬件后,按下按键,观察是否能够正确检测单击和双击事件。如果按键状态没有正确检测,请检查硬件连接和代码配置是否正确。

总结

通过本教程,您已经掌握了如何使用STM32F103的PB0引脚检测独立按键的双击事件,并通过HAL库实现模块化设计。按键状态的检测是关键步骤,选择合适的消抖和双击检测逻辑可以确保按键的稳定工作。模块化设计使代码更加清晰和易于维护,为后续的项目扩展奠定了良好的基础。希望本教程对您有所帮助,祝您在嵌入式开发的道路上取得更大的成功!

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

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

相关文章

NL2SQL的应用-长上下文模型在处理NL2SQL任务时,相较于传统模型,有哪些显著的优势

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下NL2SQL的应用-长上下文模型在处理NL2SQL任务时&#xff0c;相较于传统模型&#xff0c;有哪些显著的优势。NL2SQL&#xff08;自然语言转SQL&#xff09;技术旨在将用户自然语言提问自动转换为结构化查询语句&#…

A Large Recurrent Action Model: xLSTM Enables Fast Inference for Robotics Tasks

奥地利林茨约翰开普勒大学机器学习研究所 ELLIS 小组&#xff0c;LIT 人工智能实验室奥地利林茨 NXAI 有限公司谷歌 DeepMind米拉 - 魁北克人工智能研究所 摘要 近年来&#xff0c;强化学习&#xff08;Reinforcement Learning, RL&#xff09;领域出现了一种趋势&#xff0c;…

DeepSeek本地部署+自主开发对话Web应用

文章目录 引言前端部分核心页面DeepSeek.vueMyModal.vue 后端部分WebSocketConfig 配置类AbstractDeepSeekToolDeepSeekWebSocketHandler 数据库设计总结 引言 最近DeepSeep横空出世&#xff0c;在全球内掀起一股热潮&#xff0c;到处都是满血大模型接入的应用&#xff0c;但这…

DMA 定制固件教程:小白跟做即得单人固件,超详细纯喂饭教程,100% 成功秘籍!FPGA仿真1:1、中断逻辑和TLP核心都在。

DMA 定制固件教程 小白跟着操作做可以做出的单人固件 图文教程 链接&#xff1a;https://docs.qq.com/doc/DQ01lVGtHelROVHNv 本图文教程包含内容&#xff1a; 一、DMA仿真技术采集真实单人固件 二、网卡TLP仿真固件生成 三、DMA仿真技术io、中断逻辑&#xff0c;从零仿真 四、…

Linux | Ubuntu 与 Windows 双系统安装 / 高频故障 / UEFI 安全引导禁用

注&#xff1a;本文为 “buntu 与 Windows 双系统及高频故障解决” 相关文章合辑。 英文引文&#xff0c;机翻未校。 How to install Ubuntu 20.04 and dual boot alongside Windows 10 如何将 Ubuntu 20.04 和双启动与 Windows 10 一起安装 Dave’s RoboShack Published in…

spring中的注解介绍

本篇文章专门用来介绍spring中的各种注解。 1、RestController 1、含义 2、举例 3、使用场景 RestController 通常用于开发 RESTful API&#xff0c;适合返回 JSON 或 XML 数据的场景 4、总结 RestController 是 Spring 中用于简化 RESTful Web 服务开发的注解&#xff0c;它结…

JVM生产环境问题定位与解决实战(二):JConsole、VisualVM到MAT的高级应用

生产问题定位指南&#xff1a;几款必备的可视化工具 引言 在上一篇文章中&#xff0c;详细的介绍了JDK自带的一系列命令行工具&#xff0c;&#xff0c;如jps、jmap、jstat、jstack以及jcmd等&#xff0c;这些工具为排查和诊断Java虚拟机&#xff08;JVM&#xff09;问题提供…

网页制作09-html,css,javascript初认识のhtml如何使用表单

表单主要用来收集客户端提供的相关信息。,使网页具有交互作用。在网页制作的过程中&#xff0c;常常需要使用表单&#xff0c;如进行会员注册&#xff0c;网上调查和搜索等 访问者可以使用如文本域列表框&#xff0c;复选框以及单选按钮之类的表单对象输入信息&#xff0c;然后…

基本网络安全的实现

基本网络安全的实现 一 &#xff1a;AAA AAA 是Authentication&#xff0c;Authorization and Accounting&#xff08;认证、授权和计费&#xff09;的简 称&#xff0c;它提供了一个用来对认证、授权和计费这三种安全功能进行配置的一致性框架&#xff0c; 它是对网络安全…

Jupyter Notebook~Anaconda3安装教程

一、下载anaconda&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 百度网盘通道&#xff0c;链接:https://pan.baidu.com/s/1gyVDG2p71neFXi8VwXgvEQ?pwdewn7提取码: ewn7 二、安装 1、右击安装软件选择【以管理员身份运行】&#xff0c;点击【Next】…

【运维】内网服务器借助通过某台可上外网的服务器实现公网访问

背景&#xff1a; 内网服务器无法连接公网,但是办公电脑可以连接内网服务器又可以连接公网。 安装软件 1、frp 2、ccproxy 配置 1、内网服务器 # 内网服务器启动frp服务配置文件参考vi frps.ini# frps.ini [common] bind_port 7000# 备注: bind_port端口可以随意配置。配置完…

php 对接mqtt 完整版本,订阅消息,发送消息

首先打开链接如何在 PHP 项目中使用 MQTT 根据文章让所用依赖安装一下&#xff1a; composer require php-mqtt/client 安装之后弄一个部署 之后在工具里边可以相应链接上 接下来是代码&#xff1a; /**** 订阅消息* return void* throws \PhpMqtt\Client\Exceptions\Confi…

(2.26 “详细分析示例“ 暴力+位运算 最长优雅子数组)leetcode 2401

a&b0说明a和b的每一位都是一个0和一个1 不存在两个均为1的位次 a|0a 0与任何数|都等于它本身 &#xff08;mask&#xff09;的作用&#xff1a; 担心两数的1在用一位导致mask覆盖了&#xff1f; 答&#xff1a;出现这种情况说明mask与nums j后就直接break 由&#xff1a;…

数据开发的简历及面试

简历 个人信息: 邮箱别写QQ邮箱, 写126邮箱/189邮箱等 学历>>本科及以上写,大专及以下不写 专业>>非计算机专业不写 政治面貌>>党员写, 群众不用写 掌握的技能: 精通 > 熟悉 > 了解 专业工具: 大数据相关的 公司: 如果没有可以写的>>金融服…

Git原理+使用(超详细)

Git初识 当我们写项目代码时&#xff0c;需要不断的更新版本&#xff0c;那么就需要一个东西去管理这些不同版本的文件—版本控制器。 目前最主流的版本控制器就是Git。它是一个可以记录工程的每一次改动和版本迭代的管理系统&#xff0c;同时方便多人协同作业。 &#xff0…

数据结构秘籍(一)线性数据结构

1.数组 数组&#xff08;Array&#xff09;是一种很常见的数据结构。它由相同类型的元素&#xff08;element&#xff09;组成&#xff0c;并且是使用一块连续的内存来存储。 我们直接可以利用元素的索引&#xff08;index&#xff09;计算出该元素对应的存储地址。 数组的特…

WiFi IEEE 802.11协议精读:IEEE 802.11-2007,6,MAC service definition MAC服务定义

继续精读IEEE 802.11-2007 6&#xff0c;MAC service definition MAC服务定义 6.1 MAC服务概述 6.1.1 数据服务 此服务为对等逻辑链路控制&#xff08;LLC&#xff09;实体提供交换MAC服务数据单元&#xff08;MSDU&#xff09;的能力。为支持此服务&#xff0c;本地媒体访…

QT基于mmap文件映射机制实现的内存池方法总结

在现代计算机系统中&#xff0c;高效的内存管理对于程序性能有着至关重要的影响。尤其是在处理大量数据或频繁分配和释放小块内存的应用场景下&#xff0c;传统的内存分配方式&#xff08;如malloc和free&#xff09;可能会导致显著的性能开销和内存碎片化问题。为了克服这些问…

车载DoIP诊断框架 --- 连接 DoIP ECU/车辆的故障排除

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

0—QT ui界面一览

2025.2.26&#xff0c;感谢gpt4 1.控件盒子 1. Layouts&#xff08;布局&#xff09; 布局控件用于组织界面上的控件&#xff0c;确保它们的位置和排列方式合理。 Vertical Layout&#xff08;垂直布局&#xff09; &#xff1a;将控件按垂直方向排列。 建议&#xff1a;适…