多功能按键怎么做STM32
多功能按键怎么做STM32
更多
在STM32上实现多功能按键(如短按、长按、双击等),需要结合按键扫描、状态机、定时器和事件处理。以下是详细步骤和代码示例:
1. 硬件连接
- 按键一端接STM32 GPIO(如PA0),另一端接地。
- GPIO配置为上拉输入(内部上拉电阻),按键按下时引脚为低电平。
2. 软件设计思路
- 消抖处理:按键按下/释放时消除机械抖动。
- 状态机:跟踪按键状态(空闲、按下、长按、释放等)。
- 定时器:使用硬件定时器(如TIM2)每隔10ms扫描按键。
- 事件判断:
- 短按:按下后快速释放(时间 < 长按阈值)。
- 长按:按下持续时间 ≥ 长按阈值。
- 双击:在指定时间内连续两次短按。
3. 代码实现
(1) 初始化按键和定时器
#include "stm32f1xx_hal.h"
// 按键定义
#define KEY_PIN GPIO_PIN_0
#define KEY_PORT GPIOA
#define KEY_PRESSED 0 // 低电平表示按下
#define KEY_RELEASED 1 // 高电平表示释放
// 时间阈值(单位:10ms)
#define DEBOUNCE_TIME 2 // 消抖时间20ms
#define LONG_PRESS_TIME 100 // 长按1秒(100×10ms)
#define DOUBLE_CLICK_GAP 20 // 双击间隔200ms
// 按键状态机
typedef enum {
KEY_IDLE,
KEY_DEBOUNCE,
KEY_PRESS,
KEY_LONG_PRESS,
KEY_RELEASE
} KeyState;
// 按键事件
typedef enum {
EVENT_NONE,
EVENT_SHORT_PRESS,
EVENT_LONG_PRESS,
EVENT_DOUBLE_CLICK
} KeyEvent;
volatile KeyState key_state = KEY_IDLE;
volatile uint32_t key_press_duration = 0;
volatile uint8_t click_count = 0;
volatile uint32_t last_release_time = 0;
KeyEvent key_event = EVENT_NONE;
// 初始化GPIO
void Key_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = KEY_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉输入
HAL_GPIO_Init(KEY_PORT, &GPIO_InitStruct);
}
// 初始化定时器(10ms中断)
void Timer_Init(void) {
TIM_HandleTypeDef htim2;
__HAL_RCC_TIM2_CLK_ENABLE();
htim2.Instance = TIM2;
htim2.Init.Prescaler = 7200 - 1; // 72MHz/7200 = 10kHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 100 - 1; // 10kHz/100 = 100Hz (10ms)
HAL_TIM_Base_Init(&htim2);
HAL_TIM_Base_Start_IT(&htim2);
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
}
(2) 定时器中断处理(按键状态机)
// TIM2中断服务函数
void TIM2_IRQHandler(void) {
if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE)) {
__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_UPDATE);
uint8_t key_current = HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN);
switch (key_state) {
case KEY_IDLE:
if (key_current == KEY_PRESSED) {
key_state = KEY_DEBOUNCE;
key_press_duration = 0;
}
// 双击检测:记录两次释放的时间差
if (click_count > 0 && (++last_release_time > DOUBLE_CLICK_GAP)) {
if (click_count == 1) key_event = EVENT_SHORT_PRESS;
click_count = 0;
}
break;
case KEY_DEBOUNCE:
if (key_current == KEY_PRESSED) {
if (++key_press_duration >= DEBOUNCE_TIME) {
key_state = KEY_PRESS;
key_press_duration = 0;
}
} else {
key_state = KEY_IDLE;
}
break;
case KEY_PRESS:
if (key_current == KEY_RELEASED) {
key_state = KEY_RELEASE;
} else {
if (++key_press_duration >= LONG_PRESS_TIME) {
key_state = KEY_LONG_PRESS;
key_event = EVENT_LONG_PRESS;
click_count = 0; // 长按清零单击计数
}
}
break;
case KEY_LONG_PRESS:
if (key_current == KEY_RELEASED) {
key_state = KEY_IDLE;
}
break;
case KEY_RELEASE:
if (key_current == KEY_RELEASED) {
key_state = KEY_IDLE;
click_count++;
last_release_time = 0;
// 双击判断:第一次释放后开始计时
if (click_count == 2) {
key_event = EVENT_DOUBLE_CLICK;
click_count = 0;
}
}
break;
}
}
}
(3) 主循环中处理按键事件
int main(void) {
HAL_Init();
Key_Init();
Timer_Init();
while (1) {
switch (key_event) {
case EVENT_SHORT_PRESS:
key_event = EVENT_NONE;
// 执行短按操作
break;
case EVENT_LONG_PRESS:
key_event = EVENT_NONE;
// 执行长按操作
break;
case EVENT_DOUBLE_CLICK:
key_event = EVENT_NONE;
// 执行双击操作
break;
default:
break;
}
HAL_Delay(10); // 主循环延时
}
}
4. 关键点说明
- 消抖:在
KEY_DEBOUNCE状态延迟20ms确认按键按下。 - 长按检测:在
KEY_PRESS状态计时,超过1秒触发长按。 - 双击检测:
- 第一次释放后启动
last_release_time计时。 - 若200ms内再次按下并释放,触发双击。
- 第一次释放后启动
- 事件处理:在
主循环中根据key_event执行对应操作。
5. 优化建议
- 多按键支持:为每个按键定义独立的状态机变量。
- 松手检测:长按可在释放后触发事件(需修改状态机)。
- 资源占用:若系统已有RTOS,可用任务代替定时器扫描。
通过以上设计,可实现稳定的多功能按键检测,适用于复杂交互场景。
企业AI模型托管怎么做的
当下,越来越多的企业选择将AI模型托管给专业的第三方平台,以实现高效、灵活和安全的模型运行。下面,AI部落小编为您介绍企业AI模型托管是怎么做的。
2025-01-15 10:10:47
多功能按键嵌入式程序设计资料下载
电子发烧友网为你提供多功能按键嵌入式程序设计资料下载的电子资料下载,更有其他相关的电路图、源代码、课件教程、中文资料、英文资料、参考设计、用户指南、解决方案等资料,希望可以帮助到广大的电子工程师们。
资料下载
张国厚
2021-04-23 08:40:30
7天热门专题
换一换
换一换
- 如何分清usb-c和type-c的区别
- 中国芯片现状怎样?芯片发展分析
- vga接口接线图及vga接口定义
- 芯片的工作原理是什么?
- 华为harmonyos是什么意思,看懂鸿蒙OS系统!
- 什么是蓝牙?它的主要作用是什么?
- ssd是什么意思
- 汽车电子包含哪些领域?
- TWS蓝牙耳机是什么意思?你真的了解吗
- 什么是单片机?有什么用?
- 升压电路图汇总解析
- plc的工作原理是什么?
- 再次免费公开一肖一吗
- 充电桩一般是如何收费的?有哪些收费标准?
- ADC是什么?高精度ADC是什么意思?
- dtmb信号覆盖城市查询
- EDA是什么?有什么作用?
- 中科院研发成功2nm光刻机
- 苹果手机哪几个支持无线充电的?
- type-c四根线接法图解
- 华为芯片为什么受制于美国?
- 怎样挑选路由器?
- 元宇宙概念股龙头一览
- 锂电池和铅酸电池哪个好?
- 如何进行编码器的正确接线?接线方法介绍
- 什么是场效应管?它的作用是什么?
- 虚短与虚断的概念介绍及区别
- 晶振的作用是什么?
- 大疆无人机的价格贵吗?大约在什么价位?
- amoled屏幕和oled区别
- 苹果nfc功能怎么复制门禁卡
- 单片机和嵌入式的区别是什么
- 复位电路的原理及作用
- BLDC电机技术分析
- dsp是什么意思?有什么作用?
- 苹果无线充电器怎么使用?
- iphone13promax电池容量是多少毫安
- 芯片的组成材料有什么
- 特斯拉充电桩充电是如何收费的?收费标准是什么?
- 直流电机驱动电路及原理图
- 传感器常见类型有哪些?
- 自举电路图
- 苹果笔记本macbookpro18款与19款区别
- 通讯隔离作用
- 新斯的指纹芯片供哪些客户
- 伺服电机是如何进行工作的?它的原理是什么?
- 无人机价钱多少?为什么说无人机烧钱?
- 以太网VPN技术概述
- 手机nfc功能打开好还是关闭好
- 十大公认音质好的无线蓝牙耳机