使用EXTI线进行软件中断

4

我正在使用STM32F4,希望生成一个软件中断。 问题是在中断处理程序中如何知道中断是由软件还是与EXTI线连接的引脚引起的?


不太清楚你的问题。你是按照这里描述的方式触发了EXTI中断吗:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Cihhbccd.html? - Clifford
这里有一个很好的问题,但对于不熟悉STM32的人来说,需要进行一些研究才能理解你在问什么。你不应该期望任何人去做这种努力,而应该包含代码以说明你正在做什么。目前这个问题正在吸引着负面评价和关闭投票,但通过一些澄清,它可能会成为一个有用和有趣的问题。 - Clifford
这里被询问的内容似乎很明显。我投票支持保持开放。 - Owl
1个回答

5

在STM32F4上,有两种生成软件中断的方法。

  • 一种是通用的Cortex-M4方法,通过写入软件触发中断寄存器(STIR)

  • 另一种是特定于STM32 EXTI的方法,通过写入外部中断软件触发事件寄存器(EXTI_SWIER)

我认为在第一种方法中,中断不可区分,因为STIR是一个只写寄存器。但是EXTI_SWIER是可读可写的,写入触发中断的位直到显式写入EXTI_PR中相应的位之前不会被清除。因此,仅通过读取EXTI_SWIER就可以确定中断是否为软件触发。

void EXTI0_IRQHandler(void) 
{
    // Detect SWI
    bool is_swi = (EXTI->SWIER & 0x00000001u) != 0 ;       

    // Clear interrupt flag
    EXTI_ClearITPendingBit(EXTI_Line0);

    if ( is_swi )
    {
        ...
    }
    else
    {
        ...
    }
}

对于共享单个中断的EXTI线路,您首先需要通过检查PR寄存器来确定活动线路:

void EXTI15_10_IRQn( void )
{
    for( uint32_t exti = 10; exti < 15; exti++ )
    {
        bool is_swi = false ;
        if( EXTI_GetFlagStatus( exti ) == SET )
        {
            is_swi = (EXTI->SWIER & (0x1u << exti)) != 0 ;

            // Clear interrupt flag
            EXTI_ClearITPendingBit( exti ) ;

            if ( is_swi )
            {
                ...
            }
            else
            {
                ...
            }
        }
    }
}

非常感谢您提供详细的答案。很抱歉问题表述不够清晰。 - Samer.M
@Samer.M:不用谢;你仍然应该编辑问题以解决这些问题。 - Clifford
很遗憾,你的说法“EXTI_SWIER是读写的,写入触发中断的位直到在EXTI_PR中对应的位被显式写入后才会被清除”是不正确的。任何对EXTI_SWIER的写入都将根据所写入的每个位设置或清除:1位不会一直保持为1,直到通过写入EXTI_PR将其清零。 - John Burger
@JohnBurger:正如文档所述_"如果在EXTI_IMR寄存器的x行启用了中断,当SWIERx位被设置为'0'时写入'1'会在EXTI_PR寄存器中设置相应的挂起位,从而导致中断请求生成。通过清除EXTI_PR中的相应位(写入1到该位)来清除此位。"_ 我建议不要信任任何"未记录"的行为或以任何方式使用它,除非按照文档进行。我不确定你的观点在实践中是否有任何相关性。中断发生时,SWIER被设置为1-重置方式并不重要。 - Clifford
@JohnBurger 那个问题的解决方案是使用读取/修改/写入,或者更好地使用原子位带写入。 - Clifford
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接