NTC热敏电阻温度换算太复杂?一篇搞定所有算法!
一、NTC热敏电阻是什么
在嵌入式系统开发中,温度测量是一个常见需求。NTC(负温度系数)热敏电阻因其成本低、灵敏度高而被广泛应用。本文将详细介绍如何利用一个简单的分压电路,结合STM32的ADC和数学公式,实现高精度的温度测量。
NTC是Negative Temperature Coefficient的缩写,意为“负温度系数”。其核心特性是电阻值随温度升高而呈指数型下降。这种特性使其对温度变化极为敏感,非常适合作为温度传感器。
- 工作原理:其半导体材料内部的载流子数量随温度升高而增加,导致电阻下降。
- 关键参数:
- R25:在25°C(即298.15K)时的零功率电阻值。这是最重要的标称值,例如常见的
10kΩ、100kΩ等。在下文计算中,我们的R0就是指这个值。 - B值:材料常数,单位为开尔文(K)。它描述了NTC电阻-温度曲线的形状,代表了在
T1和T2两个温度之间的“斜率”。B值越大,在相同温度变化下,电阻变化率越高。常用值如3380K,3950K等。
- R25:在25°C(即298.15K)时的零功率电阻值。这是最重要的标称值,例如常见的
- 优点:成本低、灵敏度高、体积小。
- 缺点:非线性、需要校准和计算、测温范围相对较窄。
二、电路设计采用分压电路
为了测量NTC的电阻,我们通常不直接测量电阻,而是将其转换为电压进行测量。最经典、最经济的方案就是分压电路。

电路分析:
- 拓扑结构:NTC(R1)与一个精度较高的定值电阻R2(图中为49.9kΩ)串联,接在3.3V电源与地之间。
- 测量点:中间节点
NTC_ADC的电压V_out即是我们的测量目标。这个点连接至STM32的ADC输入引脚。 - 工作原理:这是一个经典的分压器。
V_out的电压由R1和R2的阻值比例决定:V_out = 3.3V * (R2 / (R1 + R2))由于NTC的阻值R1会随温度变化,V_out也会随之变化。温度升高 -> R1减小 -> V_out升高。 - 下拉电阻R2的选型:R2的阻值选择至关重要,它决定了电路的灵敏度和测量范围。通常选择与NTC在目标测温范围中心点的阻值相近的阻值。本例中选择
49.9kΩ,是为了在较宽的温度范围内获得较好的电压变化线性度。如果主要测量室温附近,可以选择与R25(10kΩ)相近的阻值,如10kΩ。 - 计算NTC电阻:通过ADC读取到
V_out后,我们可以反推出NTC在当前温度下的电阻值R_ntc:R_ntc = R2 * (Vcc / V_out - 1),其中Vcc = 3.3V,R2 = 49.9kΩ。
三、Steinhart-Hart简化方程公式推导
NTC的电阻-温度关系是非线性的,最精确的描述是Steinhart-Hart方程。但在一定温度范围(如-40°C ~ 125°C)内,我们可以使用其简化版本,精度已足够。推导基于NTC的数据手册参数R25和B值。



Steinhart-Hart简化公式为:

T:待求的温度,单位为开尔文(K)。
T0:参考温度,单位为开尔文(K)。通常取25°C = 298.15K。
R:在温度T下测量/计算得到的NTC电阻值。
R0:在参考温度T0下的NTC电阻值,一般为10kΩ。
B:NTC的材料常数B值。
NTC温度的计算步骤:
a. 通过ADC和分压公式,求出当前R_ntc。
b. 计算ln(R_ntc / R25)。
c. 计算1/T = 1/298.15 + (1/B) * ln(R_ntc / R25)。
d. 计算T = 1 / (1/T),得到开尔文温度。
e. 转换为摄氏度:Temp(°C) = T(K) - 273.15。
四、基于HAL库的逻辑代码
#include "temp.h" #include "stdio.h" #include "math.h" #include "oled.h" // NTC参数 #define NTC_BETA 3450.0f // NTC热敏系数(B25/85值) #define NTC_R25 10000.0f // 25℃时NTC阻值(Ω) #define PULLDOWN_RESISTOR 50000.0f // 下拉电阻R2值(Ω) - 50kΩ /** * @brief ADC初始化函数 * @note 执行ADC校准并启动ADC转换 * @param 无 * @retval 无 */ void ADC_Init(void) { HAL_ADCEx_Calibration_Start(&hadc1); HAL_ADC_Start(&hadc1); } /** * @brief 中值滤波函数 * @note 采集N次ADC值,排序后返回中值 * @param hadc: ADC句柄指针 * @param N: 采样次数(建议奇数) * @retval 滤波后的ADC值 */ int getMiddleValue(ADC_HandleTypeDef *hadc, int N) { int value_buf[N]; int i, j, k, temp; for(i = 0; i < N; i++) { HAL_ADC_PollForConversion(hadc, HAL_MAX_DELAY); value_buf[i] = HAL_ADC_GetValue(hadc); } // 冒泡排序 for(j = 0; j < N-1; j++) { for(k = 0; k < N-1-j; k++) { if(value_buf[k] > value_buf[k+1]) { temp = value_buf[k]; value_buf[k] = value_buf[k+1]; value_buf[k+1] = temp; } } } return value_buf[(N-1)/2]; } /** * @brief 计算NTC电阻值 * @note 根据NTC在上、固定电阻在下的分压电路计算NTC电阻 * @param voltage: ADC测量电压(V) * @retval NTC电阻值(Ω) */ float calculate_ntc_resistance(float voltage) { // 电路:3.3V → R16(NTC) → ADC点 → R8(40k) → GND // 分压公式:Vadc = 3.3V * R8 / (R_NTC + R8) // 推导出:R_NTC = (3.3V * R8 / Vadc) - R8 return (3.3f * PULLDOWN_RESISTOR / voltage) - PULLDOWN_RESISTOR; } /** * @brief 温度计算函数 * @note 使用Steinhart-Hart简化方程计算NTC温度 * @param resistance: 当前NTC电阻值(Ω) * @retval 温度值(℃),错误返回-999.0 */ float calculate_temperature(float resistance) { if(resistance <= 0) return -999.0f; // 参考温度T0 = 25C = 298.15K const float T0_K = 273.15f + 25.0f; // 298.15K // 计算 ln(R/R0) float ln_ratio = logf(resistance / NTC_R25); // 计算 1/T = 1/T0 + (1/B) * ln(R/R0) float reciprocal_temp = 1.0f/T0_K + (1.0f/NTC_BETA) * ln_ratio; // 计算 T = 1 / (1/T) float temp_k = 1.0f / reciprocal_temp; // 转换为摄氏度 return temp_k - 273.15f; } int ntc_value = 0; // ADC原始值 float ntc_voltage = 0.0f; // NTC电压值(V) float ntc_resistance = 0.0f; // NTC电阻值(Ω) float temperature = 0.0f; // 计算温度值(℃) char displayStr[16]; // OLED显示字符串 /** * @brief 温度处理主函数 * @note 采集温度数据,计算实际温度并在OLED显示 * @param 无 * @retval 无 */ void temperature_proc(void) { // NTC温度采集 ntc_value = getMiddleValue(&hadc1, 7); // 转换成电压值 ntc_voltage = (ntc_value / 4095.0f) * 3.3f; // 计算NTC电阻值 ntc_resistance = calculate_ntc_resistance(ntc_voltage); // 计算温度 temperature = calculate_temperature(ntc_resistance); // 显示温度 sprintf(displayStr, "T:%.1fC", temperature); OLED_ShowString(0, 1, displayStr); } 五、总结
通过NTC测量温度是一个嵌入式中的经典应用。整个过程可以总结为以下链条:温度变化 -> NTC电阻变化 -> 分压点电压变化 -> ADC采样值变化 -> 公式计算 -> 得到温度值。
- 电路设计是基础:一个稳定的
Vcc和一个精密的下拉电阻是获得准确电压的前提。 - 公式是核心:Steinhart-Hart简化公式是将非线性电阻值转换为线性温度值的关键桥梁。务必确保
B值和R25两个参数准确。 - 软件实现需注意细节:ADC的参考电压、分辨率、滤波(软件或硬件),以及浮点数运算的精度和效率都需要根据实际项目权衡。
在实际项目中,为了提高精度,我们还可以进行两点校准,(例如在冰水混合物和沸水中,以消除元件公差和电路带来的系统误差。
如有任何勘误,还望各位在评论区一起交流讨论学习!