EXTI中断不停地抛出STM32F1

问题描述

我正在尝试使用下降沿EXTI中断简单地通过按钮打开LED。不幸的是,LED闪烁而不触摸按钮,使用gdb进行调试还显示,ISR被反复调用。 在我之前测试过LED(PA5)和按钮(PC13:带上拉电阻的输入模式)时,它们的配置是正确的。

所以我认为EXTI中断配置一定有问题。

使用以下功能调用main之前,已在组装中完成配置:

@ r0 = EXTI-line (0 .. 15)
@ r1 = Trigger Seleetion,LSBs (... : b1 : b0),@        b0 = 1 -> Rising Trigger enabled,@        b1 = 1 -> Falling Trigger enabled 
.global  ConfigureEXTI
.type    ConfigureEXTI,%function
ConfigureEXTI:
   push  { r4,lr } 

   @ register value for bit $r0 in r4
   mov   r4,#1
   lsl   r4,r0
   ldr   r2,=EXTI

   ldr   r3,[r2,#EXTI_IMR]
   orr   r3,r4
   str   r3,#EXTI_IMR]

   tst   r1,#1
   ittt  ne 
   ldrne r3,#EXTI_RTSR]
   orrne r3,r4
   strne r3,#EXTI_RTSR]

   tst   r1,#2
   ittt  ne
   ldrne r3,#EXTI_FTSR]
   orrne r3,#EXTI_FTSR]

   @ First 4 EXTI lines with own ISR
   cmp   r0,#4
   bhi   1f

   add   r0,#6
   b     2f
1: 
   cmp   r0,#9
   ite   ls 
   movls r0,#23     @ combined ISR for EXTI 5-9 (23) and EXTI 10-15 (40)
   movhi r0,#40
2:
   bl   EnableIRQ

   pop   { r4,pc }
.ltorg

EnableIRQ使用以下代码在NVIC_ISER1寄存器中启用中断:

@ r0 = IRQ Number
.global  EnableIRQ
.type    EnableIRQ,%function
EnableIRQ:
   ldr   r1,=NVIC_ISER0

   movs  r2,#1
   and   r3,r0,#0x1f  @ r3 <- r0 mod 32
   lsls  r2,r2,r3

   @ calculating n = r0/32 to choose register NVIC_ISERn
   lsrs  r3,#5
   lsls  r3,r3,#2

   str   r2,[r1,r3]

   bx    lr 
.ltorg
ConfigureEXTI调用

Reset_Handler

Reset_Handler:
   @ ...
   mov   r0,#13
   mov   r1,#2
   bl    ConfigureEXTI

   b     main

main仅包含一个无限循环while(1) __WFI();

ISR用C实现:

void  EXTI15_10_IRQHandler(void)
{
   if((EXTI->PR & (1 << BUTTON_PIN)))
   {
      GPIOA->ODR ^= (1 << LED_PIN);  
      EXTI->PR |= (1 << BUTTON_PIN);
   }
}

因此,我正在执行提取参考手册的步骤:

  • 编程触发寄存器EXTI_RTSR和EXTI_FTSR
  • 在EXTI_IMR中启用中断请求
  • 在NVIC上配置中断

我不太确定为什么中断无法正常运行,我错过了设置它的步骤吗?

编辑:我只是注意到有些奇怪,仅当与gdb连接(通过openocd)时,LED才发生闪烁,但是如果我只是闪烁.elf,则led不会闪烁(该按钮仍然无法工作) )。 用于刷新/调试的命令:

$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c "program 
main.elf verify reset exit"

或调试

$ openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg
$ arm-none-eabi-gdb main.elf
(gdb) target remote :3333

解决方法

PC13:带上拉电阻的输入模式

不要使用内部上拉,这些(通常)电阻太高。使用 1k-10k 范围内的外部上拉。