打印
[STM32F4]

关于HAL库外部中断进两次中断服务的问题

[复制链接]
1732|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 数码小叶 于 2020-6-18 10:52 编辑

最近一个应用里用到了STM32F4的两个外部中断,但是最终结果一直不对,发现仿真是正确的,单独运行就不正确,多次调试后发现问题出现在中断上,中断服务函数进了两次,但是这个应用只允许进一次中断
在论坛搜索到两个帖子:


用HAL库写的一个STM32的中断程序,为什么会发生两次中断
https://bbs.21ic.com/icview-2520878-1-1.html?fromuser=
(出处: 中国电子网技术论坛)

关于STM32中断多进的问题总结
https://bbs.21ic.com/icview-184728-1-1.html?fromuser=
(出处: 中国电子网技术论坛)


知道了问题出现的原因是AHB2APB桥延迟,其中提到几条建议:
1)进入中断后,判断了相应标志位,就clear之,在作后续的处理
3、解决方法:清中断标志,只要不是中断函数的最后一条语句就没问题了。
当前这个情况下把程序下载到板子上运行的时候,按下按键,LED的状态会翻转两次,后来尝试改了一下软件生成的代码,将清中断标志位那条语句放到调用中断回调函数之后就可以了



程序原本的代码:


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
        if(GPIO_Pin == GPIO_PIN_8)
        {
                xxxxxxxxxxxxxxxxxxxxxxxxx;

        }
}


原本的清标志是自动生成的


void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}




按照建议,改成如下依旧无效果


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{  
       __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
        if(GPIO_Pin == GPIO_PIN_8)
        {
                xxxxxxxxxxxxxxxxxxxxxxxxx;

        }
}


void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
   __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
  }
}








使用特权

评论回复
沙发
598330983| | 2020-6-18 19:06 | 只看该作者
官方的例子中这个操作是怎么实现的

使用特权

评论回复
板凳
598330983| | 2020-6-18 19:13 | 只看该作者
好奇怪啊,安装官方原本的方法就行啊。

使用特权

评论回复
地板
598330983| | 2020-6-18 19:17 | 只看该作者

是不是因为没有放到这个里面

使用特权

评论回复
5
598330983| | 2020-6-18 19:19 | 只看该作者

因为在启动文件里是这样进入中断的。

使用特权

评论回复
6
数码小叶|  楼主 | 2020-6-18 20:58 | 只看该作者
598330983 发表于 2020-6-18 19:19
因为在启动文件里是这样进入中断的。

没有明白你的意思,可以讲解一下问题出在哪么,这个卡好久了

使用特权

评论回复
7
598330983| | 2020-6-18 22:18 | 只看该作者
数码小叶 发表于 2020-6-18 20:58
没有明白你的意思,可以讲解一下问题出在哪么,这个卡好久了 ...

你看一下官方的例子就明白了。还有启动文件,中断要放到中短线函数里,才能起效。

使用特权

评论回复
8
598330983| | 2020-6-18 22:23 | 只看该作者
void EXTI4_15_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
}

这样就可以了。

使用特权

评论回复
9
数码小叶|  楼主 | 2020-6-19 08:46 | 只看该作者
598330983 发表于 2020-6-18 22:23
void EXTI4_15_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);

这个代码程序里有啊,不是进不去中断,是一次中断,会跳转两次到中断服务程序

使用特权

评论回复
10
598330983| | 2020-6-22 22:20 | 只看该作者
数码小叶 发表于 2020-6-19 08:46
这个代码程序里有啊,不是进不去中断,是一次中断,会跳转两次到中断服务程序 ...

那就不清楚啥情况了,还没解决?》

使用特权

评论回复
11
598330983| | 2020-6-22 22:21 | 只看该作者
是不是真滴发生了两次,按键抖动了?

使用特权

评论回复
12
sonicll| | 2020-6-23 08:50 | 只看该作者
你在EXTI4_15_IRQHandler里面先清中断标志看看,这里是中断最早执行的地方

使用特权

评论回复
13
数码小叶|  楼主 | 2020-6-23 09:08 | 只看该作者
598330983 发表于 2020-6-22 22:21
是不是真滴发生了两次,按键抖动了?

确确实实是进入两次,HAL_GPIO_EXTI_IRQHandler进入一次,HAL_GPIO_EXTI_Callback进入两次,一进HAL_GPIO_EXTI_IRQHandler就关闭中断,HAL_GPIO_EXTI_Callback依旧两次

使用特权

评论回复
14
数码小叶|  楼主 | 2020-6-23 09:13 | 只看该作者
sonicll 发表于 2020-6-23 08:50
你在EXTI4_15_IRQHandler里面先清中断标志看看,这里是中断最早执行的地方

醉了,这样居然真的可以达到效果,但是判断中断操作居然在清标志之后,不过好像也可以讲得通

使用特权

评论回复
15
labasi| | 2020-7-9 14:07 | 只看该作者
我印象中并不需要手动清除标志位啊

使用特权

评论回复
16
paotangsan| | 2020-7-9 14:07 | 只看该作者
用示波器看看实际上是不是产生了两个中断信号呢

使用特权

评论回复
17
renzheshengui| | 2020-7-9 14:07 | 只看该作者
没遇到过这个问题

使用特权

评论回复
18
wakayi| | 2020-7-9 14:08 | 只看该作者
帮楼主顶一下

使用特权

评论回复
19
wowu| | 2020-7-9 14:08 | 只看该作者
楼主解决问题了吗

使用特权

评论回复
评论
数码小叶 2020-7-9 15:59 回复TA
解决了 
20
数码小叶|  楼主 | 2020-7-9 16:01 | 只看该作者
paotangsan 发表于 2020-7-9 14:07
用示波器看看实际上是不是产生了两个中断信号呢

我是一进去就关中断了,根本原因是清中断时间不够

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

103

主题

2540

帖子

19

粉丝