【发布时间】: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