线性插值法详解

🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习

🎬擅长领域:驱动开发,嵌入式软件开发,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

十、总结

线性插值法的核心思想可以概括为一句话:

"按比例分配"

就像分蛋糕一样:

  1. 先看总共有多少(电阻总差)
  2. 看你拿了多少(实际电阻差)
  3. 按同样的比例分温度(温度差)

这种方法虽然简单,但在工程应用中已经足够精确,而且计算速度快,非常适合嵌入式系统。

相关推荐
简简单单做算法12 天前
【第2章>第1节】基于FPGA的图像放大和插值处理概述
计算机视觉·fpga开发·双线性插值·线性插值·图像放大·均值插值·最邻近插值
B_lack0264 个月前
西门子PLC结构化编程_线性插值算法功能块
算法·pid·西门子plc·博途·线性插值·开环控制
超级大咸鱼1 年前
verilog利用线性插值实现正弦波生成器(dds)
matlab·fpga·dds·线性插值