基于51单片机的智能电热水器设计

基于51单片机的智能电热水器设计

一、系统概述与核心功能

1. 系统定位

基于51单片机的智能电热水器以“温度监测-智能加热-安全保护-人机交互”为核心,实现水温自动调节、定时加热、防干烧、漏电保护等功能,适用于家庭浴室等场景,提供安全、节能的热水供应。

2. 核心功能模块

模块 功能描述
温度采集 使用DS18B20温度传感器,实时监测水温,精度±0.5℃
加热控制 通过继电器控制加热棒电源,支持PWM调功(可选)或开关控制
显示模块 数码管或LCD1602显示当前水温、设定温度、工作模式
按键设置 3个按键:模式切换、温度加、温度减,支持长按快速调节
安全保护 防干烧(水位传感器或软件判断)、漏电检测(漏电保护插头)、超温断电
定时功能 支持24小时定时,预约加热时间
节能模式 根据使用习惯自动调整加热策略,减少保温能耗

二、硬件设计方案

1. 核心硬件选型

模块 型号 关键参数 接口方式
主控MCU STC89C52RC 8位单片机,8KB Flash,512B RAM,3个定时器,32个IO口 核心控制器
温度传感器 DS18B20 单总线接口,测温范围-55125℃,精度±0.5℃(085℃) P2.0(单总线)
加热控制 继电器模块 10A/250V AC,控制加热棒电源,低电平触发 P1.0(继电器控制)
显示模块 LCD1602 16×2字符液晶,显示水温、设定温度、模式 P0口(数据线),P2.5-P2.7(控制线)
按键模块 轻触按键×3 模式键、加键、减键,上拉输入 P3.0-P3.2
电源模块 5V/2A电源适配器 输入220V AC,输出5V DC,给单片机和继电器供电 电源输入
安全模块 漏电保护插头 检测到漏电电流>10mA时,0.1秒内切断电源 串联在加热棒电源线上
水位检测 电极式水位传感器 检测水箱水位,防止干烧 P1.1(水位检测)

2. 硬件电路设计要点

2.1 核心电路连接

2.2 安全设计

三、软件设计与核心代码

1. 系统架构(前后台系统)

采用前后台系统,主循环为前台,定时器中断为后台,核心流程:

  1. 初始化:配置IO口、定时器、LCD、DS18B20。

  2. 主循环

    • 读取温度和水位。
    • 扫描按键,更新设定温度和工作模式。
    • 根据当前温度、设定温度和水位,控制加热继电器。
    • 更新LCD显示。
  3. 定时器中断:每1秒更新一次时间,用于定时功能。

2. 核心代码实现(基于Keil C)

2.1 DS18B20驱动(单总线时序)

#include <reg52.h>
#include <intrins.h>

sbit DQ = P2^0;  // DS18B20数据线

// 延时函数(微秒级)
void DelayUs(unsigned int us) {
    while (us--) {
        _nop_(); _nop_(); _nop_(); _nop_();
    }
}

// DS18B20复位
bit DS18B20_Reset() {
    bit presence;
    DQ = 1;
    DelayUs(1);
    DQ = 0;          // 拉低总线480us以上
    DelayUs(500);
    DQ = 1;          // 释放总线
    DelayUs(60);      // 等待15-60us
    presence = DQ;    // 读取存在脉冲
    DelayUs(400);     // 等待复位完成
    return presence;   // 0=存在,1=不存在
}

// 写一个字节
void DS18B20_WriteByte(unsigned char dat) {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        DQ = 0;
        DQ = dat & 0x01;  // 写一位
        DelayUs(60);       // 保持60us以上
        DQ = 1;           // 释放总线
        dat >>= 1;
    }
}

// 读一个字节
unsigned char DS18B20_ReadByte() {
    unsigned char i, dat = 0;
    for (i = 0; i < 8; i++) {
        DQ = 0;           // 拉低总线开始读时隙
        dat >>= 1;
        DQ = 1;           // 释放总线
        if (DQ) dat |= 0x80;  // 读取数据位
        DelayUs(60);       // 等待时隙结束
    }
    return dat;
}

// 读取温度值(摄氏度,精度0.0625℃)
float DS18B20_ReadTemp() {
    unsigned char temp_l, temp_h;
    int temp;
    float temperature;
    
    DS18B20_Reset();
    DS18B20_WriteByte(0xCC);  // 跳过ROM命令
    DS18B20_WriteByte(0x44);  // 启动温度转换
    DelayUs(750000);          // 等待转换完成(12位精度需750ms)
    
    DS18B20_Reset();
    DS18B20_WriteByte(0xCC);  // 跳过ROM命令
    DS18B20_WriteByte(0xBE);  // 读取暂存器
    temp_l = DS18B20_ReadByte();
    temp_h = DS18B20_ReadByte();
    
    temp = (temp_h << 8) | temp_l;
    temperature = temp * 0.0625;  // 转换为摄氏度
    return temperature;
}

2.2 LCD1602驱动

#include <reg52.h>

sbit RS = P2^5;
sbit RW = P2^6;
sbit E  = P2^7;
#define DATA_PORT P0

// 延时毫秒
void DelayMs(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
        for (j = 0; j < 114; j++);
}

// 写命令
void LCD_WriteCmd(unsigned char cmd) {
    RS = 0;
    RW = 0;
    DATA_PORT = cmd;
    E = 1;
    DelayMs(1);
    E = 0;
    DelayMs(1);
}

// 写数据
void LCD_WriteData(unsigned char dat) {
    RS = 1;
    RW = 0;
    DATA_PORT = dat;
    E = 1;
    DelayMs(1);
    E = 0;
    DelayMs(1);
}

// 初始化LCD
void LCD_Init() {
    LCD_WriteCmd(0x38);  // 8位数据,两行显示,5×7点阵
    LCD_WriteCmd(0x0C);  // 显示开,光标关,闪烁关
    LCD_WriteCmd(0x06);  // 写入数据后光标右移
    LCD_WriteCmd(0x01);  // 清屏
    DelayMs(2);
}

// 显示字符串
void LCD_ShowString(unsigned char row, unsigned char col, char *str) {
    unsigned char addr;
    if (row == 0) addr = 0x80 + col;  // 第一行
    else addr = 0xC0 + col;              // 第二行
    LCD_WriteCmd(addr);
    while (*str != '\0') {
        LCD_WriteData(*str);
        str++;
    }
}

2.3 主程序与加热控制

#include <reg52.h>
#include <string.h>

// 全局变量
float current_temp = 0.0;    // 当前温度
float set_temp = 40.0;       // 设定温度
bit heat_flag = 0;           // 加热标志
bit water_level_ok = 1;      // 水位正常(1=有水,0=无水)
unsigned char work_mode = 0;  // 工作模式:0=手动,1=定时

// 按键定义
sbit KEY_MODE = P3^0;       // 模式键
sbit KEY_ADD  = P3^1;       // 加键
sbit KEY_SUB  = P3^2;       // 减键
sbit RELAY    = P1^0;       // 继电器控制
sbit WATER_LEVEL = P1^1;    // 水位检测

// 定时器0初始化(1ms中断)
void Timer0_Init() {
    TMOD &= 0xF0;      // 清除T0控制位
    TMOD |= 0x01;      // 设置T0为模式1(16位定时器)
    TH0 = 0xFC;        // 1ms定时初值(11.0592MHz)
    TL0 = 0x66;
    ET0 = 1;           // 允许T0中断
    EA = 1;            // 允许总中断
    TR0 = 1;           // 启动T0
}

// 加热控制函数
void Heat_Control() {
    if (!water_level_ok) {  // 无水,禁止加热
        RELAY = 1;          // 继电器断开(低电平触发则改为0)
        heat_flag = 0;
        return;
    }
    
    if (current_temp < set_temp - 1.0) {  // 低于设定温度1℃时加热
        RELAY = 0;          // 继电器闭合,开始加热
        heat_flag = 1;
    } else if (current_temp > set_temp + 1.0) {  // 高于设定温度1℃时停止
        RELAY = 1;          // 继电器断开,停止加热
        heat_flag = 0;
    }
    // 在±1℃范围内保持原状态,避免频繁开关
}

// 按键扫描
void Key_Scan() {
    static bit key_mode_lock = 0, key_add_lock = 0, key_sub_lock = 0;
    
    // 模式键
    if (KEY_MODE == 0 && !key_mode_lock) {
        key_mode_lock = 1;
        work_mode = (work_mode + 1) % 2;  // 0→1→0循环
        DelayMs(10);
    } else if (KEY_MODE == 1) {
        key_mode_lock = 0;
    }
    
    // 加键
    if (KEY_ADD == 0 && !key_add_lock) {
        key_add_lock = 1;
        if (set_temp < 75.0) set_temp += 1.0;  // 最高75℃
        DelayMs(10);
    } else if (KEY_ADD == 1) {
        key_add_lock = 0;
    }
    
    // 减键
    if (KEY_SUB == 0 && !key_sub_lock) {
        key_sub_lock = 1;
        if (set_temp > 30.0) set_temp -= 1.0;  // 最低30℃
        DelayMs(10);
    } else if (KEY_SUB == 1) {
        key_sub_lock = 0;
    }
}

// 显示更新
void Display_Update() {
    char temp_str[16];
    // 第一行:当前温度
    sprintf(temp_str, "Cur:%.1fC", current_temp);
    LCD_ShowString(0, 0, temp_str);
    // 第二行:设定温度和工作模式
    sprintf(temp_str, "Set:%.1fC M%d", set_temp, work_mode);
    LCD_ShowString(1, 0, temp_str);
}

void main() {
    // 初始化
    LCD_Init();
    Timer0_Init();
    RELAY = 1;  // 初始关闭加热
    
    LCD_ShowString(0, 0, "Smart Water Heater");
    LCD_ShowString(1, 0, "Initializing...");
    DelayMs(1000);
    
    while (1) {
        // 读取温度(每1秒读一次,实际应在定时器中断中读取)
        current_temp = DS18B20_ReadTemp();
        
        // 读取水位(假设低电平表示有水)
        water_level_ok = (WATER_LEVEL == 0) ? 1 : 0;
        
        // 按键扫描
        Key_Scan();
        
        // 加热控制
        Heat_Control();
        
        // 更新显示
        Display_Update();
        
        DelayMs(1000);  // 延时1秒
    }
}

// 定时器0中断服务函数
void Timer0_ISR() interrupt 1 {
    static unsigned int sec_count = 0;
    TH0 = 0xFC;  // 重装初值
    TL0 = 0x66;
    
    sec_count++;
    if (sec_count >= 1000) {  // 1秒到
        sec_count = 0;
        // 这里可以添加定时功能逻辑
    }
}

参考代码 基于51单片机的智能电热水器 www.youwenfan.com/contentcst/133158.html

四、关键技术与优化

1. 温度控制优化

2. 安全保护设计

3. 节能设计

五、系统调试与扩展

1. 调试步骤

阶段 操作 工具
硬件调试 测量DS18B20供电电压,检查继电器动作 万用表、示波器
温度测试 用标准温度计对比DS18B20读数,校准误差 标准温度计、热水杯
功能测试 测试加热控制、按键设置、LCD显示是否正常 实际操作测试
安全测试 模拟干烧、超温情况,验证保护功能 移除水位传感器、加热至超温

2. 扩展功能

六、总结

基于51单片机的智能电热水器设计通过DS18B20实现精准温度采集,继电器控制加热,LCD1602提供人机交互,软件保护算法确保使用安全。

专注于matlab/simulink,电子电路,编程