摘要:MCU 内部温度传感器读数偏差大?不是公式错了,是你没做 VREFINT 校准。本文解析 ADC 内部基准的波动原理,给出工程级的校准方法。
一、问题描述(现象)
**室温 25°C,ADC 算出来只有 18°C 或飙到 35°C;
换个板子,温度值又变了。**
很多工程师的处理方式是:
调整公式里的斜率参数。
增加软件滤波。
认为是芯片个体差异,接受误差。
二、原理分析
1. 物理模型
内部温度传感器本质上是一个 随温度变化的二极管电压。
Temperature ∝ (Vsense – V25) / Avg_slope
但问题在于:Vsense 的测量依赖于 ADC 的参考电压。
2. 核心参数
绝大多数 MCU 的 ADC 参考源是 VDDA。
|
Vsense |
传感器输出电压 |
|
VREF |
ADC 参考电压(通常为 VDDA) |
|
ADC_Value |
Vsense / VREF * 4096 |
3. 反直觉真相
温度不准,往往不是传感器的问题,而是 VDDA 在飘。
如果你的板子 VDDA 不是精准的 3.300V,直接用公式算出来的温度一定是错的。
三、工程级解决方案
方案 1:使用 VREFINT 进行比例校准(首选)
MCU 内部通常有一个 VREFINT(内部基准电压),约 1.2V。
原理:
既然 VDDA 会飘,那我们用 VREFINT 作为标尺,反推出当前的 VDDA。
计算公式:
Actual_VDDA = 3.3 * VREFINT_CAL / ADC_VREFINT
Actual_Temp = f(Actual_VDDA, ADC_Temp)
方案 2:软件同步采样
不要只采温度,要同时采 VREFINT。
// 伪代码
ADC_Start(TEMP_CHANNEL);
temp_val = ADC_GetValue();
ADC_Start(VREFINT_CHANNEL);
vref_val = ADC_GetValue();
// 校准
real_vdda = 3.3 * VREFINT_CAL / vref_val;
real_temp = CalculateTemp(real_vdda, temp_val);
方案 3:利用出厂校准值
Datasheet 里通常会给出 TS_CAL1 和 TS_CAL2。
注意:
-
这两个值是 在特定 VDDA(通常是 3.3V) 下测得的。
-
如果你的 VDDA 不是 3.3V,必须先用 VREFINT 校准。
四、选型避坑建议
VREFINT 稳定性:内部基准温漂虽小,但长期看仍有误差。
采样时间:温度传感器输出阻抗大,采样时间必须足够长(建议 > 10us)。
自热效应:连续高速采样会导致传感器自热,产生 1~2°C 的正偏差。
五、总结 Checklist
-
[ ] 是否启用了 VREFINT 通道?
-
[ ] 是否用 VREFINT 反推了 Actual_VDDA?
-
[ ] 采样时间是否足够长(> 10us)?
-
[ ] 是否考虑了自热效应(降低采样频率)?
💡 注意区分:本文讨论的是 ADC 参考源波动导致的测量误差。
若 ADC 数值本身跳动剧烈,请检查电源纹波或采样时间,详见《ADC采样时间到底设多少?别再瞎猜了》。
References
-
STM32 AN2834 – How to get the best ADC accuracy
-
STM32 Reference Manual – Temperature Sensor Characteristics
如果你在调试内部温度传感器时遇到过“玄学”偏差,欢迎在评论区交流。
原创文章,转载请注明出处。


