【问题标题】:EXTI Interrupt gets thrown non-stop (stm32f1)EXTI 中断被不停地抛出(stm32f1)
【发布时间】:2020-11-09 18:46:54
【问题描述】:

我正在尝试使用下降沿 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

【问题讨论】:

  • 您是否正确清除了 isr 中的中断,使其不会重新触发?早在实际允许中断进入内核之前,您是否通过轮询解决了所有这些问题?轮询外设看看如何使中断状态改变?下一个项目如何清除外设中的中断状态?下一个项目看到 nvic 中的中断了吗?下一个项目看到 nvic 中的中断清除了吗?接下来启用 nvic 中的中断(但不是核心)?看到变化,清楚,然后最后写isr,让核心看到
  • 这不是 gdb 无论如何都会提供帮助的东西......这就像一个蓝色药丸(stm32f103),因此例如 openocd 而不是核板,您可以选择只复制一个二进制文件,拖放...
  • 程序是否...与闪存 write_image 擦除 main.elf 做同样的事情? (well reset halt, flash write_image erase main.elf, reset)
  • 你解决了按钮的去抖动问题吗?

标签: assembly interrupt cortex-m3 thumb stm32f1


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 2017-11-12
    • 2017-04-29
    • 2022-06-11
    • 1970-01-01
    • 2021-07-11
    • 2020-08-11
    相关资源
    最近更新 更多