STM32 HAL库使用哪个指令单独关闭外部中断
时间: 2024-01-26 18:02:26 浏览: 204
在STM32 HAL库中,可以使用以下指令来单独关闭外部中断:
```c
HAL_NVIC_DisableIRQ(EXTIx_IRQn);
```
其中,`EXTIx_IRQn`是具体外部中断对应的中断号,例如`EXTI0_IRQn`、`EXTI1_IRQn`等。使用该指令可以单独关闭指定的外部中断,而不影响其他中断的正常运行。需要根据具体的外部中断号进行相应的设置。
相关问题
stm32f103按键双击
### STM32F103按键双击功能实现
对于STM32F103系列微控制器而言,要实现在该平台上通过软件逻辑来识别按键的不同操作模式(如单击、双击以及长按),可以通过定时器配合状态机的方式完成。下面提供了一种基于时间间隔判断的方法用于区分这些不同的点击事件。
#### 定义宏定义与变量初始化
为了简化编程并提高可读性,先对一些常用的参数进行预处理指令定义:
```c
#define KEY_PIN GPIO_PIN_12 /* 按键连接到PB12 */
#define KEY_PORT GPIOB /* PB端口 */
volatile uint8_t key_state = 0;
volatile uint8_t click_count = 0;
volatile uint8_t long_press_flag = 0;
// 时间常量设置
const uint16_t DEBOUNCE_TIME = 50; // 去抖动延迟(ms)
const uint16_t SHORT_PRESS_TIME = 300; // 单次按下最大持续时间(ms),超过则认为是长按
const uint16_t DOUBLE_CLICK_INTERVAL = 400; // 双击之间允许的最大间隔时间(ms)
/* 初始化TIM7作为系统计时器 */
void MX_TIM7_Init(void){
__HAL_RCC_TIM7_CLK_ENABLE();
TIM_HandleTypeDef htim7;
htim7.Instance = TIM7;
htim7.Init.Prescaler = SystemCoreClock / 1000 - 1; // 配置为每毫秒中断一次
htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
htim7.Init.Period = 999;
htim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
if (HAL_TIM_Base_Init(&htim7) != HAL_OK){
Error_Handler();
}
}
```
上述代码片段展示了如何配置一个硬件定时器(TIM7)[^1],以便后续能够精确测量每次按键动作的时间差。这里选择了TIM7作为一个简单的例子;实际应用中可以根据具体需求调整使用的定时器资源。
#### 中断服务程序ISR编写
当检测到按键电平变化时触发外部中断,在相应的中断服务子程序(ISR)内记录当前时刻,并启动去抖动机制:
```c
extern "C" void EXTI15_10_IRQHandler(void){
HAL_GPIO_EXTI_IRQHandler(KEY_PIN);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
static uint32_t last_time = 0;
uint32_t current_time = HAL_GetTick();
if(GPIO_Pin == KEY_PIN && !long_press_flag){
if((current_time - last_time) > DEBOUNCE_TIME){ // 去除机械开关带来的噪声干扰
switch(key_state){
case 0://等待首次下降沿到来
key_state = 1;
last_time = current_time;
break;
case 1://已经捕捉到了第一次上升沿,正在等待第二次下降沿
if(current_time - last_time < DOUBLE_CLICK_INTERVAL){
click_count++;
if(click_count >= 2){
// 执行双击响应函数
double_click_action();
click_count = 0;
key_state = 0;
}else{
key_state = 2;
last_time = current_time;
}
}else{//超出了两次点击之间的合理范围,则视为单独的一次点击
single_click_action();
key_state = 0;
}
break;
default:
key_state = 0;
break;
}
}
while(HAL_GPIO_ReadPin(KEY_PORT,KEY_PIN)==GPIO_PIN_RESET); // 等待松开按钮
if(!long_press_flag){
last_time = HAL_GetTick();
key_state = 1;
}
}
// 清除标志位
__HAL_GPIO_EXTI_CLEAR_IT(KEY_PIN);
}
```
此部分实现了对外部中断的响应逻辑[^3]。每当发生有效的按键事件后都会进入这段代码执行特定的任务分支——无论是单击还是双击都将被正确地区分出来。
#### 主循环中的长时间监测
除了依靠外部中断捕获瞬态信号外,还需要周期性地检查是否有未决的长期按键情况存在:
```c
int main(void){
...
while (1){
if(long_press_flag){
// 处理长按时的动作...
long_press_action();
// 重置标记防止重复触发
long_press_flag = 0;
}
HAL_Delay(100); // 减少CPU占用率
}
}
static void check_long_press(){
static uint32_t press_start_time = 0;
if(HAL_GPIO_ReadPin(KEY_PORT,KEY_PIN)!=GPIO_PIN_SET){
if(press_start_time==0){
press_start_time=HAL_GetTick();
}
else {
if(HAL_GetTick()-press_start_time>=SHORT_PRESS_TIME){
long_press_flag=1;
press_start_time=0;
}
}
}
else {
press_start_time=0;
}
}
```
这部分负责监控是否存在连续保持按键不放的情况,一旦满足条件即调用`long_press_action()`来进行相应处理[^4]。
阅读全文