Nucleo-L432KC的5通道ADC+DMA配置问题:无法进入HAL_ADC_ConvCpltCallback
排查Nucleo-L432KC ADC+DMA无法进入回调的核心要点
我之前跨STM32型号移植ADC+DMA时也踩过类似的坑,结合L432KC和F303RE的硬件差异,给你梳理几个高概率的排查方向:
1. 先核对硬件资源的本质差异
F303RE(64引脚)和L432KC(32引脚)的ADC/DMA资源配置区别很大,这往往是移植翻车的根源:
- L432KC只有1个ADC实例(ADC1),而F303RE有ADC1/2/3三个,你之前的代码会不会误引用了不存在的ADC实例?
- 务必查L432KC的参考手册核对DMA通道映射:L432的ADC1对应DMA1的通道1,而F303的ADC1可能绑定的是DMA2通道0,要是DMA通道配错了,根本没法触发传输完成中断。
2. 检查ADC初始化的细节偏差
- 通道可用性与序列配置:L432KC的引脚更少,有些在F303RE上能用的ADC通道,在L432上可能没引出或者复用功能不同。比如你配置的5个通道里,有没有引脚是L432不支持的?一定要对照开发板引脚图和芯片手册逐一确认。
- 扫描与连续模式必须开启:多通道转换必须打开
ADC_SCAN_ENABLE,同时要开启ADC_CONTINUOUS_CONV_MODE_ENABLE配合DMA的DMA_CIRCULAR_MODE(如果是连续采集场景),不然转换一次就停了,根本不会触发完成回调。 - 数据对齐方式:L432的ADC默认是12位右对齐,要是你之前F303用的是左对齐,移植后没修改的话,数据读取异常可能间接导致回调触发失败(这个概率低,但值得快速排查)。
3. DMA初始化的关键配置不能错
- 数据宽度匹配:ADC的转换结果存在16位寄存器里,所以DMA的
MemoryDataSize和PeriphDataSize必须都设为DMA_MDATAALIGN_HALFWORD,要是设成字节模式,传输会直接出错,不会触发完成中断。 - 内存增量模式要开启:多通道采集时,DMA必须开启
DMA_MEMORY_INCREMENT,不然所有通道的数据都会覆盖到同一个内存地址,DMA的传输完成标志也会异常。 - 中断优先级与使能:检查NVIC里DMA和ADC的中断优先级,有没有被其他高优先级中断抢占?同时要确保DMA的传输完成中断(
DMA_IT_TC)已经开启,没开的话肯定进不了回调。
4. 启动流程的顺序不能乱
必须按「启动DMA+ADC」的正确顺序来:调用HAL_ADC_Start_DMA()即可,不要先单独启动ADC再开DMA,否则DMA跟不上转换节奏,不会触发完成回调。另外还要检查代码里有没有误调用HAL_ADC_Stop_DMA()或者关闭外设时钟的逻辑。
5. 快速调试的小技巧
- 先在
HAL_ADC_IRQHandler()里加断点,看有没有进入中断服务函数:如果进了,说明是回调函数的问题——比如你重写的函数名是否完全一致?注意这个回调是弱定义的,必须严格写成void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc),参数或函数名错一个都不行。 - 如果没进IRQHandler,就直接查寄存器:看ADC的
SR寄存器里EOC(单通道转换完成)和EOS(序列转换完成)位有没有置位,再看DMA的ISR寄存器里TCIF(传输完成中断标志)有没有置位,这样能快速定位是「转换根本没发生」还是「DMA没触发中断」。
内容的提问来源于stack exchange,提问作者Soleil Anker-Baril
相关产品推荐
相关产品推荐

