本帖最后由 Peixu 于 2024-9-27 09:24 编辑
#申请原创# @21小跑堂 本文将详细介绍如何在 APM32F003 微控制器上实现一个2秒内按键双击检测程序,该程序通过双击按键 PC4 来翻转 LED(连接在 PD1 上)的状态。
1. 硬件准备
1.1 硬件连接
按键:将按键连接到 APM32F003 的 GPIOC 的 PIN4 (PC4)。
LED:将 LED 连接到 APM32F003 的 GPIOD 的 PIN1 (PD1)。
电源和接地:确保微控制器、按键和 LED 的电源和接地连接良好。
2. 代码实现
以下是实现按键双击检测的代码,代码中包含了完整的逻辑处理及注释。
- #include "main.h"
- // 定义消抖延迟时间为 20ms
- #define DEBOUNCE_DELAY 20
- // 按键状态和计数变量
- volatile uint32_t lastButtonPressTime = 0;
- volatile uint8_t buttonPressCount = 0;
- volatile uint32_t lastDebounceTime = 0;
- /*!
- * [url=home.php?mod=space&uid=247401]@brief[/url] Main program
- *
- * @param None
- *
- * @retval None
- */
- int main(void)
- {
- /* 配置 SysTick 定时器为 1 毫秒中断 */
- SysTick_Config(RCM_GetMasterClockFreq() / 1000);
-
- // 初始化 GPIO
- GPIO_Init();
-
- while(1)
- {
- // 其他任务可以放在这里
- }
- }
- void SysTick_Handler(void)
- {
- // 调用延迟中断服务程序
- APM_DelayIsr();
- static uint32_t tickCounter = 0;
- tickCounter++;
-
- // 检查按键状态
- CheckButton();
- // 检查是否超过 2 秒未按下第二次按键
- if (tickCounter >= 2000) {
- tickCounter = 0; // 重置计时器
- buttonPressCount = 0; // 重置按键计数
- }
-
- // 检测到双击时翻转 LED 状态
- if (buttonPressCount == 2) {
- GPIO_Toggle(GPIOD, GPIO_PIN_1);
- buttonPressCount = 0; // 重置按键计数
- }
- }
- void GPIO_Init(void)
- {
- GPIO_Config_T gpioConfig;
-
- // 配置 LED 引脚 PD1 为推挽输出
- gpioConfig.mode = GPIO_MODE_OUT_PP;
- gpioConfig.speed = GPIO_SPEED_10MHz;
- gpioConfig.intEn = GPIO_EINT_DISABLE;
- gpioConfig.pin = GPIO_PIN_1;
- GPIO_Config(GPIOD, &gpioConfig);
-
- // 配置按键引脚 PC4 为上拉输入
- gpioConfig.mode = GPIO_MODE_IN_PU;
- gpioConfig.speed = GPIO_SPEED_10MHz;
- gpioConfig.intEn = GPIO_EINT_DISABLE;
- gpioConfig.pin = GPIO_PIN_4;
- GPIO_Config(GPIOC, &gpioConfig);
- }
- // 检查按键状态
- void CheckButton(void) {
- static uint8_t previousButtonState = SET; // 假设初始状态为未按下
- uint8_t currentButtonState = GPIO_ReadInputBit(GPIOC, GPIO_PIN_4); // 读取当前按键状态
- uint32_t currentTime = SysTick->VAL; // 获取当前 SysTick 计数值
- uint32_t elapsedTime = (lastDebounceTime - currentTime) & 0xFFFFFF; // 计算时间差
- // 如果按键状态改变,则记录当前时间
- if (currentButtonState != previousButtonState) {
- lastDebounceTime = SysTick->LOAD - currentTime; // 记录消抖时间
- }
- // 检测按键下降沿
- if ((elapsedTime >= DEBOUNCE_DELAY) && (currentButtonState == 0) && (previousButtonState == SET)) {
- lastButtonPressTime = SysTick->LOAD - currentTime; // 记录按键按下的时间
- buttonPressCount++; // 增加按键计数
- }
-
- previousButtonState = currentButtonState; // 更新按键的上一个状态
- }
3. 代码解析
3.1 SysTick 定时器
在 main() 函数中,我们配置了 SysTick 定时器,以便每毫秒产生一次中断。这样可以实现精准的时间计数,便于我们进行消抖处理和双击检测。
3.2 GPIO 初始化
在 GPIO_Init() 函数中,我们设置了 LED 引脚(PD1)为推挽输出模式,而将按键引脚(PC4)设置为上拉输入模式。上拉输入模式能够确保在按键未按下时,GPIO 的输入状态为高。
3.3 按键检查逻辑
在 CheckButton() 函数中,我们实现了按键状态的检测与消抖功能。通过记录按键的前一个状态,我们可以判断按键是否发生了变化。若检测到按键从高电平(未按下)变为低电平(按下),并且消抖延迟已过,则增加按键计数 buttonPressCount。
3.4 双击检测
在 SysTick_Handler() 中,我们会检查 buttonPressCount 的值。如果检测到两次按键按下(buttonPressCount == 2),则翻转 LED 状态,并将计数器重置为 0。
4. 总结
通过以上代码,成功实现了一个按键双击检测的程序,只需在 PC4 上双击按键,即可翻转 PD1 上的 LED 状态。这种功能在许多应用中都非常有用,比如遥控器或者其他需要用户交互的设备。接下来,我们可以进一步扩展功能,比如增加长按检测、三击检测等,以丰富用户体验。希望本文的介绍能够帮助您更好地理解按键处理的基本原理及实现方式。
|