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

如您所见,这一个中断处理程序处理来自引脚9-5的中断,因此,如果这些引脚中的任何一个被触发,它们将调用相同的中断。我需要能够执行不同的功能,取决于哪个引脚被触发。有没有办法知道是哪个特定的引脚导致了中断?
发布于 2022-05-15 10:38:10
您可以使用EXTI_GetITStatus来检查导致中断的行。
/* 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);
}
}以后别忘了清除旗子。
发布于 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来重置它。这将清除旗子。
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,因此代码看起来更容易阅读,如下所示:
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提供的函数在幕后所做的事情,我怀疑(无法检查,但这是合乎逻辑的)。
我没有那个微控制器来测试它,但它应该能工作。
发布于 2022-05-16 01:47:35
其他答案已经覆盖了中断标志。我将添加一些有关CubeMX和HAL的信息,因为看起来您正在使用它们。
在CubeMX中启用GPIO中断时,代码生成器将在适当的IRQ处理函数中添加一行。启用多个中断时,生成的代码如下所示(注释已删除):
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()函数。
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)函数。触发中断的引脚是为了方便您而提供的参数。
https://stackoverflow.com/questions/72246688
复制相似问题