硬件
可以看到是PA0,PA8,PB1,PB2在控制四个按键
Cubemx配置
设置输入模式上拉电阻,看电路图可知按键释放为高电平,按下为低电平
软件
番外:计时器消抖
如果在主函数用延时消抖会消耗CPU资源
【STM32 HAL】按键消抖_U3VwZXJ5dV8wMQ==的博客-CSDN博客_按键消抖
T(s)=(ARR+1)∗(PSC+1) / TIM_CLK(Hz)
代码编写
记得在主函数开启中断
HAL_TIM_Base_Start_IT(&htim10);
状态机定义
-
定时器中断回调函数
-
typedef enum { KEY_CHECK = 0, //按键检测状态 KEY_COMFIRM, //按键确认状态 KEY_RELEASE //按键释放状态 }keyState_e; //状态枚举变量 typedef struct { keyState_e keyState; //按键状态 uint8_t keyFlag; //按键按下标志 }key_t; //按键状态结构体
-
定时器中断回调函数
-
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM10) { switch(Key.keyState) { case KEY_CHECK: { // 读到低电平,进入按键确认状态 if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) { Key.keyState = KEY_COMFIRM; } break; } case KEY_COMFIRM: { if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET) { //读到低电平,按键确实按下,按键标志位置1,并进入按键释放状态 Key.keyFlag = 1; Key.keyState = KEY_RELEASE; } //读到高电平,可能是干扰信号,返回初始状态 else { Key.keyState = KEY_CHECK; } break; } case KEY_RELEASE: { if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_SET) { // 读到高电平,说明按键释放,返回初始状态 Key.keyState = KEY_CHECK; } break; } default: break; } } }