1. 项目概述
在工业测量和精密仪器领域,温度检测是最基础也是最重要的参数之一。热电偶和RTD(如Pt100)作为两种最常用的温度传感器,各有其独特的优势和应用场景。热电偶具有测温范围广、响应快、结构简单等特点,而Pt100则以稳定性好、精度高著称。但它们的信号处理都面临着共同的挑战——如何实现高精度、低噪声的测量,特别是热电偶的冷端补偿问题。
这个开源项目基于STM32微控制器和AD7124-8这款高精度Σ-Δ型ADC,完整实现了八种常见热电偶(K/J/T/E/N/S/R/B型)和Pt100(三线制/四线制)的温度测量方案。特别值得一提的是,项目中针对热电偶的冷端补偿提供了完整的解决方案,这在工业现场应用中至关重要。
2. 硬件设计解析
2.1 核心器件选型
AD7124-8芯片特性:
- 24位Σ-Δ架构ADC,最高19.2kHz输出数据率
- 8个差分/15个伪差分输入通道
- 内置可编程增益放大器(PGA),增益1~128
- 低噪声:1.17μV p-p(增益=128,输出率=19.2Hz)
- 内置基准电压和温度传感器
- SPI接口通信
选择AD7124-8的主要原因在于其极高的集成度和优异的噪声性能。对于热电偶和RTD测量,微伏级的信号需要高分辨率ADC才能准确捕获。同时,内置的PGA可以灵活调整信号幅度,省去了外部放大电路。
STM32选型考虑:
项目采用了STM32F4系列作为主控,主要基于以下考量:
- 足够的计算性能处理复杂的温度计算算法
- 丰富的定时器资源用于PWM输出等控制功能
- 多个SPI接口与AD7124通信
- 浮点运算单元(FPU)加速浮点计算
2.2 热电偶测量电路设计
热电偶产生的电压信号极其微弱(K型热电偶约41μV/℃),且需要冷端补偿。电路设计要点包括:
- 输入保护:TVS二极管和RC滤波网络防止ESD和电磁干扰
- 信号调理:采用低噪声仪表放大器(如AD8421)进行初步放大
- 冷端补偿:利用AD7124内置温度传感器或外部精密温度传感器(如TMP117)测量连接点温度
- 基准连接:REFIN±引脚连接低噪声基准源(如ADR4525)
典型连接示意图:
code复制热电偶+ → 10Ω → 100nF → AD7124 AIN0
热电偶- → 10Ω → 100nF → AD7124 AIN1
冷端传感器 → I2C → STM32
2.3 Pt100测量方案对比
2.3.1 三线制测量
三线制通过额外的一根导线补偿引线电阻,是工业现场最常见的连接方式。测量原理:
- 恒流源通过A线激励Pt100
- 测量B线和C线之间的电压差
- 通过公式计算消除引线电阻影响
AD7124配置:
- 使用两个激励电流源(Iout1, Iout2)
- AIN2测量电压,AIN3作为参考
2.3.2 四线制测量
四线制完全消除了引线电阻影响,适合实验室等高精度场合:
- 一对导线提供激励电流
- 另一对导线测量电压降
- 无需考虑引线电阻补偿
AD7124配置:
- 使用一个激励电流源
- AIN4和AIN5直接测量Pt100两端电压
3. 软件架构与关键算法
3.1 系统初始化流程
- 硬件初始化:
c复制void AD7124_Init(void) {
// 复位AD7124
AD7124_Reset();
// 配置接口(SPI模式3, 数据长度8位)
AD7124_Set_SPI_Config();
// 设置基准电压源
AD7124_Set_Reference(AD7124_REFIN1);
// 配置通道和增益
AD7124_Setup_Channel(0, AD7124_AIN0, AD7124_AIN1, AD7124_GAIN_128);
// 设置滤波器类型和输出数据率
AD7124_Set_Filter(0, AD7124_SINC3_FILTER, 19.2);
}
- 校准流程:
AD7124支持内部零标度和满标度校准,建议上电时执行:
c复制void AD7124_Calibrate(void) {
AD7124_Start_Internal_Zero_Scale_Cal();
while(AD7124_Check_Cal_Complete() == 0);
AD7124_Start_Internal_Full_Scale_Cal();
while(AD7124_Check_Cal_Complete() == 0);
}
3.2 热电偶温度计算
热电偶温度计算分为两步:
- 测量热电偶电压
- 测量冷端温度并补偿
NIST多项式算法:
项目实现了基于NIST ITS-90标准的逆多项式计算,以K型热电偶为例:
c复制float Calculate_K_Type_Temperature(float mv) {
// 分段多项式系数
const float coeff1[] = {0.0, 2.5173462e1, -1.1662878, -1.0833638...};
const float coeff2[] = {0.0, 2.508355e1, 7.860106e-2, -2.503131e-1...};
if(mv < -5.891) {
// 使用第一段多项式
return Horner_Polynomial(mv, coeff1, sizeof(coeff1)/sizeof(float));
} else if(mv < 0.0) {
// 使用第二段多项式
return Horner_Polynomial(mv, coeff2, sizeof(coeff2)/sizeof(float));
}
// ...其他区间
}
冷端补偿算法:
c复制float Compensated_Temperature(float measured_mv, float cold_junction_temp) {
// 1. 计算冷端对应的热电偶电压
float cold_mv = Temp_To_MV(cold_junction_temp);
// 2. 补偿后的热电偶电压
float actual_mv = measured_mv + cold_mv;
// 3. 计算实际温度
return MV_To_Temp(actual_mv);
}
3.3 Pt100电阻计算与温度转换
对于三线制Pt100,引线电阻补偿算法:
c复制float Calculate_3Wire_Pt100_Temp(float R1, float R2, float R3) {
// 假设三根引线电阻相同
float lead_resistance = (R1 + R2 + R3) / 3.0f;
float pt100_resistance = R1 - lead_resistance;
// 使用Callendar-Van Dusen方程计算温度
float temp = (-R0 * A + sqrt(R0*R0*A*A - 4*R0*B*(R0 - pt100_resistance)))
/ (2 * R0 * B);
return temp;
}
四线制计算更简单:
c复制float Calculate_4Wire_Pt100_Temp(float resistance) {
// 直接使用Callendar-Van Dusen方程
return (-R0 * A + sqrt(R0*R0*A*A - 4*R0*B*(R0 - resistance)))
/ (2 * R0 * B);
}
4. 工程实现细节
4.1 AD7124配置最佳实践
-
滤波器选择:
- Sinc3滤波器:适合静态或缓慢变化的信号,抑制50/60Hz工频干扰
- Sinc4滤波器:更高抑制比,但建立时间更长
- 输出数据率(ODR)选择:热电偶推荐≤100Hz,Pt100可到1kHz
-
增益设置原则:
- K型热电偶:增益128(41μV/℃ → 5.25mV/℃)
- Pt100:增益32(典型激励电流0.5mA → 100Ω=50mV)
-
基准电压选择:
- 内部2.5V基准:简单但精度一般(±10mV)
- 外部基准:推荐ADR4525(2.5V, ±0.02%初始精度)
4.2 噪声抑制技巧
-
PCB布局要点:
- 模拟和数字地分开,单点连接
- 热电偶输入走线加屏蔽层
- 去耦电容尽量靠近AD7124电源引脚
-
软件滤波算法:
c复制#define FILTER_DEPTH 8
float Moving_Average_Filter(float new_sample) {
static float buffer[FILTER_DEPTH] = {0};
static uint8_t index = 0;
static float sum = 0;
sum -= buffer[index];
buffer[index] = new_sample;
sum += buffer[index];
index = (index + 1) % FILTER_DEPTH;
return sum / FILTER_DEPTH;
}
4.3 校准与温度补偿
-
两点校准法:
- 冰水混合物(0℃)和沸水(100℃)作为参考
- 记录ADC读数并计算斜率和偏移
-
非线性补偿:
对于Pt100,使用更高阶的Callendar-Van Dusen方程:code复制Rt = R0(1 + A*t + B*t² + C*(t-100)*t³) // t>0℃ Rt = R0(1 + A*t + B*t²) // t≤0℃
5. 常见问题与解决方案
5.1 热电偶测量异常排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 读数跳变 | 接触不良 | 检查接线端子,使用抗氧化剂 |
| 负温度显示 | 极性接反 | 交换热电偶两根引线 |
| 温度偏高 | 冷端补偿失效 | 检查冷端传感器是否接触良好 |
| 无变化 | 开路故障 | 测量热电偶电阻,正常应<10Ω |
5.2 Pt100测量问题
三线制测量误差大:
- 检查三根引线电阻是否匹配(差异应<0.1Ω)
- 确认激励电流稳定(推荐0.5mA恒流源)
- 检查AD7124的Iout1和Iout2配置是否正确
四线制噪声问题:
- 增加输入端的RC滤波(如1kΩ+100nF)
- 降低数据输出率,使用更强的数字滤波
- 检查基准电压稳定性
5.3 AD7124通信故障
-
SPI无响应:
- 检查CS引脚是否正常拉低
- 确认SPI模式设置(CPOL=1, CPHA=1)
- 测量SCLK频率(建议<5MHz)
-
数据异常:
c复制uint32_t AD7124_Read_Register(uint8_t reg) { uint8_t tx_buf[4] = {0}; uint8_t rx_buf[4] = {0}; tx_buf[0] = AD7124_COMM_READ | AD7128_COMM_ADDR(reg); SPI_Transfer(tx_buf, rx_buf, 4); return (rx_buf[1]<<16) | (rx_buf[2]<<8) | rx_buf[3]; }如果读取失败,建议:
- 检查电源电压(3.3V±5%)
- 复位AD7124后重新初始化
- 降低SPI时钟频率测试
6. 项目扩展与优化方向
-
多通道扫描实现:
利用AD7124的8个差分通道,可以扩展为多路温度采集系统。关键配置:c复制void Setup_Multi_Channel(void) { for(int i=0; i<8; i++) { AD7124_Setup_Channel(i, AD7124_AIN0+i, AD7124_AIN1+i, AD7124_GAIN_128); AD7124_Set_Filter(i, AD7124_SINC3_FILTER, 50); } AD7124_Enable_Channel_Scanning(); } -
无线传输功能:
通过STM32的USART接口连接蓝牙/WiFi模块,实现远程监控:- HC-05蓝牙模块:适合短距离传输
- ESP8266 WiFi模块:支持TCP/IP协议
-
LCD界面优化:
添加图形化显示,使用STemWin库实现:c复制void Display_Temperature(float temp) { char buf[20]; sprintf(buf, "Temp: %.1f°C", temp); GUI_DispStringAt(buf, 50, 50); } -
数据记录功能:
添加SD卡存储,记录温度变化曲线:c复制void Log_To_SD_Card(float temp) { FIL file; char line[50]; sprintf(line, "%lu,%.2f\n", HAL_GetTick(), temp); if(f_open(&file, "temp_log.csv", FA_WRITE | FA_OPEN_APPEND) == FR_OK) { f_puts(line, &file); f_close(&file); } }
在实际部署中发现,AD7124的基准电压稳定性对测量精度影响极大。我曾在一个工业现场项目中遇到温度读数漂移的问题,最终发现是由于基准电压芯片(ADR4525)的供电纹波过大所致。解决方案是在基准芯片的输入输出端都增加10μF钽电容和0.1μF陶瓷电容并联滤波,同时将基准芯片远离MCU等数字器件布局。这个小技巧让系统稳定性提升了近一个数量级。