-1

我正在尝试使用下降沿 EXTI 中断简单地打开带有按钮的 LED。不幸的是,LED 在没有触摸按钮的情况下闪烁,使用 gdb 进行调试也显示 ISR 被重复调用。我之前测试过 LED (PA5) 和 Button(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, [r2, #EXTI_IMR]

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

   tst   r1, #2
   ittt  ne
   ldrne r3, [r2, #EXTI_FTSR]
   orrne r3, r4
   strne r3, [r2, #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, r0, #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 上配置中断

我不太确定为什么中断不能正常工作,是否有设置它的步骤,我错过了?

编辑:我刚刚注意到一些奇怪的事情,LED 的闪烁仅在与 gdb 连接(通过 openocd)时发生,但如果我只是闪烁 .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
4

1 回答 1

0

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

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

于 2021-01-23T16:07:03.657 回答