MCU:STM32F407VET6
先说结论,调试时跳转到启动文件里的死循环,只要不是硬件错误中断,那么多半是因为中断处理函数没有定义导致的。
【历程】
今天在测试最小单片机系统时,定义了一个按键处理,依赖的是外部中断线0。配置好外部中断回调后,能正常初始化运行。但只要按下按键就会进入看门狗中断,然后死循环。可问题是我没有设置看门狗,这是怎么一回事?
全局搜索看门狗中断,进入map文件可以看到,这个看门狗中断和其他中断一样,并没有定义。也就是说调试窗口显示进入看门狗中断可能只是和其他重名了,毕竟指向的都是同一个地址
去搜索HAL外部中断,发现也没定义?!那么我定义的中断回调岂不是无根之萍?
那么只好直接搜索到最底层——中断向量表,可以看到没有定义!
这时才发觉我工程中并非是由STM32CubeMX直接生成的,那么直接把CubeMX生成的外部中断初始化代码复制到代码里是会出问题的(实际上是复制少了)。 既然如此,那么便定义一个外部中断。这里没有使用外部中断回调,因为它只是一只最小单片机系统,不需要太多功能。如下图所示,按下按键后顺利进入测试的程序了万幸的是,没有该死的按键抖动
【总结】
进入硬件错误中断,那肯定是发生了硬件错误。但进入Default中断十有八九是没有定义中断处理导致的,因为启动文件里的中断向量表默认指向Default_Handler。
如果你使用的是HAL,那么当发生了这种问题后,可以用CubeMX生成初始化代码,重新配置。或者根据CubeMX生成的代码,来观察哪些宏要取消注释,哪些函数要调用。或者不管什么中断回调,硬上中断向量。
硬上中断向量时要注意,如果你的工程含有C++,那么定义这个中断向量时,一定要用extern "C"包起来,不然会被C++编译器链接成别的符号导致找不到这个函数。中断回调则不需要
如果是使用CubeMX生成含中断的初始化代码,那么搬移代码时,需要把stm32f4xx_it.c中定义的中断处理例程也要迁移过来。下图中CubeMX工程名为CubeTest,以ADC中断为例,把这句复制到工程里即可。需要注意的是这个是C函数而非C++函数,否则识别不到
【示例工程】
ichliebedich-DaCapo/STM32F407VET6: stm32f407vet6