此文方便我手抄hhh
way 1:
提前在CUBEMX中将对应按键勾选为输入模式,并根据按键检测的电平将IO配置为上拉或下拉,并命名KEY1(我这里是KEY1,其他的对照.c.h文件自行修改名称)。(这种配置方式,在文件生成时会自动将初始化代码放在main中,只需要田间按键检测的代码即可)
way 1——key.c (通用的单次检测函数)
#include "key.h"
/**
* @brief 按键扫描函数,实现按键按下的稳定检测(消抖+单次触发)
* @param mode 模式参数:1-重置按键状态(强制认为按键已释放),0-正常扫描模式
* @return uint8_t 按键值:0-无按键操作,1-按键被稳定按下
*/
uint8_t KeyScan(uint8_t mode)
{
// 静态变量,用于记录按键状态:1表示按键已释放(可检测新按下),0表示按键未释放(避免重复触发)
// 静态特性确保函数调用后状态不丢失,跨调用维持状态记忆
static uint8_t key_up = 1;
// 按键返回值,默认0(无操作)
uint8_t keyvalue = 0;
// 模式判断:若mode为1,强制重置按键为"已释放"状态(用于初始化或强制刷新)
if (mode)
key_up = 1;
// 核心检测逻辑:当按键处于"已释放"状态,且当前检测到按键按下(!KEY1表示按键闭合,假设KEY1为高电平常态)
if (key_up && (!KEY1))
{
osDelay(3); // 延时3ms消除机械抖动(按键按下时的瞬时不稳定状态)
if (!KEY1) // 延时后再次检测,确认按键确实稳定按下(排除抖动干扰)
keyvalue = 1; // 确认按下,设置返回值为1
// 若已检测到有效按下,标记按键为"未释放"状态,避免一次按下被重复识别
if (keyvalue)
key_up = 0;
}
// 分支:当按键处于"未释放"状态(key_up=0),检测是否已松开
else
{
osDelay(3); // 延时3ms消除松开时的机械抖动
if (KEY1) // 延时后检测到按键恢复高电平,确认已稳定松开
key_up = 1; // 重置为"已释放"状态,允许下次按下检测
}
return keyvalue; // 返回按键状态(0或1)
}
way 1——key.h
#ifndef __KEY_H__
#define __KEY_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
//KEY1
#define KEY1_PORT GPIOE //在这里修改引脚
#define KEY1_PIN GPIO_PIN_3 //在这里修改引脚
#define KEY1 HAL_GPIO_ReadPin(KEY1_PORT,KEY1_PIN)
//KEY2
#define KEY2 0
void Key_Port_Init(void);
void Key_Interrupt_Callback(void);
uint8_t KeyScan(uint8_t mode);
#ifdef __cplusplus
}
#endif
#endif
way 2:
懒得去CUBEMX中配置的话,就去看好对应的按键是哪个,创建key.c文件准备进行后续初始化函数和检测函数的编写
way 2——key.c
相较于way 1的.c文件增加了 void Key_Port_Init(void),初始化,记得在主函数中初始化即可
#include "key.h"
#include "cmsis_os.h"
void Key_Port_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOE_CLK_ENABLE();
/*Configure GPIO pin : PA0 */
GPIO_InitStruct.Pin = KEY1_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY1_PORT, &GPIO_InitStruct);
/* EXTI interrupt init*/
// HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(EXTI0_IRQn);
}
/**
* @brief 按键扫描函数,实现按键按下的稳定检测(消抖+单次触发)
* @param mode 模式参数:1-重置按键状态(强制认为按键已释放),0-正常扫描模式
* @return uint8_t 按键值:0-无按键操作,1-按键被稳定按下
*/
uint8_t KeyScan(uint8_t mode)
{
// 静态变量,用于记录按键状态:1表示按键已释放(可检测新按下),0表示按键未释放(避免重复触发)
// 静态特性确保函数调用后状态不丢失,跨调用维持状态记忆
static uint8_t key_up = 1;
// 按键返回值,默认0(无操作)
uint8_t keyvalue = 0;
// 模式判断:若mode为1,强制重置按键为"已释放"状态(用于初始化或强制刷新)
if (mode)
key_up = 1;
// 核心检测逻辑:当按键处于"已释放"状态,且当前检测到按键按下(!KEY1表示按键闭合,假设KEY1为高电平常态)
if (key_up && (!KEY1))
{
osDelay(3); // 延时3ms消除机械抖动(按键按下时的瞬时不稳定状态)
if (!KEY1) // 延时后再次检测,确认按键确实稳定按下(排除抖动干扰)
keyvalue = 1; // 确认按下,设置返回值为1
// 若已检测到有效按下,标记按键为"未释放"状态,避免一次按下被重复识别
if (keyvalue)
key_up = 0;
}
// 分支:当按键处于"未释放"状态(key_up=0),检测是否已松开
else
{
osDelay(3); // 延时3ms消除松开时的机械抖动
if (KEY1) // 延时后检测到按键恢复高电平,确认已稳定松开
key_up = 1; // 重置为"已释放"状态,允许下次按下检测
}
return keyvalue; // 返回按键状态(0或1)
}
way 2——key.h
与way 1的文件相同
750

被折叠的 条评论
为什么被折叠?



