摘要: 我已将 GPIO 配置为中断。我可以从所有寄存器中看到它似乎正在触发,但我的中断例程从未被调用。
详细信息: 我使用的是 Nucleo F446 板,文档指定 PC13 应该是按钮的输入。我想在发生这种情况时触发中断(我知道这不是处理按钮的最佳方式;我在使用更复杂的系统时遇到了问题,并将其简化为这个简化的示例)。我在裸机上执行此操作,而不使用任何现有库。
PC13进入EXTI13:
我看到这是微控制器参考手册中的中断#40:
我正在按如下方式配置微控制器(为简单起见,此处使用伪 C):
为 GPIOC 模块 SYSCFG 启用时钟
RCC_AHB1ENR |= GPIOC_EN RCC_APB2EN |= SYSCFG_EN
为 GPIO C13 启用外部中断(默认为输入)
SYSCFG_EXTICR4 |= (PCx << 4)
设置中断屏蔽、事件屏蔽和上升触发选择寄存器的引脚 13:
EXTI_IMR |= 1 << 13 EXTI_EMR |= 1 << 13 EXTI_RTSR |= 1 << 13
启用 IRQ 40
NVIC_ISER1 |= 1 << 8
设置中断向量(这里是反汇编)
08000000 <_reset-0x124>: ... 80000e0: 08000621 .word 0x08000621 08000620 <exti15_10_handler>: 8000620: 4906 ldr r1, [pc, #24] ; (800063c <exti15_10_handler+0x1c>)
我有一个循环中的主代码,将一些寄存器值打印到串行端口,稍后我将对其进行描述。我已经实现了 exti15_10_handler 来打开一个 LED 并进入一个无限循环,所以我应该知道它什么时候被调用,因为它也会停止打印。当我按下并释放按钮时,我看到以下内容:
- 在 GPIOC_IDR(GPIO 输入寄存器)中,我可以看到第 13 位发生了变化,这告诉我 GPIO 模块正在工作。
- 在 EXTI_PR(外部中断挂起)中,我看到第 13 位的值从 0 切换到 1 并保持在那里。
- 在 NVIC_ISPR1(中断设置挂起)中,第 8 位(对应于中断 40)从 0 切换到 1 并停留在那里。
- 但是,NVIC_IABR0(中断有效位寄存器)不会改变。
- 没有调用中断,因为我看到 LED 没有变化并且电路板没有挂起。
我确定我忘了启用某些东西,但是在仔细阅读了参考手册和一堆代码示例之后,我只是没有看到它。我确实尝试了以下方法:
asm volatile ("cpsie i" : : : "memory");
设置中断标志(我认为应该已经打开了)。我很好奇这对任何人来说是否熟悉。