🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习
🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发
❄️作者主页:一个平凡而乐于分享的小比特的个人主页
✨收录专栏:硬件知识,本专栏为记录项目中用到的知识点,以及一些硬件常识总结
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

线性插值法详解
一、什么是线性插值?
生活中的例子
想象你在爬一座山:
- 山脚下(0米处)温度是 25°C
- 山顶上(1000米处)温度是 15°C
你现在爬到 400米 的高度,想知道这里的温度是多少?
直观推理:
- 从山脚到山顶,高度上升1000米,温度下降10°C
- 平均每上升100米,温度下降1°C
- 你现在上升了400米,温度应该下降4°C
- 所以400米处的温度 = 25°C - 4°C = 21°C
这就是线性插值 的核心思想:在两个已知点之间,按比例估算未知点的值。
二、数学原理图解
2.1 基本概念图
温度(°C)
↑
25 ┼───────● (0米, 25°C)
│ \
24 ┼ \
23 ┼ \
22 ┼ \
21 ┼ ● (400米, 21°C) ← 我们要求的值
20 ┼ \
19 ┼ \
18 ┼ \
17 ┼ \
16 ┼ \
15 ┼ ● (1000米, 15°C)
└──────────┴──────────┴──────────→ 高度(米)
0 400 1000
2.2 数学公式图解
已知:点A (x₁, y₁) 和 点B (x₂, y₂)
求:点P (x, y) 其中 x₁ < x < x₂
公式:y = y₁ + (x - x₁) × (y₂ - y₁) / (x₂ - x₁)
图解:
y₂ ┼───────● B
│ ╱
│ ╱
y ┼──────● P ← 高度差比例 = 水平距离比例
│ ╱
│ ╱
y₁ ┼───● A
│
└───┴───┴───┴───→
x₁ x x₂
三、NTC热敏电阻应用详解
3.1 问题背景
NTC热敏电阻的特点是:温度升高,电阻下降(负温度系数)。
我们需要通过测量电阻值来反推温度。
3.2 R-T关系曲线
电阻(Ω) ↑
200k ┼──● (-40°C, 198.4k)
│ \
150k ┼ \
│ \
100k ┼ \
│ \
50k ┼ \
│ \
10k ┼ ● (25°C, 10k)
│ \
5k ┼ \
│ \
1k ┼ ● (90°C, 1k)
└──────────┴──────────┴──────────→ 温度(°C)
-40 25 90
3.3 R-T数据表(部分)
| 温度(°C) | 电阻(Ω) | 说明 |
|---|---|---|
| -40 | 198,400 | 低温时电阻很大 |
| -35 | 151,100 | |
| -30 | 116,000 | |
| -25 | 89,800 | |
| -20 | 70,200 | |
| -15 | 55,300 | |
| -10 | 43,900 | |
| -5 | 34,800 | |
| 0 | 27,800 | 冰点 |
| 5 | 22,400 | |
| 10 | 18,160 | |
| 15 | 14,800 | |
| 20 | 12,140 | 室温附近 |
| 21 | 11,670 | |
| 22 | 11,220 | |
| 23 | 10,800 | |
| 24 | 10,390 | |
| 25 | 10,000 | 标称值 |
| 26 | 9,625 | |
| 27 | 9,266 | |
| 28 | 8,922 | |
| 29 | 8,593 | |
| 30 | 8,278 | |
| 35 | 6,891 | |
| 40 | 5,767 | |
| 45 | 4,851 | |
| 50 | 4,101 | |
| 60 | 2,995 | |
| 70 | 2,219 | |
| 80 | 1,667 | |
| 90 | 1,263 | |
| 100 | 965 | |
| 120 | 589 | |
| 150 | 308 | 高温时电阻很小 |
四、三种典型场景详细对比
场景1:正好落在表格点上
情况 :测得电阻 = 10,000Ω
查找过程:
电阻表: 10,000Ω 正好对应 25°C
结果: 温度 = 25.00°C
图解:
电阻
10,000 ┼───● (25°C, 10,000Ω)
│
│
│
└───────→ 温度
25°C
结论:直接查表,无需计算
场景2:落在两个表格点之间
情况 :测得电阻 = 10,600Ω
步骤1:确定区间
查找电阻所在范围:
24°C → 10,390Ω
23°C → 10,800Ω
10,600Ω 介于 10,390Ω 和 10,800Ω 之间
步骤2:可视化分析
电阻(Ω)
10,800 ┼───● A (23°C, 10,800)
│ \
10,700 ┼ \
│ \
10,600 ┼ ● P (?, 10,600) ← 我们在这里
│ \
10,500 ┼ \
│ \
10,400 ┼ \
10,390 ┼ ● B (24°C, 10,390)
└────────┴────────┴────→ 温度(°C)
23°C 24°C
步骤3:比例计算
电阻差计算:
总电阻差 = 10,800 - 10,390 = 410Ω
已下降电阻 = 10,800 - 10,600 = 200Ω
比例 = 200 / 410 = 0.4878
温度计算:
总温度差 = 24°C - 23°C = 1°C
温度增量 = 0.4878 × 1°C = 0.4878°C
最终温度 = 23°C + 0.4878°C = 23.49°C
场景3:超出表格范围
情况A:电阻大于最大值
测得电阻 = 200,000Ω (> 198,400Ω)
电阻
200k ────● 超出范围
╱
198.4k ┼───● 表格最大值 (-40°C)
│
└──────→ 温度
-40°C
结果 :温度 = -40°C(按边界值处理)
情况B:电阻小于最小值
测得电阻 = 300Ω (< 308Ω)
电阻
308 ──● 表格最小值 (150°C)
╲
300 ──● 超出范围
结果:温度 = 150°C
五、计算对比表
为了更直观地理解插值过程,我们来看不同电阻值对应的计算过程:
| 测量电阻(Ω) | 所在区间 | 计算公式 | 计算结果(°C) |
|---|---|---|---|
| 27,800 | 正好是0°C点 | 直接查表 | 0.00 |
| 25,000 | 0°C-5°C之间 | 25,000在27,800和22,400之间 | 约2.5 |
| 22,400 | 正好是5°C点 | 直接查表 | 5.00 |
| 20,000 | 5°C-10°C之间 | 20,000在22,400和18,160之间 | 约7.8 |
| 18,160 | 正好是10°C点 | 直接查表 | 10.00 |
| 15,000 | 10°C-15°C之间 | 15,000在18,160和14,800之间 | 约13.2 |
| 14,800 | 正好是15°C点 | 直接查表 | 15.00 |
| 12,140 | 正好是20°C点 | 直接查表 | 20.00 |
| 11,000 | 20°C-21°C之间 | 11,000在12,140和11,670之间 | 约20.8 |
| 10,600 | 23°C-24°C之间 | 详细计算见上文 | 23.49 |
| 10,390 | 正好是24°C点 | 直接查表 | 24.00 |
| 10,000 | 正好是25°C点 | 直接查表 | 25.00 |
| 9,500 | 25°C-26°C之间 | 9,500在10,000和9,625之间 | 约25.8 |
| 8,278 | 正好是30°C点 | 直接查表 | 30.00 |
六、算法流程图

七、代码实现逐行解析
c
static float BSP_NTC_ResToTemp(uint32_t resistance)
{
uint8_t i;
/* 1. 边界检查:超出表格范围的情况 */
if (resistance >= ntc_res_table[0]) /* 电阻太大 → 温度太低 */
return (float)ntc_temp_table[0]; /* 返回 -40°C */
if (resistance <= ntc_res_table[NTC_TABLE_SIZE - 1]) /* 电阻太小 → 温度太高 */
return (float)ntc_temp_table[NTC_TABLE_SIZE - 1]; /* 返回 150°C */
/* 2. 遍历表格,查找电阻所在的区间 */
for (i = 0; i < NTC_TABLE_SIZE - 1; i++)
{
/* 注意:电阻值随温度升高而降低,所以是递减序列
条件:当前点电阻 ≥ 实际电阻 ≥ 下一点电阻 */
if (resistance <= ntc_res_table[i] && resistance >= ntc_res_table[i + 1])
{
/* 3. 计算比例因子
分子:从当前点下降到实际电阻的差值
分母:当前点到下一点的电阻总差值 */
float ratio = (float)(ntc_res_table[i] - resistance) /
(float)(ntc_res_table[i] - ntc_res_table[i + 1]);
/* 4. 线性插值计算温度
当前点温度 + 比例 × 温度差 */
return (float)ntc_temp_table[i] +
ratio * (float)(ntc_temp_table[i + 1] - ntc_temp_table[i]);
}
}
return 25.0f; /* 默认值(正常情况下不会执行到这里) */
}
八、数据流向图
┌─────────────────┐
│ ADC采样值 │
│ (0-4095) │
└────────┬────────┘
↓
┌─────────────────┐
│ 计算电阻值 │
│ R = f(ADC) │
└────────┬────────┘
↓
┌─────────────────┐
│ 电阻值 R │
│ (单位: Ω) │
└────────┬────────┘
↓
┌─────────────────────────────────────┐
│ 查表插值过程 │
├─────────────────────────────────────┤
│ ┌──────────────┐ │
│ │ R ≥ 198,400? │───是──→ 温度 = -40°C │
│ └──────────────┘ │
│ ↓ 否 │
│ ┌──────────────┐ │
│ │ R ≤ 308? │───是──→ 温度 = 150°C │
│ └──────────────┘ │
│ ↓ 否 │
│ ┌──────────────────────┐ │
│ │ 查找区间 i 使 │ │
│ │ table[i] ≥ R ≥ table[i+1] │ │
│ └──────────────────────┘ │
│ ↓ │
│ ┌──────────────────────┐ │
│ │ 计算比例 = (T[i]-R) │ │
│ │ / (T[i]-T[i+1]) │ │
│ └──────────────────────┘ │
│ ↓ │
│ ┌──────────────────────┐ │
│ │ 温度 = temp[i] + │ │
│ │ 比例 × (temp[i+1]-temp[i]) │
│ └──────────────────────┘ │
└─────────────────────────────────────┘
↓
┌─────────────────┐
│ 最终温度值 │
│ (单位: °C) │
└─────────────────┘
九、精度分析
9.1 误差来源
| 误差类型 | 原因 | 影响程度 |
|---|---|---|
| 表格离散化 | 只有离散点,没有连续曲线 | 主要误差 |
| 线性近似 | R-T关系实际是非线性的 | 中等 |
| ADC量化 | ADC分辨率有限 | 较小 |
| 电阻计算 | 参考电压精度、分压电阻精度 | 较小 |
9.2 不同区间的线性度
温度区间 线性度 最大误差
─────────────────────────────
-40°C ~ 0°C 较差 ±1.5°C
0°C ~ 50°C 较好 ±0.3°C
50°C ~ 100°C 中等 ±0.8°C
100°C ~ 150°C 较差 ±2.0°C
十、总结
线性插值法的核心思想可以概括为一句话:
"按比例分配"
就像分蛋糕一样:
- 先看总共有多少(电阻总差)
- 看你拿了多少(实际电阻差)
- 按同样的比例分温度(温度差)
这种方法虽然简单,但在工程应用中已经足够精确,而且计算速度快,非常适合嵌入式系统。