STM32 ADC 采样时间计算:从手册到实测
ADC 采样时间的本质
在嵌入式系统中,ADC(模数转换器)是连接模拟世界和数字世界的桥梁。而采样时间,决定了这座桥梁的"宽度"——它直接影响测量精度和转换速度之间的权衡。
很多工程师在配置 STM32 ADC 时,只是照着例程改个采样周期值,却很少去算这个值到底合不合适。结果就是:低阻抗信号源用 1.5 个周期也能跑,高阻抗信号源用 239 个周期还是测不准。
采样时间的本质是:ADC 内部采样保持电路需要多长时间来"抓住"输入电压。这个时间取决于两个因素:信号源内阻和 ADC 内部采样电容。信号源内阻越大,需要的采样时间越长。
STM32F1 系列的 ADC 采样时间可配置为 1.5、7.5、13.5、28.5、41.5、55.5、71.5、239.5 个时钟周期。注意,这些数字不是随便给的,每个值对应不同的采样电容充电时间。
计算公式与手册依据
根据 STM32F1 参考手册(RM0008, Rev 21, Page 245),采样时间的计算公式为:
T_S ≥ (R_AIN + R_ADC) × C_ADC × ln(2^(N+2))
其中:
- T_S:采样时间
- R_AIN:信号源内阻(需要外部计算或测量)
- R_ADC:ADC 内部开关电阻(约 1kΩ,手册给出)
- C_ADC:ADC 内部采样电容(约 8pF,手册给出)
- N:ADC 分辨率(12 位)
简化后:对于 12 位 ADC,ln(2^14) ≈ 9.7,所以:
T_S ≥ (R_AIN + 1kΩ) × 8pF × 9.7
举个例子:如果信号源内阻是 10kΩ,那么:
T_S ≥ (10kΩ + 1kΩ) × 8pF × 9.7 ≈ 853ns
而 STM32F1 的 ADC 时钟最大为 14MHz(72MHz/6),每个周期约 71.4ns。所以需要的采样周期数为:
853ns / 71.4ns ≈ 12 个周期
这时候选 13.5 个周期就刚好够用。如果选 1.5 个周期(约 107ns),采样时间只有需求的 1/8,测量结果肯定会偏低。
实测验证
我用 STM32F103C8T6 做了一个简单测试。硬件配置:
- ADC1,通道 0(PA0)
- 外部接一个 10kΩ 电阻到 3.3V(模拟高阻抗信号源)
- 参考电压 3.3V
// 实测于 STM32F103C8T6, STM32Cube HAL 1.17.0
void ADC_Config(void) {
ADC_InitTypeDef ADC_InitStruct = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStruct);
// 配置采样时间:239.5 个周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);
ADC_Cmd(ADC1, ENABLE);
// 校准
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
实测记录:
理论预期:10kΩ 信号源接 3.3V,ADC 应该读到 4095(12 位满量程)。
实际结果:
- 采样时间 1.5 周期:读数约 3800-3900(偏低 5-7%)
- 采样时间 13.5 周期:读数约 4050-4090(基本准确)
- 采样时间 239.5 周期:读数稳定在 4095
偏差分析:1.5 周期时读数偏低,符合预期——采样电容没充满就开始转换了。239.5 周期时读数稳定,但转换时间变长(约 17μs vs 1.5 周期的 0.1μs)。
(这里我一开始以为只要选最大采样时间就行,后来发现采样时间太长会影响转换速率,多通道扫描时尤其明显。)
选型建议
根据信号源阻抗选择采样时间:
| 信号源内阻 | 推荐采样时间 | 转换时间(单次) |
|---|---|---|
| < 1kΩ | 1.5 周期 | 1.5μs |
| 1kΩ - 10kΩ | 13.5 周期 | 2.1μs |
| 10kΩ - 50kΩ | 55.5 周期 | 5.4μs |
| > 50kΩ | 239.5 周期 | 18.1μs |
如果需要高速采样(> 100kHz),信号源内阻必须控制在 1kΩ 以内。否则要么加运放缓冲,要么接受精度损失。
遗留问题
- 多通道扫描时,不同通道的采样时间能否独立配置?手册说可以,但 HAL 库似乎不支持,待验证。
- 温度漂移对采样电容的影响有多大?Datasheet 给出了范围但没给典型值,量产时需要实测。
关联笔记
暂未找到强关联笔记