stm32f103多个按键
时间: 2024-12-30 21:19:18 浏览: 8
### STM32F103多个按键的硬件连接
对于STM32F103系列微控制器而言,在设计多按键电路时,通常采用矩阵键盘或独立按键两种方式。当涉及较少数量的按键(如不超过4个),推荐使用独立按键方案来简化布线和程序逻辑。
#### 独立按键布局建议:
- 将每个按键的一端接地(GND),另一端接至MCU的不同GPIO引脚;
- 每个按键对应的IO口需配置为输入模式并启用内部上拉电阻;
- 需要确保所选引脚支持外部中断EXTI功能以便触发相应的事件处理函数[^1]。
```c
// GPIO初始化设置示例代码 (假设使用的是PA0, PA1两个按键)
void Key_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure the GPIO pins */
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发中断
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
```
### 编程实现要点
为了区分不同类型的按键操作(即短按与长按),可以利用定时器配合状态机的方式来进行判断。具体来说就是记录下每次按下时刻的时间戳,并在释放时计算持续时间从而判定属于哪种情况。
#### 中断服务子程序(ISR)框架构建:
每当检测到有键被按下或者松开的时候就会进入这个ISR里面执行相应动作。这里需要注意防止抖动带来的误判问题,一般通过软件延时去抖即可解决。
```c
uint32_t key_press_time[KEY_NUM]; // 存储各按键首次按下时间
volatile uint8_t key_status[KEY_NUM]; // 记录当前按键的状态(0=未按下, 1=已按下)
void EXTI0_IRQHandler(void){ // 假设这是PA0对应IRQ Handler
if (__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_0)){
if(HAL_GetTick() - key_press_time[0] >= LONG_PRESS_TIME_MS && !key_status[0]){
// 执行长按指令...
key_status[0] = 1;
}else{
// 如果不是长按,则等待抬起后再做进一步处理
}
__HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);
}
}
void EXTI1_IRQHandler(void){ // 同理定义其他按键的IRQ handler ...
}
```
另外还需要编写一个用于监测按键弹起后的回调函数,用来最终确认是一次完整的短按还是已经发生了超时转成长按的情况。
```c
void CheckForKeyRelease(uint8_t index){
if(!HAL_GPIO_ReadPin(KEY_PORT[index], KEY_PIN[index])){
if(key_status[index]){
// 已经识别过一次长按了,无需再响应此次抬升沿
key_status[index]=0;
} else {
// 属于正常范围内的快速点击行为
// 发送短按命令给应用层...
}
}
key_press_time[index] = HAL_GetTick(); // 更新最新按下时间戳
}
```
阅读全文