1.NTC参数

2.查表法
2.1. 温度-阻值对照表(0℃ ~ 150℃)
为了方便阅读和对比,我们先提取核心部分的表格(步长 5℃)。在实际代码中,这是一个常量数组。
| 温度 (℃) | 阻值 (Ω) | 温度 (℃) | 阻值 (Ω) | 温度 (℃) | 阻值 (Ω) |
|---|---|---|---|---|---|
| 0 | 16277 | 55 | 1268 | 110 | 232 |
| 5 | 12682 | 60 | 1052 | 115 | 201 |
| 10 | 9951 | 65 | 877 | 120 | 175 |
| 15 | 7863 | 70 | 735 | 125 | 153 |
| 20 | 6254 | 75 | 619 | 130 | 134 |
| 25 | 5000 | 80 | 524 | 135 | 118 |
| 30 | 4021 | 85 | 445 | 140 | 104 |
| 35 | 3253 | 90 | 380 | 145 | 92 |
| 40 | 2646 | 95 | 325 | 150 | 82 |
| 45 | 2164 | 100 | 280 | ||
| 50 | 1779 | 105 | 242 |
注意:此表是根据你提供的 B 值公式计算得出的。因为 NTC 是负温度系数,温度升高,阻值下降。
2.2. C 语言代码实现
以下代码可以直接移植到你的单片机(STM32、DSP、GD32 等)中。假设温度范围为 0°C 到 150°C,步长为 5°C。
cpp
#include <stdint.h>
// 1. 定义表格参数
#define TABLE_SIZE 31 // 数组元素个数 (0℃到150℃,步长5,共31个点)
#define TEMP_STEP 5.0f // 步长 5℃
#define TEMP_MIN 0.0f // 最低温度 0℃
// 2. 电阻查表数组 (单位:欧姆 Ω)
// 注意:必须按温度从低到高排列,对应的阻值是从大到小(降序)
const float NTC_Resistance_Table[TABLE_SIZE] = {
16277.0f, 12682.0f, 9951.0f, 7863.0f, 6254.0f, // 0℃ - 20℃
5000.0f, 4021.0f, 3253.0f, 2646.0f, 2164.0f, // 25℃ - 45℃
1779.0f, 1268.0f, 1052.0f, 877.0f, 735.0f, // 50℃ - 70℃
619.0f, 524.0f, 445.0f, 380.0f, 325.0f, // 75℃ - 95℃
280.0f, 242.0f, 232.0f, 201.0f, 175.0f, // 100℃ - 120℃ (注意105-110区间)
153.0f, 134.0f, 118.0f, 104.0f, 92.0f, // 125℃ - 145℃
82.0f // 150℃
};
/**
* @brief 通过查表法将 NTC 阻值转换为摄氏度
* @param current_res_ohm: 当前通过 ADC 换算出的 NTC 阻值 (单位 Ω)
* @retval 当前温度 (摄氏度)
*/
float Get_Temp_From_Table(float current_res_ohm)
{
uint8_t i = 0;
float temp_result = 0.0f;
float r_high, r_low, t_high, t_low;
// 3. 越界处理(开路或短路保护)
if (current_res_ohm >= NTC_Resistance_Table[0]) {
return TEMP_MIN; // 阻值大于 0℃ 的阻值,说明温度极低或开路,直接返回下限
}
if (current_res_ohm <= NTC_Resistance_Table[TABLE_SIZE - 1]) {
return TEMP_MIN + (TABLE_SIZE - 1) * TEMP_STEP; // 阻值极小,温度极高或短路
}
// 4. 遍历查找所在区间
for (i = 0; i < TABLE_SIZE - 1; i++) {
// 由于阻值是递减的,我们要找的区间是: 前一个值 >= 当前值 >= 后一个值
if (current_res_ohm <= NTC_Resistance_Table[i] &&
current_res_ohm >= NTC_Resistance_Table[i + 1])
{
// 获取区间的上下限阻值和对应的温度
r_high = NTC_Resistance_Table[i]; // 较大的阻值(较低温度)
r_low = NTC_Resistance_Table[i + 1]; // 较小的阻值(较高温度)
t_low = TEMP_MIN + i * TEMP_STEP; // 较低的摄氏度 (如 25℃)
t_high = TEMP_MIN + (i + 1) * TEMP_STEP;// 较高的摄氏度 (如 30℃)
// 5. 线性插值计算
// 公式: T = T_low + (R_current - R_low) / (R_high - R_low) * (T_high - T_low)
// 注意:这里分母 (R_high - R_low) 是正数,(T_high - T_low) 也是正数
temp_result = t_low + (current_res_ohm - r_low) / (r_high - r_low) * (t_high - t_low);
break; // 找到区间并计算完毕,跳出循环
}
}
return temp_result;
}
2.3. 如何在主程序中调用
在你的主循环或定时器中断里,大概需要这几步:
cpp
// 假设你已经通过 ADC 采样并计算出了 NTC 的当前阻值 R_ntc
float R_ntc = 1052.0f; // 假设实测阻值为 1052 Ω
// 1. 获取查表温度
float temp_c = Get_Temp_From_Table(R_ntc);
// 2. 用于你的保护逻辑(例如降载或停机)
if (temp_c > 85.0f) {
// 预警:风扇全速,或者限制电流
}
if (temp_c > 100.0f) {
// 故障:封锁 IGBT PWM 输出
}
工程优化建议
-
ADC 换算阻值公式 :上面的函数输入是阻值。实际单片机里读的是 ADC 的 12 位数字量(0~4095)。你需要先自己写个函数把
ADC_Value换成R_ntc(如前文所述的分压公式)。 -
浮点 vs 定点 :如果你的单片机没有硬件浮点运算单元(FPU)(如某些低端 8 位机或 M0 内核),大量使用
float会拖慢速度。你可以把表格和计算全部放大 10 倍或 100 倍,用**整型(int32_t)**来计算,最后除以倍数转回来。 -
首尾越界:注意代码中的越界处理。如果 NTC 线断了,阻值无穷大(ADC 读满),温度理应显示最低;如果短路,阻值为 0,理应显示最高温度并立即触发最高级别报警。