跳转到主要内容
杨月昌的硬件博客
返回

STM32传感器标定实战:最小二乘法二次曲线拟合工程实现(附完整代码)

引言

传感器标定是嵌入式系统中提升精度的关键步骤。温度、压力、电流等传感器普遍存在非线性误差,通过二次曲线拟合可大幅提高测量准确度。

在PC端我们习惯调用MATLAB/Eigen,但在STM32这种资源受限平台,移植大型矩阵库既耗内存又慢。本文采用代数解析法(克莱姆法则推导正规方程解),给出可直接拷贝的完整C代码,无需任何外部库,在开启FPU的STM32F4上计算7个标定点仅需几十微秒。


1. 数学模型:最小二乘法二次拟合

目标:找到系数 (a_0, a_1, a_2),使二次多项式
[ y = a_0 + a_1 x + a_2 x^2 ]
与观测点 ((x_i, y_i)) 的误差平方和最小。

通过对误差函数求偏导并令其为零,得到三元正规方程组。利用克莱姆法则可直接求出解析解,避免矩阵求逆运算,非常适合嵌入式实时计算。


2. 优化后的工程实现(直接可用)

typedef struct {
    double a0;  // 常数项
    double a1;  // 一次项系数
    double a2;  // 二次项系数
} QuadraticCoeff;

/**
 * @brief  最小二乘法二次曲线拟合(解析法,无矩阵库)
 * @param  x     输入数组(自变量,如ADC值)
 * @param  y     输入数组(标准值)
 * @param  n     数据点个数(推荐5~10个)
 * @return       拟合系数结构体
 */
QuadraticCoeff fit_quadratic(double *x, double *y, int n) {
    QuadraticCoeff coeff = {0.0, 0.0, 0.0};
    
    if (n < 3) return coeff;   // 至少3个点
    
    double s0 = n;
    double s1 = 0.0, s2 = 0.0, s3 = 0.0, s4 = 0.0;
    double t0 = 0.0, t1 = 0.0, t2 = 0.0;
    
    for (int i = 0; i < n; i++) {
        double xi = x[i];
        double x2 = xi * xi;
        double x3 = x2 * xi;
        double x4 = x3 * xi;
        double yi = y[i];
        
        s1 += xi;
        s2 += x2;
        s3 += x3;
        s4 += x4;
        
        t0 += yi;
        t1 += yi * xi;
        t2 += yi * x2;
    }
    
    // 行列式(det)
    double det = s0 * (s2 * s4 - s3 * s3) -
                 s1 * (s1 * s4 - s2 * s3) +
                 s2 * (s1 * s3 - s2 * s2);
    
    if (fabs(det) < 1e-12) return coeff;  // 奇异矩阵(数据线性或重合)
    
    // 克莱姆法则求解 a0, a1, a2
    coeff.a0 = (t0 * (s2 * s4 - s3 * s3) - t1 * (s1 * s4 - s2 * s3) + t2 * (s1 * s3 - s2 * s2)) / det;
    coeff.a1 = (s0 * (t1 * s4 - t2 * s3) - s1 * (t0 * s4 - t2 * s2) + s2 * (t0 * s3 - t1 * s2)) / det;
    coeff.a2 = (s0 * (s2 * t2 - s3 * t1) - s1 * (s1 * t2 - s3 * t0) + s2 * (s1 * t1 - s2 * t0)) / det;
    
    return coeff;
}

使用示例(标定后实时修正):

QuadraticCoeff c = fit_quadratic(adc_values, standard_values, 7);
double corrected = c.a0 + c.a1 * raw + c.a2 * raw * raw;

3. STM32 FPU配置与性能实测(2018年实践)


4. 标定工程CheckList(上线必查)

  1. 标定点个数是否 ≥5 且均匀分布在量程内?
  2. 是否开启了STM32 FPU硬浮点?
  3. 输入数据是否已做归一化(x范围过大时建议除以1000避免数值溢出)?
  4. det防除零保护是否生效?
  5. 拟合后残差是否在可接受范围内(建议打印验证)?
  6. 标定系数是否存入Flash/EEPROM(掉电不丢失)?

5. 常见避坑指南


6. 总结

最小二乘法二次曲线拟合是嵌入式传感器标定的高效利器。通过解析法+累乘优化+克莱姆法则,我们在STM32上实现了零外部库、微秒级实时计算。

工程铁律点要多且散、FPU要硬开、det要判零、结果要存Flash

掌握此方法,你就能轻松完成温度、压力、流量、电池SOC等高精度标定,让STM32的测量精度从“够用”升级到“专业级”。



上一篇
STM32以太网接口硬件设计全攻略:PHY选型、硬件协议栈与PCB布局实战指南
下一篇
遗传算法优化 PID 控制器的 C 语言实现