0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

聊聊一个STM32中断处理问题

茶话MCU 来源:茶话MCU 作者:茶话MCU 2023-03-22 09:06 次阅读

先看一段代码:

while(1)

{

if(EXTI_Sign==1)

{

HAL_Delay(Period);

HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);

HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);

EXTI_Sign=0;

。。。。。。

}

}

有人使用STM32G0系列的芯片开发产品,有段功能测试验证代码如上所示,相同的函数必须调用2次才能正常运行,调用2次倒也罢了,关键是必须!颇为纳闷。

这里开启了PA3的外部中断功能,上下沿均可触发。PA3接收外来报警信号,类似于烟感报警器。报警信号是一串脉冲信号,报警信号过来时存在多次抖动问题。客户想了个方法消抖,只要报警端口有电平变化就触发中断然后把中断Disable,并设置报警标志再回到主程序。

主程序里识别到报警有效标志后延时几分钟再Enable刚才Disable掉的外部中断。但是,他发现再次使能外部中断时需要连续两次调用使能中断的代码才可以响应新的报警信号。【此处文字依据反馈者的文字描述组织而成】

下面MX_GPIO_Init(void)是经CubeMx配置后自动生成的,里面有EXTI相关NVIC配置。相关代码如下:

static void MX_GPIO_Init(void)


{


  GPIO_InitTypeDef GPIO_InitStruct = {0};


/* GPIO Ports Clock Enable */


  __HAL_RCC_GPIOA_CLK_ENABLE();


  __HAL_RCC_GPIOB_CLK_ENABLE();


    。。。。。。


/*Configure GPIO pin : PA3 */


  GPIO_InitStruct.Pin = GPIO_PIN_3;


  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;


  GPIO_InitStruct.Pull = GPIO_PULLUP;


  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/


  HAL_NVIC_SetPriority(EXTI2_3_IRQn, 0, 0);


  HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);


}




基于上沿触发的中断服务程序如下[基于下沿触发的此处省略】:
EXTI ISR():
{
__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_PIN_3);//清中断申请标志;


HAL_NVIC_DisableIRQ(EXTI2_3_IRQn);//关闭中断响应


EXIT_Sign=1;//表示收到报警信号
}


主循环代码像下面书写才能让程序正常运行:【略去了其它代码】


while (1)
  {
    if(EXTI_Sign ==1)
    {
    HAL_Delay(Period);


    MX_GPIO_Init();//客户无意中发现加这句有用


   HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);


   EXTI_Sign =0;
    。。。。。。
    }
}



现在的疑问是在EXTI中断服务程序运行HAL_NVIC_DisableIRQ(EXTI2_3_IRQn)后,到主循环代码里再次使能外部中断时,为何还要额外运行一次MX_GPIO_Init()函数才能让程序正常运行。最终发现运行该函数的实质就是将HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)多运行一次。

换句话说,上面的主循环代码要改成下面样子才可以让程序正常运行:

while(1)

{

if(EXTI_Sign==1)

{//报警有效,即发生过报警时,代码进到这里。

HAL_Delay(Period);

HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);//1

HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);//2

EXTI_Sign=0; //清除报警标志,准备监测新的警情

。。。。。。

}

}

说到底,问题就是主循环里为何要两次重复运行HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)函数后才能响应新的报警信号呢?

可以肯定,理论上讲,开启某个中断响应无须2次运行相关函数。我们来一起找找原因。为了便于查看代码,我把中断服务程序和主程序代码截图放在一起。

348cf5ca-c844-11ed-bfe3-dac502259ad0.png

34a6f79a-c844-11ed-bfe3-dac502259ad0.png

在中断服务程序里就是清除中断请求标志,关闭PA3的外部中断响应,并设置警情标志EXTI_Sign为1。

这里有没有问题呢?

他使用的HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)函数,关闭的是内核对该中断请求的响应,尽管他刚才在进中断时做外部中断请求标志的清零,但并不能保证他这个清零操作之后不会再产生外部中断请求。事实上,结合目前的使用场景,由于报警信号是一串跳变脉冲,即使一进中断就先做了个中断请求标志的清零,在中断退出甚至还未完全退出时大概率还会产生新的中断请求,但又由于他在中断服务程序里把中断响应关闭了,中断不能得到及时响应,请求只能悬着【Pending】跟随程序来到主循环。

主循环代码首先检查报警标志是否生效,生效则进入循环体,先静静地歇会儿【HAL_Delay(Period)】,让刚才的报警信号完全消停下来,然后再调用第一个HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)函数打开中断响应。这下可好,刚才候着的中断请求得到响应机会了,则马上去执行中断服务程序。这次在中断服务程序里的操作跟上次完全一样,即在中断服务程序里,又调用中断响应关闭函数,做了跟刚才主循环里第一个HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)函数完全相反的功能。即到这个点的时候,中断响应被关闭了。

如果中断返回后没有使用第2句HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)函数打开中断响应,而只是执行那句清零报警标志然后退出循环体。由于中断响应已经关闭,不管外部怎么报警都不会得到响应,报警标志也就永远不会被置1,这样主循环体也进不了内循环来开启中断响应。

如果有了第2句HAL_NVIC_EnableIRQ(EXTI2_3_IRQn)函数在循环体内,它就可以扭转刚才在中断服务程序里关闭外部中断响应的局面,即把它扳回来。这样的话功能上至少能正常运转了。

原因基本就大致这么回事。基于现有代码写法,如何破除这个连写2次的搞法呢。其实,我们只需要在主循环体内开启外部中断响应的函数前,延时等待函数之后加上对相关中断请求标志位的清零即可解决当前困惑。

比如像下面这样【其中DSB是个数据同步隔离指令,保障它前面的指令执行完毕后才执行它后面的】,在主循环内开启中断响应前,先做中断请求标志的清零。

while(1)

{

if(EXTI_Sign==1)

{

HAL_Delay(Period);

__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_PIN_3); __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_PIN_3);

__DSB();

HAL_NVIC_EnableIRQ(EXTI2_3_IRQn);

EXTI_Sign=0;

。。。。。。

}

}

OK,本话题就聊到这里,愿君有所获。类似问题不论STM32新手还是老手都可能不期而遇,祝君好运!

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2265

    文章

    10859

    浏览量

    354537
  • 中断
    +关注

    关注

    5

    文章

    895

    浏览量

    41366
  • 程序
    +关注

    关注

    116

    文章

    3769

    浏览量

    80797
  • 函数
    +关注

    关注

    3

    文章

    4299

    浏览量

    62354
  • 代码
    +关注

    关注

    30

    文章

    4733

    浏览量

    68288

原文标题:聊聊一个STM32中断处理问题

文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32中断优先级和开关总中断教程

    STM32中断优先级和开关总中断 教程
    发表于 11-23 18:03 0次下载

    STM32中断管理函数

    STM32中断管理函数,感兴趣的小伙伴们可以瞧瞧。
    发表于 11-02 19:13 15次下载

    中断是什么?STM32中断系统介绍和中断配置步骤资料免费下载

    本文档的主要内容详细介绍的是中断是什么?STM32中断系统介绍和中断配置步骤资料免费下载。
    发表于 10-11 08:00 5次下载
    <b class='flag-5'>中断</b>是什么?<b class='flag-5'>STM32</b><b class='flag-5'>中断</b>系统介绍和<b class='flag-5'>中断</b>配置步骤资料免费下载

    STM32的Cortex-M3中断异常处理

    STM32处理器中有43可屏蔽中断通道(不包含 16 Cortex?-M3的中断线)。共设
    发表于 11-16 15:35 8112次阅读
    <b class='flag-5'>STM32</b>的Cortex-M3<b class='flag-5'>中断</b>异常<b class='flag-5'>处理</b>

    STM32中断及FreeRTOS中断优先级配置

    STM32中断,及FreeRTOS中断优先级配置
    的头像 发表于 03-04 11:45 8805次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>中断</b>及FreeRTOS<b class='flag-5'>中断</b>优先级配置

    STM32关全局中断的方法 STM32中断类型

    STM32中断类型: 系统异常:内核水平 10 外部中断:外设水平 60 STM32关全
    的头像 发表于 07-22 10:52 2.8w次阅读

    STM32中断与DMA通信编程

    学习stm32中断、DMA通信原理和编程方法。使用stm32tubemx和HAL库分别完成以下编程练习:(1)用stm32F103核心板的GPIOA端
    发表于 11-23 17:51 12次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>中断</b>与DMA通信编程

    stm32f103中断总结很详细

    stm32f103中断总结很详细
    发表于 11-24 17:06 28次下载
    <b class='flag-5'>stm32</b>f103<b class='flag-5'>中断</b>总结很详细

    STM32中断与DMA通信编程

    学习stm32中断、DMA通信原理和编程方法。使用stm32tubemx和HAL库分别完成以下编程练习:(1)用stm32F103核心板的GPIOA端
    发表于 11-26 10:21 3次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>中断</b>与DMA通信编程

    STM32中断与DMA通信编程

    学习stm32中断、DMA通信原理和编程方法。使用stm32tubemx和HAL库分别完成以下编程练习:(1)用stm32F103核心板的GPIOA端
    发表于 11-26 19:21 11次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>中断</b>与DMA通信编程

    STM32中断系统的基本概念

    STM32中断系统基本概念、日常生活中断*图片来源网络二、处理
    发表于 01-14 14:57 0次下载
    <b class='flag-5'>STM32</b><b class='flag-5'>中断</b>系统的基本概念

    stm32中断初识与实践(上)

    stm32中断的讲解我分为两部分,即两篇文章,上半部分做一个总结性的概览,有初步认识,下半部分会通过
    发表于 02-11 15:26 4次下载
    <b class='flag-5'>stm32</b><b class='flag-5'>中断</b>初识与实践(上)

    STM32中断系统的工作流程

    管理核心的STM32中断系统有初步的了解,明白中断些基本概念以及
    的头像 发表于 06-22 09:17 2436次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>中断</b>系统的工作流程

    为什么有些STM32中断没有子优先级?

    看到交流群在讨论关于【关于STM32中断优先级的话题】,其中就有小伙伴提到:为什么有些STM32中断
    的头像 发表于 10-17 15:50 797次阅读
    为什么有些<b class='flag-5'>STM32</b><b class='flag-5'>中断</b>没有子优先级?

    stm32中断怎么处理

    STM32款非常强大的微控制器系列,具有丰富的外设和功能。中断STM32非常重要的部分,能够帮助我们提高系统的响应速度和效率。本文将
    的头像 发表于 01-02 17:35 2433次阅读