我试图简单地把一个LED与一个按钮,使用下降沿EXTI中断。不幸的是,LED在没有触摸按钮的情况下 Flink ,用gdb调试也显示,ISR被重复调用。当我测试LED(PA 5)和按钮(PC 13:输入模式带上拉电阻)之前,它们的配置是正确的。
所以我认为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
从Reset_Handler
调用ConfigureEXTI
:
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的 Flink 只发生在连接gdb时(通过openocd),但如果我只是 Flink .elf,LED不会 Flink (按钮不工作)。用于刷新/调试的命令:
$ 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
1条答案
按热度按时间nafvub8i1#
PC 13:带上拉电阻的输入模式
不要使用内部上拉电阻,这些电阻(通常)太高。使用1 k-10 k范围内的外部上拉。