别再直接读ADC了!手把手教你用STM32F103和LM358搭建PT100高精度测温电路(附完整代码)
2026/6/6 5:59:03 网站建设 项目流程

从理论到实战:STM32+LM358构建工业级PT100测温系统

为什么直接读取PT100会失败?

很多嵌入式开发者第一次接触PT100温度传感器时,都会犯一个典型错误——试图直接用STM32的ADC读取传感器电压。这种看似简单的方法在实际测试中往往会出现令人沮丧的结果:温度读数波动大、精度差,甚至完全无法使用。这背后的根本原因在于PT100的特性与ADC的局限性。

PT100在0℃时阻值为100Ω,温度每升高1℃电阻仅增加约0.385Ω。假设采用恒流源驱动,当温度变化1℃时,电压变化量仅为:

ΔV = I × ΔR = 1mA × 0.385Ω = 0.385mV

STM32F103的12位ADC在3.3V参考电压下,最小分辨率为:

LSB = 3.3V / 4096 ≈ 0.8mV

显然,温度变化1℃产生的信号变化还不到ADC的半个LSB,这就是直接读取精度低下的根本原因。

高精度测温电路设计原理

电桥电路:微小电阻变化转电压信号

惠斯通电桥是将电阻变化转换为电压变化的最佳方案之一。当电桥平衡时(R1/R2 = R3/R4),输出电压为零;当PT100阻值变化导致电桥失衡时,会产生差分电压信号。

典型三线制PT100电桥配置:

元件参数选择作用说明
R1PT100传感器感温元件
R2100Ω精密电阻参考臂
R3,R41kΩ金属膜电阻比例臂,精度1%
R5200Ω多圈电位器电桥平衡调节

电桥输出电压公式:

Vout = Vcc × (R1/(R1+R4) - R2/(R2+R3))

差分放大电路设计关键

LM358作为经典双运放芯片,非常适合构建仪表放大器电路。其关键设计参数包括:

  • 增益计算:根据测温范围确定所需放大倍数
  • 共模抑制比:抑制电源噪声和共模干扰
  • 输入偏置电流:影响小信号测量精度

35倍放大电路元件选型:

// 差分放大电路电阻配置 #define R_GAIN1 10.0f // 单位:kΩ #define R_GAIN2 350.0f // 单位:kΩ float gain = R_GAIN2 / R_GAIN1; // 理论增益35倍

实际调试中发现,由于电阻公差和PCB寄生参数影响,实测增益约为32倍,需要通过电位器微调。

硬件设计避坑指南

电路板迭代经验总结

经过三个版本的硬件迭代,总结了以下关键经验:

  1. V1.0实验板

    • 采用模块化设计,所有电阻可调
    • 精度达到0.1℃,但体积庞大
    • 适合前期验证和参数优化
  2. V2.0测试板

    • 固定关键电阻值
    • 增加电源开关和测试点
    • 精度保持0.2℃,体积缩小40%
  3. V3.0成品板

    • 双面布局,优化走线
    • 内置增益调节电位器
    • 独立电源接口,稳定性提升

常见故障排查表

现象可能原因解决方案
输出饱和(3.3V)电桥供电接反检查5V和GND连接
读数不稳定电源滤波不足增加0.1μF去耦电容
温度显示跳变电位器接触不良更换高质量多圈电位器
低温段非线性导线电阻影响改用三线制接法补偿线阻

软件算法实现与优化

基于动态拟合的温度计算

PT100的电阻-温度关系并非完全线性,特别是在宽温度范围内。采用分段线性拟合算法:

// 温度-AD值对应表(示例) const uint16_t tempTable[] = {20, 25, 30, 35, 40, 45, 50}; // 温度值 const uint16_t adTable[] = {850, 937, 1024, 1111, 1198, 1285, 1372}; // AD值 float calculate_temp(uint16_t adValue) { uint8_t i; for(i=0; i<6; i++) { if(adValue >= adTable[i] && adValue < adTable[i+1]) { float slope = (tempTable[i+1]-tempTable[i])/(float)(adTable[i+1]-adTable[i]); return tempTable[i] + slope*(adValue-adTable[i]); } } return 0.0f; // 超出量程 }

数字滤波技术应用

针对工业环境干扰,采用复合滤波算法:

  1. 移动平均滤波:平滑随机噪声
  2. 中值滤波:抑制脉冲干扰
  3. 一阶滞后滤波:处理慢变信号

实现代码示例:

#define FILTER_LEN 10 uint16_t filter_buf[FILTER_LEN]; uint16_t adc_filter(uint16_t new_val) { static uint8_t index = 0; filter_buf[index++] = new_val; if(index >= FILTER_LEN) index = 0; uint32_t sum = 0; for(uint8_t i=0; i<FILTER_LEN; i++) { sum += filter_buf[i]; } return sum / FILTER_LEN; }

系统集成与性能测试

OLED显示界面设计

采用128×64 OLED显示关键信息:

----------------- | TEMP: 25.6℃ | | AD: 1024 | | STATUS: NORMAL| -----------------

显示刷新逻辑:

  • 温度值每秒更新一次
  • AD值实时显示(调试模式)
  • 状态栏显示报警信息

温度报警功能实现

三级温度报警设置:

void check_alarm(float temperature) { if(temperature > 70.0f) { buzzer_on(HIGH_ALARM); } else if(temperature > 50.0f) { buzzer_on(MID_ALARM); } else if(temperature > 30.0f) { buzzer_on(LOW_ALARM); } else { buzzer_off(); } }

实测性能数据

在20-80℃范围内进行测试:

温度点(℃)测量值(℃)误差(℃)
20.020.1+0.1
30.029.9-0.1
50.050.2+0.2
70.069.8-0.2
80.080.1+0.1

系统满足设计要求的±0.3℃精度指标,在工业现场连续运行72小时稳定性良好。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询