首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果多个引脚共享同一个中断,我如何知道哪个引脚在触发中断?

如果多个引脚共享同一个中断,我如何知道哪个引脚在触发中断?
EN

Stack Overflow用户
提问于 2022-05-15 08:30:44
回答 3查看 506关注 0票数 1

我正在用STM323 ide编写代码,并使用STM32f303re核板。我将pin PA7配置为一个中断,但是它没有自己的中断处理程序,就像我以前使用过的开发板一样。

如您所见,这一个中断处理程序处理来自引脚9-5的中断,因此,如果这些引脚中的任何一个被触发,它们将调用相同的中断。我需要能够执行不同的功能,取决于哪个引脚被触发。有没有办法知道是哪个特定的引脚导致了中断?

EN

回答 3

Stack Overflow用户

发布于 2022-05-15 10:38:10

您可以使用EXTI_GetITStatus来检查导致中断的行。

代码语言:javascript
运行
复制
 /* Handle PA7 interrupt */
void EXTI9_5_IRQHandler(void) {
    /* Make sure that interrupt flag is set */
    if (EXTI_GetITStatus(EXTI_Line7) != RESET) {
        /* Do your stuff when PA7 is changed */
        
        
        /* Clear interrupt flag */
        EXTI_ClearITPendingBit(EXTI_Line7);
    }
}

以后别忘了清除旗子。

票数 3
EN

Stack Overflow用户

发布于 2022-05-15 17:33:55

对于多个引脚共享中断的情况,当中断触发时,您需要检查哪个引脚具体导致中断。与pin 1中断不同,中断本身意味着它是pin 1,您可以立即处理它,在这种情况下,中断意味着“它要么是pin 5,要么是6,要么是7,或者是8,或9",因此在ISR中,您需要检查”它是引脚5?还是6?“

我认为这是一个直接查看EXTI外围设备寄存器的好机会。

如果您在第299页第14.3.6节中打开你的单片机参考手册,您可以看到这个EXTI_PR1寄存器保存了第0..31行的挂起位。这些bits被标记为rc_w1,从文档一开始就表示(参考手册,第46页):

阅读/清除(rc_w1) 软件可以通过写1来读取和清除这个位。写入‘0’对位值没有任何影响。

因此,逻辑如下:如果发生了第5..9行的中断,则需要检查寄存器中的特定位设置为1,然后在那里写入1来重置它。这将清除旗子。

代码语言:javascript
运行
复制
void EXTI9_5_IRQHandler(void)
{
 if(EXTI_PR1 & (1U<<5U)) //check if it's line 5, returns 0 if PR5 is 0, otherwise returns non-zero, which is true
 {
   EXTI_PR1 |= (1U<<5U); //write 1 to that bit to clear it so interrupt doesn't fire again once ISR is finished
   do_stuff_if_it's_pin5();
 }

}

或者,与1U<<5U不同,您应该能够使用EXTI_PR1_PR5,因此代码看起来更容易阅读,如下所示:

代码语言:javascript
运行
复制
void EXTI9_5_IRQHandler(void)
    {
     if(EXTI_PR1 & EXTI_PR1_PR5) //check if it's line 5, returns 0 if PR5 is 0, otherwise returns non-zero, which is true
     {
       EXTI_PR1 |= EXTI_PR1_PR5; //write 1 to that bit to clear it so interrupt doesn't fire again once ISR is finished
       do_stuff_if_it's_pin5();
     }
    
    }

这就是@Lime7 7提供的函数在幕后所做的事情,我怀疑(无法检查,但这是合乎逻辑的)。

我没有那个微控制器来测试它,但它应该能工作。

票数 1
EN

Stack Overflow用户

发布于 2022-05-16 01:47:35

其他答案已经覆盖了中断标志。我将添加一些有关CubeMX和HAL的信息,因为看起来您正在使用它们。

在CubeMX中启用GPIO中断时,代码生成器将在适当的IRQ处理函数中添加一行。启用多个中断时,生成的代码如下所示(注释已删除):

代码语言:javascript
运行
复制
void EXTI9_5_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
}

HAL_GPIO_EXTI_IRQHandler()函数检查给定引脚的中断状态,并在设置标志时调用HAL_GPIO_EXTI_Callback()函数。

代码语言:javascript
运行
复制
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流中,通常不直接在IRQ处理程序中编写代码,而是实现HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)函数。触发中断的引脚是为了方便您而提供的参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72246688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档