用 STM32H723 做 ADC 多通道序列转换时,很多工程师习惯直接操作寄存器,结果遇到一个非常隐蔽的坑:单通道转换正常,多通道序列配置后直接写寄存器启动,ADC 完全不转换,JADSTART 置 1 也没反应,没有任何报错。
ST 官方 LAT1158 笔记一针见血:问题就出在ADC 使能后没有等待 ADRDY 就绪,直接启动注入组 / 规则组序列,导致 ADC 挂起。
资料获取:【应用笔记】LAT1154 LPUART 单线半双工通信过程中 stop 位与 start 位重叠的问题
1. 典型故障现象(完全一致就是同款问题)
- 芯片:STM32H723
- 配置:ADC 多通道序列转换
- 操作:直接寄存器使能并启动
ADC1->CR |= 0x01; // ADEN=1 使能ADC ADC1->CR |= 0x08; // JADSTART=1 启动注入组 - 结果:无转换、无 EOC、无中断、JADSTART 保持 1
- 但:单通道模式这样写正常工作
- 用 HAL 库函数
HAL_ADCEx_InjectedStart()正常
2. 根因:ADEN 之后必须等 ADRY=1,才能启动转换
H7 系列 ADC 有严格启动时序:
- 写 ADEN=1 使能 ADC
- 硬件需要 tsTAB 启动时间
- 硬件置位 ADRDY 表示 ADC 就绪
- 此时才能启动转换(JADSTART / ADSTART)
客户问题就是:使能 ADC 后立刻启动序列转换,ADC 还没准备好,直接拒绝执行。
单通道对时序不敏感,所以侥幸能跑。
3. 10 秒修复代码(寄存器正确流程)
// 1. 清除 ADRDY 标志
ADC1->ISR = 0x01;
// 2. 使能 ADC
ADC1->CR |= 0x01;
// 3. 等待 ADC 就绪(最关键!)
while((ADC1->ISR & 0x01) == 0);
// 4. 启动序列转换
ADC1->CR |= 0x08;
加一行 while 等待,多通道序列立刻正常转换。
4. 为什么 HAL 库没问题?
因为 HAL_ADCEx_InjectedStart() 内部已经帮你做了:
- 检查 ADEN
- 等待 ADRDY
- 检查状态
- 然后才启动转换
寄存器操作需要自己实现这套流程。
5. 工程师一句话总结
STM32H7 ADC 多通道序列启动三要素:
先使能 → 等 ADRDY → 再启动。
少一步,序列就卡死不动。
6. LAT1158 最终结论
- H7 ADC 序列转换依赖启动时序
- ADEN 之后必须等待 ADRDY=1
- 单通道不敏感,多通道必现
- 寄存器操作必须按手册流程
- 加 while 等待 ADRDY 即可根治
阅读全文
210