CASE / 01 · 问题定位
STM32C5 的 ADC 读数卡在 3568 不动:ADC1_IN7 双引脚 remap 的定位与验证
一块电源类控制板从某国产 Cortex-M4 MCU 移植到 STM32C531 后,起机约 100ms 即被过压保护关断。母线电压通道读数恒为 3568,对引脚接地毫无反应。根因是 C53x 的 ADC1_IN7 由 PA7、PB1 两个引脚共用,复位默认接 PA7,驱动没有改选 PB1。补 2 行寄存器配置后,在同族开发板上复验通过;客户量产板尚待复测。
适用范围
| 芯片 | STM32C53x / STM32C542(手册注明该 remap 位只存在于这两个系列) |
| 场景 | 用 PB1、PB0、PC5、PC4 做模拟输入,同时 PA7、PA6、PA5、PA2 另作他用 |
| 迁移来源 | 通道与引脚固定、没有 remap 机制的 MCU(本例为某国产 Cortex-M4) |
| 验证平台 | NUCLEO-C542RC 同族开发板预验证;客户 C531 板未复测 |
现象
- 受控出波测试中,起机约 100ms 后过压保护动作,PWM 关断。
- 母线电压通道(PB1)的 ADC 原始值恒为约 3568(12 位满量程 4095)。
- 把 PB1 直接接地、换探头加载,读数纹丝不动。
排查过程
- 读数对硬件操作免疫,先查软件。 真实引脚上的电压变了、读数不变,说明 ADC 采的根本不是这个引脚。所以先不动硬件,回头查通道配置。
- 读数不是随机漂移,而是有规律的残影。 3568 ≈ 前一通道读数的 87%,且稳定复现。形态像采样保持电容里残留的前一次电荷,而不是悬空噪声。
-
排除上下拉。
直接读 GPIOA 的
PUPDR寄存器,PA7 没有被上拉或下拉。 -
数据手册里同一个通道出现了两次。
DS15125 Rev 2 引脚表:PA7(第 40 页)和 PB1(第 41 页)的 Additional functions 列都写着
ADC1_IN7。 -
追到参考手册,找到选择寄存器。
RM0522 Rev 1 §12.5.4(第 363 页):
SBS_PMCR偏移 0x100,复位值 0x8000 0000;bit 3ADC1_IN7_REMAP,0 = IN7 接 PA7,1 = IN7 接 PB1。复位默认接 PA7。 -
当场实证。
调试器在线把
SBS_PMCRbit 3 写 1,母线通道读数立即从 3568 变为 1(此时 PB1 被探头拉地)。
根因
- 源平台的 ADC 通道和引脚是一一固定的,驱动里从来不需要选引脚;STM32C53x/542 新增了 IN7 的双引脚选择。
- 移植后的驱动没有写
ADC1_IN7_REMAP,IN7 停在复位默认的 PA7 上。 - 本设计中 PA7 是 USART1_RX(复用功能模式),ADC 通路没有接到这个引脚。IN7 实际上没有接到任何被测信号,采到的是前一通道残留的电荷,恒定偏高,于是触发过压保护。
「采样电容残留前一通道电荷」是对 87% 比例的机理解释,属于推断:它与实测比例、对接地免疫这两个现象吻合,但手册没有给出这个数值。
处理
在 ADC 初始化里加 2 行:先开 SBS 时钟,再置 remap 位。
LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_SBS);
SBS->PMCR |= SBS_PMCR_ADC1_IN7_REMAP; /* IN7 → PB1,RM0522 §12.5.4 */
连带检查同一寄存器的其余三位(RM0522 第 363–364 页):IN6(PA6/PB0)、IN5(PA5/PC5)、IN2(PA2/PC4)的默认引脚与本设计一致,不需要改。
验证结果与限制
| 项 | 结果 | 状态 |
|---|---|---|
| 在线写 remap 位 | 读数 3568 → 1,与探头拉地一致 | 已实测 |
| 重新编译烧录后 PB1 接地 | 读数 0,过压保护不再误动作 | 已实测 |
| 修复后受控出波测试 | 预设的七项检查全部通过 | 已实测 |
| 客户 STM32C531 量产板 | — | 未复测 |
「已实测」均在 NUCLEO-C542RC 同族开发板上完成。没有覆盖的:真实母线电压下的采样精度与标定、量产板上的长期运行。
可复用的经验
- 数据手册里同一个 ADC 通道出现在两个引脚上,就一定有选择寄存器,要追到参考手册落实默认值,不能只记「IN7 = PB1」半句。
- 读数对硬件操作免疫,是软件侧的强信号。先查通道、引脚、选择寄存器,再考虑换线、重焊。
- DMA 多通道搬运要逐槽位核对。只锚定前几个槽位,后面槽位的残影会被误读成悬空漂移。
结论—依据—验证状态对照
| # | 结论 | 依据 | 类型 |
|---|---|---|---|
| 1 | PA7、PB1 共用 ADC1_IN7 | DS15125 Rev 2,第 40 页(PA7)、第 41 页(PB1),Additional functions 列 | 手册原文 |
| 2 | 复位默认 IN7 接 PA7,bit 3 置 1 才接 PB1 | RM0522 Rev 1 §12.5.4 第 363 页:SBS_PMCR 复位值 0x8000 0000,bit 3 定义 | 手册原文 |
| 3 | 该位只存在于 STM32C53x/542 | 同上,bit 3 的 Note | 手册原文 |
| 4 | IN6/IN5/IN2 另有同类 remap 位 | RM0522 Rev 1 第 363–364 页,bit 2/1/0 | 手册原文 |
| 5 | 漏写 remap 导致读数恒定、触发过压 | 在线写位后读数 3568 → 1;修复后接地读 0 | 实测 |
| 6 | 3568 是前一通道电荷残留 | 读数 ≈ 前一通道 × 87%,对接地免疫 | 推断 |
| 7 | 修复在客户 C531 板上同样有效 | 同一寄存器位适用于 C53x/542 | 推断 待复测 |
「实测」指在 NUCLEO-C542RC 同族开发板上完成;手册页码按 PDF 页眉页码。
遇到类似问题
「读数不随输入变化」的 ADC 问题,发来这几项能更快收敛:芯片型号与封装、用到的通道与引脚、那个引脚上还配了什么复用功能、读数随输入是否变化。