简介:面向电子工程师、单片机开发者与温度采集方案设计者的一份NTC热敏电阻参数速查文档,聚焦MFH103-3950型号B值为3950的温度—电阻对照关系。文档以摄氏度与千欧为单位,逐点列出-20.0℃至82.5℃区间(以0.5℃为步进)的阻值数据,例如-20.0℃时约95.3370KΩ、25.0℃时10.0000KΩ、30.0℃时8.0541KΩ,可直接看出阻值随温度升高而显著下降的非线性趋势。压缩包共1个文件,为doc格式,体积约26KB,轻量易取,适合嵌入程序开发流程作为查表依据。已有5168人学习。读者可据此在单片机固件中构建查找表,实现快速温度换算,也可结合B值公式或Steinhart-Hart方程做精度校正,用于家电、汽车电子与工业设备的测温电路选型与调试核对。
1. B值3950到底在说什么:一颗电阻的"温度性格"
翻元件盒找出一颗标着 mfh103-3950 的热敏电阻,不少人的第一反应是"3950 是不是阻值"。不是。它在 25℃ 时的阻值是 10KΩ,3950 是另一个参数——B 值,单位是 K。用一句大白话说:B 值描述这颗电阻对温度的反应有多剧烈。打个比方,同样被扔进桑拿房,有人十秒就往外跑,有人还能坐着聊完一轮,B 值就是这颗电阻的"怕热程度"。两颗都是 25℃ 时 10KΩ 的 NTC,B 值 3435 的那颗到 100℃ 还剩 0.987KΩ,B 值 3950 的只剩 0.663KΩ——同样升温,后者"塌"得更狠。搞懂这个数字,你才知道手里那张 R/T 对照表为什么长这样、查表能查到什么精度、什么时候该换别的方案。
2. 为什么温度一高电阻就变小:NTC 的物理直觉与 B 值的位置
2.1 从半导体导电讲起:载流子多了,路就好走了
NTC 的芯子是锰、钴、镍这类过渡金属氧化物烧结出来的陶瓷半导体。半导体和金属的导电逻辑不一样:金属靠自由电子,温度升高晶格振动加剧,电子被撞得更频繁,电阻反而变大;半导体靠的是载流子浓度,温度升高时,一部分电子从价带被热激发跳到导带,电子-空穴对的数量呈指数级增长。载流子一变多,能导电的"通道"就变多,电阻就往下掉。
打个比方,早高峰的地铁站只开了两个闸机口,人流挤在门口寸步难行——这就是低温下 NTC 的样子,载流子少,电阻大。太阳升起来,温度上去,站务员把十几个闸机全打开,人流一下就疏散了——载流子变多,电阻变小。注意这里的"闸机数量"不是线性增加的,温度每升高一点,能打开的闸机数量就翻一截,所以 NTC 的电阻-温度曲线是一条陡峭的指数下滑线,不是一条斜直线。
这个物理图像决定了 NTC 的两件"性格":一是灵敏度高,室温附近阻值随温度的变化率能到每摄氏度百分之几,比铂电阻那种线性器件猛得多;二是非线性强,你没法用一句"每升高 1℃ 减多少欧姆"来描述它,必须借助公式或表格。B 值就是用来概括这条曲线陡峭程度的那一个数字。
2.2 B 值:把一整条曲线压缩成一个数字
严格一点说,B 值又叫材料常数,定义为两个温度点上的电阻比的对数,除以这两个温度倒数的差:
B = ln(R1 / R2) / (1/T1 - 1/T2)这里 T1、T2 必须用开尔文,不是摄氏度。R1、R2 是对应温度下的阻值。单位是 K。
这个式子可以改写成更常用的形式,也就是把任意温度 T 下的阻值和 25℃ 的标称阻值联系起来:
R(T) = R25 × exp[ B × (1/T - 1/298.15) ]看懂这个式子的关键在指数那一项:(1/T - 1/298.15)。温度 T 越低于 25℃,这个差值越正,指数越大,电阻越大;温度越高于 25℃,差值越负,指数越小,电阻越小。B 值就是乘在这个差值前面的"放大系数"。B 越大,同样一段温度变化被放大得越厉害,曲线越陡。
拿项目里这张表验证一下。25.0℃ 对应 10.0000 KΩ,50.0℃ 对应 3.5870 KΩ,代进第一个式子:
B = ln(10.0000 / 3.5870) / (1/298.15 - 1/323.15) = ln(2.7878) / (0.0033540 - 0.0030945) = 1.0254 / 0.0002595 ≈ 3951 K算出来 3951K,和标称的 3950K 只差 0.05%。这不是巧合,因为型号里写的 B25/50 = 3950K,定义就是用 25℃ 和 50℃ 这两个点拟合出来的。换句话说,3950 这个数字的"主场"就在 25 到 50℃ 这个区间,越往外走,它跟真实曲线的偏差越大——这一点后面会专门算给你看。
2.3 3950 算大还是算小:不同 B 值摆在一起看
NTC 的 B 值常见范围大概在 3000K 到 4500K 之间。2950、3435、3950、4200 这些都是市面上能见到的档位。数字本身没有好坏,它只是一个"陡峭度"的刻度。
把三颗 25℃ 时都是 10KΩ 的 NTC 摆在一起,看它们在 100℃ 时的表现:
| B 值(B25/50) | 25℃ 阻值 | 100℃ 阻值 | -20℃ 阻值 | 曲线特征 |
|---|---|---|---|---|
| 3435 K | 10 KΩ | 约 0.987 KΩ | 约 60.9 KΩ | 相对平缓,低温端不吓人 |
| 3950 K | 10 KΩ | 约 0.697 KΩ | 约 105.4 KΩ | 中等偏陡,最通用 |
| 4200 K | 10 KΩ | 约 0.590 KΩ | 约 131.4 KΩ | 陡,灵敏度高但两端更难处理 |
表中 100℃ 和 -20℃ 两列是按 B 值公式推算的,和项目里的实测表会有出入,原因稍后解释。
这张表能读出两件事。第一,B 值越大,高温端电阻掉得越狠。B=3435 的到 100℃ 还剩 0.987KΩ,B=3950 的只剩 0.697KΩ,差了 30%。这意味着如果你用分压电路采样,B 值大的那颗在高温端的电压信号更靠近地,对 ADC 的低端分辨率要求更高。第二,B 值越大,低温端电阻涨得越凶,-20℃ 时 B=4200 的那颗已经 131KΩ 了,串一个 10K 分压电阻,输出几乎贴着电源轨,分辨率损失同样明显。
所以选 B 值不是选"越陡越好",而是选"你的测温区间落在曲线的哪一段"。3950 之所以成了通用款,是因为它把 -20℃ 到 100℃ 这个家用和工业最常见的区间,压缩到了一个阻值跨度大约 144 倍(95.337KΩ 到 0.663KΩ)的范围里——大到信号够用,又没大到电路难以处理。这是一个被市场反复验证过的折中点。
3. 这张 R/T 表从哪来:从 10KΩ 锚点到 241 个格点
3.1 三个锚点:-20℃、25℃、100℃ 分别意味着什么
项目里这张表从 -20.0℃ 一路列到 100.0℃,步进 0.5℃,一共 241 行。扫一眼就能看出三个关键位置。
第一个锚点是 25.0℃,阻值 10.0000 KΩ。这是标称值 R25,厂家在恒温槽里逐颗测出来、再按这个值分档的。表格里这一行长得"太整齐",因为它本身就是一个定义点,不是算出来的。
第二个锚点是 -20.0℃,阻值 95.3370 KΩ。这是低温端的边界,也是整张表里阻值最大的一格。从 10KΩ 到 95.3KΩ,涨了 9.5 倍。
第三个锚点是 100.0℃,阻值 0.6630 KΩ。这是高温端的边界,从 10KΩ 掉到 0.663KΩ,掉了 15 倍。整个区间最大最小阻值相差 143.8 倍,横跨两个数量级还多。
为什么步进选 0.5℃ 而不是 1℃?算一下相邻两行的相对变化就明白了。25.0℃ 到 25.5℃,阻值从 10.0000 掉到 9.7833,变化 2.17%;-20.0℃ 到 -19.5℃,从 95.3370 掉到 92.6559,变化 2.81%;100.0℃ 到 99.5℃,从 0.6729 掉到 0.6630,变化 1.47%。也就是说,0.5℃ 的步进下,相邻两格之间阻值差 1.5% 到 3%,在这个密度上做线性插值,插值引入的误差可以压到 0.01℃ 量级,完全够用。如果步进放到 5℃,相邻格之间差 15% 以上,插值就明显失真了。
这三个锚点还告诉你一件事:这张表不是纯公式生成的。如果拿 B=3950 从 25℃ 硬算,-20℃ 会算出 105.4KΩ,而表里是 95.337KΩ,差了 10.5%;0℃ 会算出 33.62KΩ,表里是 32.50KΩ,差 3.4%;100℃ 会算出 0.697KΩ,表里是 0.663KΩ,差 5.1%。只有 50℃ 附近几乎完全吻合(算出 3.5872KΩ,表里 3.5870KΩ)。这说明表格是厂家在多个温度点实测、再平滑处理出来的,不是拿一条固定 B 值的公式铺到底。
3.2 用公式反推:为什么 25℃ 必须正好是 10KΩ
写一段代码,把表格里的几个点和 B 值公式的预测摆在一起,偏差就一目了然了。
import math R25 = 10_000.0 # 25℃ 标称阻值,单位欧姆 B = 3950.0 # 标称 B 值(B25/50),单位开尔文 T25 = 298.15 # 25℃ 对应的开尔文温度 def r_of_t(celsius): """用固定 B 值公式估算某温度下的阻值,返回欧姆""" T = celsius + 273.15 return R25 * math.exp(B * (1.0 / T - 1.0 / T25)) def b_from_two(t1_c, r1, t2_c, r2): """由两个温度点及其阻值反算该区间的实际 B 值""" T1, T2 = t1_c + 273.15, t2_c + 273.15 return math.log(r1 / r2) / (1.0 / T1 - 1.0 / T2) # 表格中抽取的六个点,阻值单位 KΩ bench = [(-20.0, 95.3370), (0.0, 32.5030), (25.0, 10.0000), (50.0, 3.5870), (85.0, 1.0530), (100.0, 0.6630)] print("温度 表值(KΩ) 公式(KΩ) 偏差") for t, r_k in bench: pred = r_of_t(t) / 1000.0 print(f"{t:6.1f} {r_k:9.4f} {pred:9.4f} {(pred / r_k - 1) * 100:+6.2f}%") # 分段反算实际 B 值,看 3950 在哪一段最准 table = dict(bench) for a, b in [(-20.0, 25.0), (0.0, 25.0), (25.0, 50.0), (25.0, 85.0), (25.0, 100.0)]: ba = b_from_two(a, table[a] * 1000, b, table[b] * 1000) print(f"{a:5.1f}~{b:5.1f}℃ 的实际 B 值 = {ba:.0f} K")跑出来的结果大致是这样:
| 温度 | 表值(KΩ) | 公式(KΩ) | 偏差 |
|---|---|---|---|
| -20.0℃ | 95.3370 | 105.38 | +10.53% |
| 0.0℃ | 32.5030 | 33.62 | +3.44% |
| 25.0℃ | 10.0000 | 10.00 | 0.00% |
| 50.0℃ | 3.5870 | 3.587 | +0.01% |
| 85.0℃ | 1.0530 | 1.114 | +5.79% |
| 100.0℃ | 0.6630 | 0.697 | +5.13% |
再看分段反算的 B 值:
| 温度区间 | 反算 B 值 |
|---|---|
| -20~25℃ | 3782 K |
| 0~25℃ | 3840 K |
| 25~50℃ | 3952 K |
| 25~85℃ | 4006 K |
| 25~100℃ | 4025 K |
这组数字信息量很大。它说明"B 值是常数"只是一个近似——真实的 B 值随温度区间在变,从 -20℃ 附近的 3782K 一路爬升到 100℃ 附近的 4025K。标称的 3950K 是厂家挑了一个最有代表性的区间(25~50℃)定下来的。你在 25~50℃ 之间用 3950 计算,误差几乎为零;拿到 -20℃ 或 100℃ 用,误差就出来了。
把阻值误差换算成温度误差更直观。假设实际阻值是表里的 95.337KΩ(真实温度 -20℃),你拿 B=3950 的公式反算:
1/T = 1/298.15 + ln(95.337/10) / 3950 = 0.0033540 + 2.2550 / 3950 = 0.0039250 T = 254.78 K = -18.37℃也就是说,明明 -20℃,公式告诉你 -18.37℃,错了 1.63℃。同样算 100℃(实际 0.663KΩ):1/T = 0.0033540 + ln(0.0663)/3950 = 0.0033540 - 0.0006850 = 0.0026690,T = 374.67K = 101.52℃,错 1.5℃。室温附近呢?30℃ 实测 8.0541KΩ,用公式反算:1/T = 0.0033540 + ln(0.80541)/3950 = 0.0033540 - 0.0000547 = 0.0032993,T = 303.10K = 29.95℃,只错 0.05℃。
这就是为什么工程上会流传一句话:B 值公式在室温附近好用,两端要靠表。不是玄学,是这条曲线的 B 值本来就不是常数。
3.3 查表法怎么落到单片机里:964 字节换 0.01℃
把 241 个点做成查找表,是嵌入式里最常见的做法。表格阻值单位取 0.1Ω,-20℃ 那格是 953370,100℃ 那格是 6630,一个 32 位整数装得下。总共 241 × 4 = 964 字节 flash。
/* R/T 表:-20.0℃ ~ 100.0℃ 步进 0.5℃,共 241 项 表项单位 0.1Ω(例如 953370 表示 95337.0Ω = 95.337KΩ) 阻值随温度单调递减,可用二分查找 */ static const uint32_t r_table_01ohm[241] = { 953370, 926559, 900580, /* ……中间省略…… */ 6630 }; /* 输入阻值(0.1Ω 单位),返回温度 ×10(即 0.1℃ 分辨率) 低于 -20℃ 返回 -200,高于 100℃ 返回 1000 */ int16_t ntc_lookup(uint32_t r_01ohm) { int lo = 0, hi = 240; if (r_01ohm >= r_table_01ohm[0]) return -200; if (r_01ohm <= r_table_01ohm[240]) return 1000; while (hi - lo > 1) { /* 二分定位区间,最多 8 次比较 */ int mid = (lo + hi) >> 1; if (r_table_01ohm[mid] >= r_01ohm) lo = mid; /* 表值大 = 温度低 */ else hi = mid; } uint32_t r_lo = r_table_01ohm[lo]; /* 区间左端阻值,较大 */ uint32_t r_hi = r_table_01ohm[hi]; /* 区间右端阻值,较小 */ int32_t t10 = lo * 5; /* 左端温度 ×10,每格 0.5℃ = 5 */ t10 += (int32_t)(5L * (r_lo - r_01ohm) / (r_lo - r_hi + 1)); /* 线性插值 */ return (int16_t)t10; }这段代码有几个点值得说清楚。r_table_01ohm按温度从低到高排列,所以阻值是从大到小,二分时的比较方向要和这个顺序对齐——表值大于目标值,说明查到的位置温度偏低,要往右半边找,所以是lo = mid。t10 = lo * 5是因为每格 0.5℃,换成 0.1℃ 单位就是 5。最后那行插值里加 1 是为了防止两端阻值相等时除零,代价是引入极小的偏差,可以忽略。
精度方面,因为原始表步进就是 0.5℃,相邻格阻值差 1.5%~3%,线性插值把残余误差压到了 0.01℃ 以下。这个精度已经远超 NTC 本身的容差(±1% 的 B 值在低温端就对应 0.4℃ 的误差),所以查表法的瓶颈不在算法,在器件。
内存吃紧的方案可以换一种存法:把表压缩成 int16,存"相对 25℃ 的阻值比例 ×10000",能省一半空间;或者只存每隔 2℃ 一个点,靠插值补中间,精度会掉到 0.1℃ 左右但仍够用。这些取舍看你手头的 flash 有多宽裕。
4. 常见误区与易混概念:B值、10K、3950 不是一回事
4.1 误区一:把 3950 当成阻值,或者把 10K 当成型号
易混点:mfh103-3950这一串字符里,103和3950到底哪个是阻值。不少人第一眼会把 3950 当成"3950 欧姆"。
为什么混:电子元件的命名习惯不统一。贴片电阻用103表示 10×10³ = 10KΩ,而 NTC 型号里 3950 直接就是 B 值数字,两套规则混在一个标签上,很容易看错。
怎么区分:记住两个固定搭配——10K或103说的是 25℃ 时的标称阻值,单位欧姆;3950说的是 B 值,单位 K。看到四位数字在 3000~4500 之间,基本可以断定是 B 值;看到三位数字带一个字母(103、473、104),那是阻值编码。买料的时候这两项必须同时确认,因为 10KΩ 的 NTC 有 3435、3950、4200 好几个 B 值版本,光看阻值会买错。
4.2 误区二:以为 B 值是恒定常数,敢拿它全温区外推
易混点:把B = 3950当成一颗电阻的固有属性,像电阻阻值一样不变,于是用一条公式从 -40℃ 算到 150℃。
为什么混:教科书和大部分器件手册给的公式都是R = R25·exp[B(1/T - 1/T25)],形式上看 B 就是个常数。加上摘要类资料常写"B 值越大,电阻随温度变化越快",更容易让人觉得它是个固定刻度。
怎么区分:上一章的分段反算已经给了答案——同一颗料,-20~25℃ 区间实际 B 值是 3782K,25~50℃ 是 3952K,25~100℃ 是 4025K。跨度接近 250K,相当于 6% 的差异。如果你的测温范围超过 ±40℃,只用单一 B 值算,误差会爬到 1℃ 以上。判断方法很简单:把你要用的温度区间两端代入公式反算一次 B 值,如果算出来和标称值差超过 1%,就老老实实查表或者上 Steinhart-Hart 三参数模型。
4.3 误区三:B25/50 和 B25/85 混着用
易混点:手册上有时写B25/50 = 3950K,有时写B25/85 = 3950K,看起来都是 3950,能不能通用。
为什么混:B 值必须附两个参考温度才有意义,但很多资料省略了这两个下标,只写"B 值 3950"。这一省略就埋了雷。
怎么区分:B25/50 是用 25℃ 和 50℃ 两个点算出来的,B25/85 是用 25℃ 和 85℃ 两个点算出来的,同一颗料这两个数字不一样。拿这张表算一下:25~85℃ 区间反算出来是 4006K,比 3950 高了 56K。如果你把 B25/85 = 4006K 的料当成 B25/50 = 3950K 来用,85℃ 附近会算出什么?实际阻值 1.053KΩ,用 3950 反算:1/T = 0.0033540 + ln(0.1053)/3950 = 0.0033540 - 0.0005699 = 0.0027841,T = 359.18K = 86.03℃。报出来 86℃,实际 85℃,差 1℃。
判断方法:看手册里 B 值后面的下标,没有下标就找同型号的完整规格书。替换料的时候不能只对 B 值数字,还要对参考温度点。
4.4 误区四:NTC、PTC、PT100 当成可以互换的"温度电阻"
易混点:这四样东西(还有热电偶)都是测温度的,看起来都是"温度一变、输出就变",随手抓一个用行不行。
为什么混:名字里都带"热"或"温",外观上 NTC 和 PTC 甚至长得一模一样,都是两颗小圆片带两根引脚。
怎么区分:看电阻随温度变化的方向和曲线形状。NTC 是负温度系数,温度升、电阻降,曲线指数型陡降,便宜、灵敏度高、非线性强,测温范围大致 -40~150℃。PTC 是正温度系数,分两类:陶瓷 PTC 在居里点附近电阻急剧上升几个数量级,主要拿来做过流保护和自控温加热,不是用来测温的;高分子 PTC 也是开关型。PT100/PT1000 是铂热电阻,正温度系数,近似线性,精度能到 ±0.1℃,但贵、需要专用激励电路。热电偶靠两种金属接点的温差电动势,能测上千度,但信号只有几十微伏,要冷端补偿。
一句话判断:要便宜、要灵敏度、温度不超 150℃、能接受查表——NTC;要精度和线性、预算够——PT100;要测几百度——热电偶;要做保护而不是测量——PTC。
5. 从阻值到温度读数:三种算法和它们的误差边界
5.1 分压电路:把电阻的变化翻成电压的变化
NTC 不能直接读出温度,得先变成电压。最常见的做法是串一个固定电阻分压。假设上拉电阻 R_series = 10KΩ,接 3.3V,NTC 接地:
Vout = Vcc × R_ntc / (R_ntc + R_series)代入表格里的几个点算一下:25℃ 时 R_ntc = 10KΩ,Vout = 3.3 × 10/20 = 1.650V,正好是电源的一半。这就是为什么上拉电阻也选 10KΩ——让工作点落在量程中央,两端都能用。
-20℃ 时 R_ntc = 95.337KΩ,Vout = 3.3 × 95.337/105.337 = 2.987V,占电源的 90.5%,已经贴近电源轨。100℃ 时 R_ntc = 0.663KΩ,Vout = 3.3 × 0.663/10.663 = 0.205V,只占 6.2%,贴近地。
这个电压跨度看着还行,但分辨率是不均匀的。12 位 ADC、3.3V 参考,一个码大约 0.806mV,换算成电源的比例是 0.0244%。看低温端:-20℃ 到 -19.5℃,Vout 从 90.51% 变到 90.26%,差 0.25%,大约 10 个码。看高温端:100℃ 到 99.5℃,从 6.218% 变到 6.305%,差 0.087%,只有 3.6 个码。也就是说,高温端每 0.5℃ 只有三四个 ADC 码的变化,噪声稍大就会跳。
这是个实打实的坑:很多人以为 12 位 ADC 就够,实测发现 90℃ 以上温度读数抖得厉害。解决思路有三个——把上拉电阻改小(比如 3.3KΩ)让高温段电压摆幅变大,但低温段会更快贴顶;用更高位数的 ADC;或者接受现实,靠软件滤波和多次平均把噪声压下去。
提示:分压电阻的取值本质上是在给"你最关心的温度区间"分配 ADC 码。没有哪个阻值能让 -20~100℃ 全程均匀,先想清楚你的测温重点在哪一段。
5.2 三种算法摆在一起:查表、B 值公式、Steinhart-Hart
从电压反推温度,工程上有三条路。
查表加插值,就是第 3 章那段代码。把厂家给的 R/T 表烧进 flash,二分查找加线性插值。优点是完全忠实于实测曲线,全温区误差最小(0.01℃ 量级,受限于表本身);缺点是占内存,换料就得换表。
B 值公式,就是1/T = 1/T25 + ln(R/R25)/B。优点是不占内存、代码三行;缺点是只在标称区间准,前面算过,-20℃ 会错 1.63℃,100℃ 会错 1.5℃。
Steinhart-Hart 方程是三条里的"专业款",形式是:
1/T = A + B·ln(R) + C·(ln R)³三个系数 A、B、C 用三个温度点标定出来(比如 0℃、25℃、50℃,或者 0℃、50℃、100℃)。因为多了一个三次项,它能拟合出 B 值随温度漂移那段弯曲,全温区精度通常能压到 0.1℃ 以内,好的标定能到 0.01℃。代价是要标定、要算两次对数一次立方,8 位单片机上跑一次大概几十微秒到几百微秒,不算重但也不轻。
| 方案 | flash 占用 | 全温区精度 | 计算量 | 换料成本 | 适用场景 |
|---|---|---|---|---|---|
| 查表 + 线性插值 | 约 1 KB | 约 0.01℃ | 8 次比较 | 换表 | 量产、温度范围固定 |
| B 值公式 | 几十字节 | ±1.5℃ | 一次 log | 改一个常数 | 精度要求宽松、快速验证 |
| Steinhart-Hart | 几十字节 + 系数 | 约 0.1℃ | 两次 log + 一次立方 | 重新标定 | 高精度、宽温区 |
选哪条路,看你能容忍多少误差、有多少 flash、愿不愿意做标定。三者不冲突,很多方案是常温段用 B 值公式、两端切到查表。
顺带说一个实现细节:B 值公式反算温度时,结果对浮点精度不敏感,float就够了,不必上double。
/* 由阻值反算摄氏温度,返回 0.1℃ 单位;仅适合 25℃ 附近区间 */ int16_t ntc_b_to_temp(uint32_t r_ohm) { /* 1/T = 1/T25 + ln(R/R25) / B */ float inv_t = 1.0f / 298.15f + logf((float)r_ohm / 10000.0f) / 3950.0f; return (int16_t)((1.0f / inv_t - 273.15f) * 10.0f + 0.5f); }298.15f是 25℃ 的开尔文值,10000.0f是 R25,3950.0f是 B 值——这三处都得跟你的实际料号对上,改料不改代码是常见的翻车点。logf在某些精简工具链里会拉进几 KB 的数学库,如果 flash 特别紧张,可以用定点查表替代。
5.3 误差从哪来:容差、自热、线阻、ADC
算出来的温度准不准,算法只是其中一环,更多误差藏在硬件里。
B 值容差是第一个。项目标注B25/50 = 3950K ± 1%,也就是说真实 B 值可能在 3910 到 3990 之间。这个 1% 会变成多少温度误差?在 -20℃ 处,1/T 的第二项是 -0.000596,B 变 1% 就是 5.96×10⁻⁶ 的倒数变化,换算成温度约 0.38℃;在 100℃ 处第二项是 -0.000674,1% 对应约 0.94℃。低温端影响小、高温端影响大,这又一次说明高温段要用 B25/85 的数据。
自热是第二个,也是最容易被忽略的。NTC 靠电流测阻值,电流一流过就会发热,测出来的温度自然偏高。算一下:3.3V 供电、上拉 10KΩ、25℃ 时 NTC 也是 10KΩ,回路电流 3.3/20K = 0.165mA,NTC 上的功耗是 I²R = (1.65×10⁻⁴)² × 10000 = 0.272mW。小珠状 NTC 在静止空气里的耗散系数大约 1~3 mW/℃,取 2 mW/℃,自热升温约 0.14℃。如果把供电换成 5V,电流变 0.25mA,功耗 0.625mW,自热升到 0.31℃,误差直接翻倍。
有意思的是,功耗最大点出现在 NTC 阻值等于上拉电阻的时候,也就是 25℃ 附近;-20℃ 时虽然阻值大,但电流小,功耗反而只有 0.094mW;100℃ 时阻值小,功耗 0.064mW。所以自热误差是"中间大、两头小"的,校准的时候别只在室温校。
线阻是第三个。长导线把 NTC 接到板子上,导线电阻直接串进测量回路。25℃ 时 10KΩ 串 1Ω 是 0.01%,无所谓;但 100℃ 时 NTC 只有 663Ω,串 1Ω 就是 0.15%,换算成温度大概 0.07℃。几十米长的线、线径又细,这个数会继续放大。两线制没法消除,三线制或四线制可以,但成本和接线复杂度上去了。
ADC 本身的误差也不能忽略。参考电压漂移、量化噪声、输入失调,加在一起几十个码是常态。前面算过高温端每 0.5℃
本文还有配套的精品资源,点击获取