点击链接下载protues仿真设计资料:https://download.csdn.net/download/m0_51061483/92081500
- 系统总体方案设计
2.1 设计背景与应用意义
水泵广泛应用于供水、排水、循环冷却、工业输送、农业灌溉等场合,其运行效率直接关系到能耗成本和设备健康状态。传统的水泵效率检测往往依赖流量计、压力传感器、电功率测量等多参数综合计算,仪表成本高、安装维护复杂,且在一些老旧站点或小型系统中难以长期部署。
在工程实践中,尤其是热水循环泵、热交换循环系统、锅炉补水泵以及部分具有稳定工况的介质输送系统中,水泵进出口的温度差(ΔT)与系统能量变化存在一定关联。通过温差法可快速评估水泵运行状态,识别效率下降、空转、堵塞、异常摩擦导致发热等问题,从而实现“低成本、易部署”的在线健康监测。
本设计提出一种基于AT89C52单片机的水泵效率温差法测量与报警系统,利用两个E型热电偶配合MAX31855热电偶数字转换模块采集水泵进出口温度,单片机计算温差并依据经验公式估算水泵效率,同时使用LCD1602实时显示效率上下限与当前效率值,支持通过按键设置温度阈值与效率上下限,当效率超出设定范围时触发声光报警。该系统适合用于泵站巡检辅助、设备状态监控以及节能管理等领域。
2.2 系统设计目标
系统面向实际应用与课程设计双重需求,目标如下:
- 温度采集准确可靠:采用E型热电偶检测进出口温度,MAX31855进行冷端补偿并输出数字温度。
- 温差与效率计算:单片机实时计算ΔT,并依据经验公式估算水泵效率η。
- 可视化显示:LCD1602显示温度、温差、当前效率、效率上限/下限和阈值信息。
- 可设置参数:按键可设置温差阈值、效率上下限,支持参数保存(可扩展EEPROM)。
- 报警机制清晰可靠:效率超出范围触发报警,可区分“低效率报警”和“高效率异常报警”(例如传感器故障导致异常值)。
- 系统稳定性与工程化:具备按键消抖、传感器异常检测、测量滤波、报警延迟确认、抗干扰与电源保护设计。
2.3 系统组成结构
系统硬件模块组成如下:
- AT89C52单片机最小系统模块
- E型热电偶测温模块(进水口、出水口)
- MAX31855热电偶数字转换模块(两路或两模块)
- LCD1602显示模块
- 按键设置模块
- 声光报警模块(蜂鸣器+LED)
- 电源供电模块(5V稳压、滤波)
- 可选扩展模块(EEPROM参数保存、RS485上传、继电器联动)
系统软件模块组成如下:
系统工作流程:
- 上电初始化 → 读取参数(默认/EEPROM) → 采集进出口温度 → 过滤与校验 → 计算温差ΔT → 代入经验公式得到效率η → LCD刷新显示 → 按键调整阈值/效率范围 → 判断η是否越限 → 触发报警 → 循环运行。
- 功能设计与工作原理
3.1 温度采集功能(双E型热电偶 + MAX31855)
3.1.1 E型热电偶工作原理与特点
热电偶属于接触式温度传感器,利用塞贝克效应:当两种不同金属材料构成闭合回路且两端温度不同时,回路中产生热电势,其大小与温差相关。
E型热电偶(Chromel-Constantan)具有以下特点:
- 灵敏度高:相较K型等,E型在中低温区热电势较大,更适合精细温差测量。
- 适用范围广:典型测温范围可达-200℃到900℃(实际应用常在0~200℃)。
- 稳定性较好:适合工业现场长期使用。
- 抗干扰要求高:热电偶信号为微小电压,易受电磁干扰,需要良好屏蔽与信号调理。
在水泵效率温差法中,进出口温度差往往只有几摄氏度,E型热电偶的高灵敏度有助于提高测量分辨率。
3.1.2 MAX31855模块作用与优势
MAX31855是一款集成冷端补偿的热电偶数字转换芯片,可直接与多种热电偶配合工作,将热电偶信号转换为数字温度数据输出。其优势包括:
- 集成冷端补偿:无需额外温度传感器测量冷端,简化硬件设计。
- 数字输出:通过SPI接口输出温度数据,减少模拟放大和噪声问题。
- 故障检测:可检测热电偶开路、短路等异常并输出故障位。
- 分辨率与稳定性:温度输出具有一定分辨率(通常0.25℃级),适合温差计算。
由于系统需要采集进出口两点温度,因此可以采用两种方式:
- 使用两个MAX31855模块分别读取两个热电偶
- 或使用多通道热电偶转换方案(更复杂)
在课程设计中通常采用“两个MAX31855模块”的方案,结构清晰,调试方便。
3.1.3 温差测量与误差来源分析
温差ΔT = Tout - Tin。温差测量误差来源主要包括:
- 热电偶安装位置不同导致温度不一致(应尽量靠近泵体进出口,且保证探头插入深度一致)。
- 传感器响应时间差(进出口流速不同导致动态误差)。
- MAX31855量化误差(输出分辨率导致温差存在±0.25℃阶梯)。
- 外界环境影响(管道散热、保温情况、环境温度变化)。
- 工况波动(流量变化导致ΔT波动)。
系统需通过滤波算法(移动平均、一阶低通)提升温差稳定性,并可设置“稳定判定”后再计算效率与报警。
3.2 效率计算功能(温差法经验公式)
3.2.1 温差法效率评估思路
水泵效率通常定义为:
- η = 水力功率 / 轴功率
温差法在某些场景下通过“泵损耗转化为热量导致温升”来反推效率。简化理解:泵输入功率中一部分转化为有用水力功,一部分转化为热损耗,损耗越大,泵体与介质温升越明显,因此温差可反映效率趋势。
由于不同泵型、介质、流量、压力工况差异较大,温差法通常依赖经验拟合公式或现场标定。实际工程中常用: - η = A - B·ΔT(线性近似)
- η = A / (1 + B·ΔT)(非线性近似)
- η = A - B·ΔT - C·ΔT²(拟合曲线)
本设计使用“经验公式”计算效率,建议采用可配置参数形式(A、B、C可通过按键设置或预设),以适配不同泵型与工况,并便于实验标定。
3.2.2 效率计算的工程合理性
温差法更适用于“效率趋势监测”和“异常报警”,而非高精度计量。系统设计中应强调:
- 用于判断泵是否效率下降、是否异常发热、是否空转或堵塞;
- 通过现场标定提高准确度;
- 结合温度阈值与效率阈值同时判断,提高可靠性。
因此系统增加温度阈值设置是有必要的:当温度过高或温差异常时,可能说明工况异常或传感器错误,需要报警或提示维护。
3.3 LCD1602显示功能
3.3.1 显示内容设计
LCD1602显示两行16字符,为兼顾信息量与可读性,可采用页面切换:
- 页面1:Tin、Tout、ΔT
- 页面2:η、ηL、ηH
- 页面3(可选):阈值设置界面(T阈值、ΔT阈值)
典型显示格式: - 第一行:
IN:25.0 OUT:28.2 - 第二行:
DT:3.2 ETA:78%
或者: - 第一行:
ETA:78% L:60 H:90 - 第二行:
ALM:OFF或显示报警类型。
3.3.2 显示刷新与稳定性
温度数据一般1秒更新一次即可,LCD刷新周期建议500ms~1s,避免频繁刷新导致闪烁或占用CPU。设置模式下显示应固定在设置页,并提供光标或闪烁提示当前参数。
3.4 按键设置功能
3.4.1 按键功能规划
建议至少3~4个按键实现完整设置:
- SET:进入/切换设置项/确认
- UP:参数增加
- DOWN:参数减少
- ESC(可选):退出不保存或返回
设置内容包括:
- 温度阈值(可为Tin/Tout上限或ΔT上限)
- 效率下限ηL
- 效率上限ηH
- (可扩展)经验公式参数A、B、C
- (可扩展)报警延迟时间与确认次数
3.4.2 参数保存与掉电保持(可选)
若仅为实验系统,可使用单片机内部RAM保存参数,断电后恢复默认。若要工程化,可外接EEPROM(如AT24C02)保存阈值与参数,避免断电丢失。
3.5 报警功能
3.5.1 报警触发逻辑
系统要求当效率超出设定范围触发报警,具体可定义:
- η < ηL:低效率报警(可能泵磨损、堵塞、空转、轴承故障、流量异常)
- η > ηH:高效率异常报警(可能公式不适配、温差过小、传感器故障、接触不良导致温差失真)
同时建议增加温度阈值报警: - Tin或Tout超过设定上限(例如过热报警)
- ΔT超过设定阈值(例如异常发热或工况异常)
报警输出:蜂鸣器鸣叫 + LED闪烁,并在LCD显示报警原因。
3.5.2 误报警抑制策略
为避免因瞬间波动误报警,建议:
- 连续N次超限才报警(如连续3次)
- 报警解除需要回到正常范围并保持一定时间(如5秒)
- 采样滤波后再判断报警
这些策略能显著提升系统实用性。
- 电路设计(分模块详细说明)
4.1 AT89C52单片机最小系统模块
4.1.1 核心作用与资源需求
AT89C52为经典8051内核单片机,具备:
4.1.3 抗干扰设计要点
由于热电偶测量易受干扰,尽管MAX31855输出为数字信号,仍需:
4.2 E型热电偶测温模块
4.2.1 安装与结构设计建议
热电偶应安装在水泵进出口近端或管路上,建议:
- 使用金属护套热电偶,防水耐腐蚀
- 采用螺纹安装或卡箍固定
- 传感器探头与介质充分接触,提高响应速度
- 两个热电偶尽量同型号同长度,减少误差
- 管道外侧可加保温层,减少环境散热影响
4.2.2 引线与屏蔽注意事项
热电偶输出为微小电压,尽管MAX31855近端转换为数字,但热电偶到MAX31855的引线仍应尽量短:
- 引线用热电偶专用补偿导线
- 远离电源线和继电器线
- 必要时使用屏蔽线并单端接地
这些措施能提高测温稳定性与系统可靠性。
4.3 MAX31855热电偶转换模块
4.3.1 模块功能与接口
MAX31855通过SPI输出32位数据帧,包含:
- 热电偶温度(高位数据)
- 内部冷端温度
- 故障位(开路、短路等)
连接方式: - SCK:串行时钟
- CS:片选(每个模块一个CS)
- SO:串行数据输出
AT89C52可采用软件SPI(bit-bang)读取,避免占用硬件SPI资源(8051通常无硬件SPI)。
4.3.2 两路采集实现方式
由于系统需要两路热电偶:
- 方案A:两片MAX31855,每片对应一个热电偶;SCK与SO可共用,CS独立。
- 方案B:采用模拟多路切换(不推荐,会引入误差与复杂度)。
推荐方案A,简单可靠且便于调试。
4.3.3 故障检测与保护
MAX31855提供故障位,可用于检测:
- 热电偶断线
- 对地短路
- 对VCC短路
系统在检测到故障时应: - LCD显示“SENSOR ERR”
- 停止效率计算或标记数据无效
- 可触发报警提示维护
这样可避免传感器故障导致错误效率值误报警。
4.4 LCD1602显示模块
4.4.1 接口模式选择
LCD1602支持8位与4位模式。为了节省I/O口,推荐4位模式连接:
4.4.2 显示抗干扰措施
LCD数据线应远离蜂鸣器与电源高电流路径,必要时:
- 在电源端加去耦电容
- LCD旁加小电容
防止显示乱码或死机。
4.5 按键设置模块
4.5.1 按键硬件设计
按键采用上拉输入:
- 一端接地
- 一端接I/O口并上拉(10K)
按下为低电平。
为提高抗干扰,可增加RC滤波,但软件消抖通常足够。
4.5.2 操作逻辑与用户体验
设置模式建议:
- SET进入设置 → SET切换项目 → UP/DOWN修改数值 → 长按SET保存退出
并在LCD显示“SET”提示,当前参数闪烁显示,避免误改。
4.6 声光报警模块
4.6.1 蜂鸣器驱动
采用有源蜂鸣器简单可靠,单片机IO通过三极管驱动蜂鸣器,避免直接带负载。报警节奏可由定时器控制:
- 低效率报警:间歇鸣叫
- 高效率/故障报警:快速鸣叫
使报警类型可听辨。
4.6.2 LED报警灯
LED可用于视觉报警,越限时闪烁。若需驱动高亮警示灯,可使用MOSFET并采用独立电源,避免对逻辑供电造成干扰。
4.7 电源供电模块
4.7.1 电源架构
系统一般采用12V适配器输入,再通过稳压模块输出5V供单片机与LCD:
- 7805线性稳压:电路简单但发热较大
- DC-DC降压:效率高,推荐
MAX31855通常工作在3.3V环境,若模块带稳压可直接用5V供电;若不带稳压需提供3.3V并注意电平兼容。
4.7.2 滤波与保护
电源模块必须加:
- 输入端大电容(100uF~470uF)
- 每个芯片旁0.1uF去耦
- 反接保护与保险丝(可选)
- TVS防浪涌(可选)
保证系统在工业现场稳定运行。
- 程序设计(分模块详细说明)
5.1 软件总体架构设计
软件采用模块化与非阻塞设计,主要任务包括:
- MAX31855采集任务(1秒一次或更快)
- 温度滤波与有效性判断任务
- 温差计算与效率计算任务
- LCD显示刷新任务(500ms~1s刷新)
- 按键扫描与设置菜单任务(10ms扫描)
- 报警判断与输出控制任务(100ms节拍控制报警节奏)
- 参数保存与加载任务(可选EEPROM)
主循环中按不同周期执行任务,定时器中断提供系统节拍,保证响应及时且不阻塞。
5.2 MAX31855 SPI读取模块
5.2.1 软件SPI实现思路
AT89C52可通过IO模拟SPI时序:
- CS拉低开始
- SCK上升沿/下降沿采样SO数据
- 读取32位数据
- CS拉高结束
读取后解析温度与故障位。
5.2.2 数据帧解析与温度转换
MAX31855输出热电偶温度通常为14位带符号值,单位为0.25℃;冷端温度为12位带符号值。程序需要:
- 判断故障位
- 将温度原始值转换为浮点或定点数
由于8051浮点运算较慢,推荐使用定点表示: - 温度×100(单位0.01℃)
- 或温度×4(单位0.25℃)
通过定点运算实现温差与效率计算,提升效率与稳定性。
5.3 温度滤波与有效性检测模块
5.3.1 滤波算法选择
由于温度变化较慢,可采用:
- N点滑动平均(N=8或16)
- 一阶低通滤波:y = αx + (1-α)y_prev
滤波可减少温差抖动,避免效率显示跳动。温差越小系统越敏感,因此滤波尤为重要。
5.3.2 异常数据处理
当检测到:
- MAX31855故障位为1
- 温度超出合理范围(如<-50℃或>200℃)
- 两路温差异常大(例如>50℃,不符合工况)
则认为数据无效: - LCD显示错误信息
- 停止效率计算或保持上一次有效值
- 触发故障报警(可选)
这样可避免错误数据导致误报警。
5.4 温差计算模块
温差计算公式:
- ΔT = Tout - Tin
若采用定点温度×100: - ΔT100 = Tout100 - Tin100
显示时再转换为“X.Y℃”。
系统可设置温差阈值:当ΔT过大或过小可提示工况异常或传感器异常。
5.5 效率计算模块(经验公式)
5.5.1 经验公式设计与可配置化
为了适配不同泵型,建议经验公式参数可设置。示例公式:
- η = A - B·ΔT
其中: - η为效率百分比(0~100)
- ΔT为温差(℃)
- A、B为经验系数(通过标定确定)
例如在某系统中:A=90,B=3,则ΔT=5℃时η=75%。
为了避免浮点,建议使用定点: - η = A100 - B100 * ΔT100 / 100
其中A100=A×100,B100=B×100,可保持两位小数精度。
5.5.2 效率限制与异常判断
计算后应限制:
- η < 0 → 置0
- η > 100 → 置100或视为异常
若η超出合理范围可能是传感器或公式不匹配,应提示“CAL ERR”并报警或忽略。
5.6 按键扫描与参数设置模块
5.6.1 按键消抖
采用10ms扫描,连续稳定20ms确认按下,生成短按事件。
长按可用于快速加减或保存退出设置。
5.6.2 菜单状态机
设置模块可采用状态机:
- MODE_RUN:运行显示模式
- MODE_SET_TTH:设置温度阈值
- MODE_SET_ETAL:设置效率下限
- MODE_SET_ETAH:设置效率上限
- MODE_SET_AB(可选):设置经验系数A、B
SET按键切换状态,UP/DOWN修改数值,长按SET保存退出。
这种结构清晰易实现,也便于扩展更多参数。
5.7 报警判断与声光输出模块
5.7.1 报警逻辑
报警条件:
- η < ηL → 低效率报警
- η > ηH → 高效率异常报警
- 温度超过阈值 → 温度报警(可选)
- 传感器故障 → 故障报警(可选)
报警输出应区分类型:
- 低效率:慢闪+间歇鸣
- 高效率/故障:快闪+急促鸣
并在LCD显示报警原因。
5.7.2 报警延迟与解除机制
为了稳定,建议:
- 连续3次越限才报警
- 连续3次恢复正常才解除
可通过计数器实现。
- 核心程序代码示例(C语言,AT89C52/8051风格,双MAX31855采集 + 效率计算 + LCD显示 + 按键设置 + 报警)
#include <reg52.h>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
typedef signed long s32;
// ===================== MAX31855 SPI引脚定义(软件SPI) =====================
// 共用SCK与SO,两路独立CS
sbit SPI_SCK = P1^0;
sbit SPI_SO = P1^1;
sbit CS_IN = P1^2; // 进水口MAX31855
sbit CS_OUT = P1^3; // 出水口MAX31855
// ===================== LCD1602 (4位模式) =====================
sbit LCD_RS = P2^0;
sbit LCD_E = P2^1;
sbit LCD_D4 = P2^4;
sbit LCD_D5 = P2^5;
sbit LCD_D6 = P2^6;
sbit LCD_D7 = P2^7;
// ===================== Keys =====================
sbit KEY_SET = P3^2;
sbit KEY_UP = P3^3;
sbit KEY_DOWN = P3^4;
// ===================== Alarm =====================
sbit BUZZ = P3^6;
sbit LEDA = P3^7;
// ===================== 系统节拍 =====================
volatile u32 g_ms = 0;
// ===================== 参数(可设置) =====================
u16 eta_low = 6000; // 60.00%
u16 eta_high = 9000; // 90.00%
s32 t_th_high = 8000; // 80.00℃(可选:温度阈值)
// 经验公式:eta = A - B*DT(均为百分比)
// 使用定点:A100, B100
s32 A100 = 9000; // 90.00
s32 B100 = 300; // 3.00
// ===================== 测量数据(定点:温度×100) =====================
s32 Tin100 = 0;
s32 Tout100 = 0;
s32 DT100 = 0;
s32 Eta100 = 0;
bit sensor_err_in = 0;
bit sensor_err_out = 0;
// ===================== 定时器0:1ms节拍 =====================
void Timer0_Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = 0xFC; // 1ms@12MHz
TL0 = 0x18;
ET0 = 1;
EA = 1;
TR0 = 1;
}
void Timer0_ISR(void) interrupt 1
{
TH0 = 0xFC;
TL0 = 0x18;
g_ms++;
}
// ===================== 简单延时 =====================
void delay_us(u8 t){ while(t--) _nop_(); }
void delay_ms(u16 ms){ u16 i,j; for(i=0;i<ms;i++) for(j=0;j<120;j++); }
// ===================== LCD1602驱动 =====================
void LCD_Write4(u8 dat)
{
LCD_D4 = dat & 0x01;
LCD_D5 = (dat & 0x02) ? 1 : 0;
LCD_D6 = (dat & 0x04) ? 1 : 0;
LCD_D7 = (dat & 0x08) ? 1 : 0;
}
void LCD_Enable(void)
{
LCD_E = 1; delay_us(10);
LCD_E = 0; delay_us(10);
}
void LCD_Cmd(u8 cmd)
{
LCD_RS = 0;
LCD_Write4(cmd >> 4); LCD_Enable();
LCD_Write4(cmd & 0x0F); LCD_Enable();
delay_ms(2);
}
void LCD_Data(u8 dat)
{
LCD_RS = 1;
LCD_Write4(dat >> 4); LCD_Enable();
LCD_Write4(dat & 0x0F); LCD_Enable();
delay_us(50);
}
void LCD_SetPos(u8 row, u8 col)
{
u8 addr = (row==0)?0x80:0xC0;
LCD_Cmd(addr + col);
}
void LCD_Print(char *s)
{
while(*s) LCD_Data(*s++);
}
void LCD_Init(void)
{
delay_ms(20);
LCD_RS=0; LCD_E=0;
LCD_Write4(0x03); LCD_Enable(); delay_ms(5);
LCD_Write4(0x03); LCD_Enable(); delay_ms(1);
LCD_Write4(0x03); LCD_Enable(); delay_ms(1);
LCD_Write4(0x02); LCD_Enable();
LCD_Cmd(0x28);
LCD_Cmd(0x0C);
LCD_Cmd(0x06);
LCD_Cmd(0x01);
}
// ===================== MAX31855读取32位数据 =====================
u32 MAX31855_ReadRaw(bit is_out)
{
u8 i;
u32 data = 0;
bit cs;
cs = is_out;
SPI_SCK = 0;
if(cs) CS_OUT = 0; else CS_IN = 0;
delay_us(5);
for(i=0; i<32; i++)
{
SPI_SCK = 1;
data <<= 1;
if(SPI_SO) data |= 1;
SPI_SCK = 0;
delay_us(2);
}
if(cs) CS_OUT = 1; else CS_IN = 1;
return data;
}
// ===================== 解析温度(输出:温度×100,错误标志) =====================
// MAX31855热电偶温度:bits[31:18] 14位有符号,单位0.25℃
s32 MAX31855_ParseTemp100(u32 raw, bit *err)
{
s32 tc;
u16 fault = raw & 0x7; // fault bits
if(raw & 0x00010000) // bit16 = fault
{
*err = 1;
return 0;
}
if(fault != 0)
{
*err = 1;
return 0;
}
*err = 0;
tc = (raw >> 18) & 0x3FFF; // 14-bit
// 符号扩展
if(tc & 0x2000) tc |= 0xFFFFC000;
// tc单位0.25℃ -> ×100: tc * 25
return tc * 25;
}
// ===================== 滤波(简单滑动平均,示例:4次平均) =====================
s32 Avg4(s32 a, s32 b, s32 c, s32 d)
{
return (a + b + c + d) / 4;
}
// ===================== 效率计算:Eta100 = A100 - B100 * (DT100/100) =====================
void Calc_Efficiency(void)
{
// DT100为温差×100,先得到ΔT(℃)的×100形式,再计算
// Eta100 = A100 - B100 * DT100 / 100
Eta100 = A100 - (B100 * DT100) / 100;
if(Eta100 < 0) Eta100 = 0;
if(Eta100 > 10000) Eta100 = 10000;
}
// ===================== 数值格式化(温度×100 -> xx.x) =====================
void fmt_temp(s32 t100, char *buf)
{
// buf长度>=6,例如 "25.3"
s32 t = t100;
if(t < 0)
{
*buf++ = '-';
t = -t;
}
buf[0] = (t/1000)%10 + '0';
buf[1] = (t/100)%10 + '0';
buf[2] = '.';
buf[3] = (t/10)%10 + '0';
buf[4] = 0;
}
// ===================== 数值格式化(效率×100 -> xx.xx%) =====================
void fmt_eta(u16 e100, char *buf)
{
// buf "78.25"
buf[0] = (e100/1000)%10 + '0';
buf[1] = (e100/100)%10 + '0';
buf[2] = '.';
buf[3] = (e100/10)%10 + '0';
buf[4] = (e100)%10 + '0';
buf[5] = 0;
}
// ===================== 显示更新(两页轮换) =====================
void LCD_ShowPage0(void)
{
char b1[8], b2[8], b3[8];
LCD_SetPos(0,0);
LCD_Print("IN:");
fmt_temp(Tin100, b1); LCD_Print(b1);
LCD_Print(" OUT:");
fmt_temp(Tout100, b2); LCD_Print(b2);
LCD_SetPos(1,0);
LCD_Print("DT:");
fmt_temp(DT100, b3); LCD_Print(b3);
LCD_Print(" ETA:");
fmt_eta((u16)Eta100, b1); LCD_Print(b1);
}
void LCD_ShowPage1(void)
{
char b1[8], b2[8], b3[8];
LCD_SetPos(0,0);
LCD_Print("ETA:");
fmt_eta((u16)Eta100, b1); LCD_Print(b1);
LCD_Print(" L:");
fmt_eta(eta_low, b2); LCD_Print(b2);
LCD_SetPos(1,0);
LCD_Print("H:");
fmt_eta(eta_high, b3); LCD_Print(b3);
if(sensor_err_in || sensor_err_out) LCD_Print(" ERR");
else LCD_Print(" OK ");
}
// ===================== 按键扫描(简单消抖) =====================
u8 Key_Scan(void)
{
static u8 last_set=1, last_up=1, last_down=1;
u8 now_set = KEY_SET;
u8 now_up = KEY_UP;
u8 now_down = KEY_DOWN;
if(last_set==1 && now_set==0){ last_set=0; return 1; }
if(last_up==1 && now_up==0 ){ last_up=0; return 2; }
if(last_down==1&& now_down==0){ last_down=0; return 3; }
last_set = now_set;
last_up = now_up;
last_down = now_down;
return 0;
}
// ===================== 设置菜单状态 =====================
typedef enum {
MODE_RUN = 0,
MODE_SET_ETAL,
MODE_SET_ETAH,
MODE_SET_TTH
} Mode_t;
Mode_t g_mode = MODE_RUN;
void Apply_SettingKey(u8 ev)
{
if(ev == 0) return;
if(ev == 1) // SET
{
if(g_mode == MODE_RUN) g_mode = MODE_SET_ETAL;
else if(g_mode == MODE_SET_ETAL) g_mode = MODE_SET_ETAH;
else if(g_mode == MODE_SET_ETAH) g_mode = MODE_SET_TTH;
else g_mode = MODE_RUN;
}
else if(ev == 2) // UP
{
if(g_mode == MODE_SET_ETAL && eta_low < 9900) eta_low += 50; // +0.50%
if(g_mode == MODE_SET_ETAH && eta_high < 10000) eta_high += 50;
if(g_mode == MODE_SET_TTH) t_th_high += 100; // +1.00℃
}
else if(ev == 3) // DOWN
{
if(g_mode == MODE_SET_ETAL && eta_low > 0) eta_low -= 50;
if(g_mode == MODE_SET_ETAH && eta_high > 0) eta_high -= 50;
if(g_mode == MODE_SET_TTH) t_th_high -= 100;
}
}
// ===================== 报警判断与输出控制 =====================
void Alarm_Update(void)
{
bit alarm = 0;
if(sensor_err_in || sensor_err_out) alarm = 1;
// 温度阈值(可选)
if(Tin100 > t_th_high || Tout100 > t_th_high) alarm = 1;
// 效率越限
if((u16)Eta100 < eta_low) alarm = 1;
if((u16)Eta100 > eta_high) alarm = 1;
if(alarm)
{
LEDA = 0;
BUZZ = 1;
}
else
{
LEDA = 1;
BUZZ = 0;
}
}
// ===================== 主函数 =====================
void main(void)
{
u32 last_sample = 0;
u32 last_disp = 0;
u32 last_key = 0;
u8 page = 0;
s32 t_in[4], t_out[4];
u8 idx = 0;
CS_IN = 1;
CS_OUT = 1;
SPI_SCK = 0;
LEDA = 1; BUZZ = 0;
LCD_Init();
Timer0_Init();
while(1)
{
// 10ms扫描按键
if(g_ms - last_key >= 10)
{
u8 ev;
last_key = g_ms;
ev = Key_Scan();
Apply_SettingKey(ev);
}
// 1秒采样一次温度
if(g_ms - last_sample >= 1000)
{
u32 raw_in, raw_out;
last_sample = g_ms;
raw_in = MAX31855_ReadRaw(0);
raw_out = MAX31855_ReadRaw(1);
t_in[idx] = MAX31855_ParseTemp100(raw_in, &sensor_err_in);
t_out[idx] = MAX31855_ParseTemp100(raw_out, &sensor_err_out);
idx++;
if(idx >= 4) idx = 0;
// 滑动平均
Tin100 = Avg4(t_in[0], t_in[1], t_in[2], t_in[3]);
Tout100 = Avg4(t_out[0], t_out[1], t_out[2], t_out[3]);
DT100 = Tout100 - Tin100;
if(DT100 < 0) DT100 = -DT100; // 若进出口接反,取绝对值
if(!sensor_err_in && !sensor_err_out)
{
Calc_Efficiency();
}
Alarm_Update();
}
// 2秒切换显示页(设置模式时可固定显示设置界面,这里简化)
if(g_ms - last_disp >= 2000)
{
last_disp = g_ms;
if(page == 0) { LCD_ShowPage0(); page = 1; }
else { LCD_ShowPage1(); page = 0; }
}
}
}
- 关键模块深化说明与工程化优化建议
7.1 温差法经验公式的标定流程建议
为了让效率计算更接近真实值,应进行标定:
- 在水泵正常工况下,用传统方法测得真实效率η_real(或参考铭牌效率)
- 同时记录温差ΔT
- 通过多组数据拟合A、B、C参数
- 将拟合参数写入系统(可按键输入或EEPROM存储)
标定后温差法可较准确反映效率变化趋势,并用于报警。
7.2 温度测量精度提升措施
- 热电偶安装点要合理并加保温层,减少环境散热影响。
- 使用导热硅脂或金属接触件提高传热效率。
- 采样数据滤波并设置稳定判定。
- 若温差很小,可通过提高采样次数、延长平均窗口提升稳定性。
- 检查MAX31855模块与热电偶连接是否牢固,避免接触电阻导致误差。
7.3 报警策略优化
- 加入报警确认次数,避免瞬态波动误报警。
- 区分报警类型并采用不同声光节奏。
- 增加“静音键”与“报警保持/复位”机制,提升现场使用体验。
- 增加继电器联动输出(可选),效率过低时自动停泵或启动备用泵(需严格安全评估)。
7.4 参数存储与掉电保护
建议加入EEPROM:
- 保存ηL、ηH、温度阈值、经验公式参数A/B
- 上电自动加载,降低维护成本
并在写入时使用校验字节,防止数据损坏。
7.5 通信与远程监测扩展方向
系统可扩展:
- 系统测试方案与验证要点
8.1 温度采集测试
- 在恒温水浴或已知温度环境中验证Tin、Tout准确性。
- 检查两路温度的一致性与偏差,必要时进行零点校准。
- 验证MAX31855故障检测:拔掉热电偶应显示ERR并报警。
8.2 温差与效率计算测试
- 人为制造不同温差(改变流量、加热)检查ΔT计算是否正确。
- 检查效率计算范围是否在0~100%。
- 修改A、B参数验证效率随温差变化趋势是否符合预期。
8.3 显示与按键测试
- LCD显示是否清晰、无乱码、页面切换正确。
- 按键设置ηL、ηH与温度阈值是否可正确修改并立即生效。
- 参数越界处理是否正确(例如ηL不得大于ηH)。
8.4 报警功能测试
- 设置ηL较高,模拟低效率(增大ΔT)触发报警。
- 设置ηH较低,模拟高效率异常触发报警。
- 温度超过阈值触发报警。
- 误报警抑制策略验证(连续超限才报警、解除延迟等)。
- 总结
本设计完成了一套基于AT89C52单片机的水泵效率温差法测量与报警系统,采用两只E型热电偶配合MAX31855模块实现水泵进出口温度的高可靠采集,通过单片机计算温差并依据经验公式估算水泵效率,利用LCD1602显示效率上下限与当前效率值,并支持按键设置温度阈值与效率上下限。当效率超出设定范围或传感器出现异常时,系统触发声光报警,帮助运维人员及时发现水泵效率下降、异常发热或传感器故障等问题。
在电路设计方面,系统采用模块化结构,包含单片机最小系统、热电偶测温模块、MAX31855转换模块、显示、按键与报警、电源供电等模块,易于调试与扩展;在程序设计方面,采用定时采样、滤波、定点运算与菜单状态机实现实时测量与参数可配置,并可进一步扩展EEPROM掉电保存、通信上传与历史数据记录等功能。
该系统具有成本低、部署方便、维护简单的优势,适用于水泵运行状态在线监测与节能管理场景,同时也具备较强的教学示范价值与工程扩展潜力。
211