ST意法半导体
直播中

李英

8年用户 1538经验值
私信 关注
[问答]

Stm32f103 hal库如果设置多个外部中断,只要用螺丝刀碰触其中一个中断线,所有的中断函数都有可能进入,乱跳,为什么?

STM32f103 hal库如果设置多个外部中断,只要用螺丝刀碰触其中一个中断线,所有的中断函数都有可能进入,乱跳。同一个线路板用标准库就没问题。正点原子的开发版及HAL库例程也这样。STM32H562开发板及HAL库例程也这样。谁能答复一下

回帖(2)

刘晓燕

2025-3-10 14:38:16
hal库一般用的回调,这个里面输入有产生中断源,需要判断中断源进行处理。
举报

贺服窍

2025-3-11 17:43:07

在使用STM32F103的HAL库时,如果设置多个外部中断,当用螺丝刀碰触其中一个中断线时,所有的中断函数都有可能进入,出现“乱跳”的现象,这可能是由于以下几个原因导致的:


1. 中断优先级设置问题



  • 问题描述:如果多个外部中断的优先级设置相同或未正确配置,可能会导致中断嵌套或中断抢占,从而出现多个中断函数被触发的情况。

  • 解决方案:确保每个外部中断的优先级设置正确,避免优先级冲突。可以使用HAL_NVIC_SetPriority()函数为每个外部中断设置不同的优先级。


2. 中断线配置问题



  • 问题描述:在HAL库中,外部中断线的配置可能没有正确初始化或清除中断标志位,导致中断误触发。

  • 解决方案:在初始化外部中断时,确保正确配置中断线,并在中断服务函数中及时清除中断标志位。可以使用__HAL_GPIO_EXTI_CLEAR_FLAG()函数清除中断标志。


3. 硬件干扰问题



  • 问题描述:用螺丝刀碰触中断线可能会引入静电或电磁干扰,导致其他中断线误触发。

  • 解决方案:在硬件设计上,确保中断线的抗干扰能力,如增加滤波电容、使用屏蔽线等。在软件上,可以在中断服务函数中增加去抖动处理,避免误触发。


4. HAL库版本问题



  • 问题描述:某些HAL库版本可能存在BUG或配置不当,导致外部中断处理异常。

  • 解决方案:尝试更新到最新的HAL库版本,或参考官方例程进行配置。如果问题依然存在,可以考虑使用标准库或LL库进行开发。


5. 中断服务函数实现问题



  • 问题描述:在HAL库中,中断服务函数的实现可能存在问题,如未正确判断中断源或未及时清除中断标志。

  • 解决方案:确保在中断服务函数中正确判断中断源,并清除相应的中断标志。例如,使用__HAL_GPIO_EXTI_GET_FLAG()函数判断中断源,并使用__HAL_GPIO_EXTI_CLEAR_FLAG()函数清除中断标志。


6. GPIO配置问题



  • 问题描述:如果GPIO模式配置不正确,可能会导致中断误触发。例如,配置为浮空输入时,未连接外部上拉或下拉电阻,容易受到干扰。

  • 解决方案:确保GPIO模式配置正确,如配置为上拉或下拉输入,以增强抗干扰能力。


7. 电源噪声问题



  • 问题描述:电源噪声可能会通过GPIO引脚引入,导致中断误触发。

  • 解决方案:确保电源稳定,增加去耦电容,减少电源噪声。


示例代码


以下是一个配置外部中断的示例代码,确保优先级设置和中断标志清除:


// 初始化外部中断
void EXTI_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 配置GPIO引脚为输入模式
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 设置中断优先级
    HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
    HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0);

    // 使能中断
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);
    HAL_NVIC_EnableIRQ(EXTI1_IRQn);
}

// 外部中断0服务函数
void EXTI0_IRQHandler(void) {
    if (__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_0)) {
        __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0);
        // 处理中断
    }
}

// 外部中断1服务函数
void EXTI1_IRQHandler(void) {
    if (__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_1)) {
        __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_1);
        // 处理中断
    }
}

通过以上措施,可以有效避免外部中断“乱跳”的问题。如果问题依然存在,建议进一步检查硬件设计和软件配置,或联系ST官方技术支持。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分