找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 209|回复: 0
打印 上一主题 下一主题
收起左侧

基于STC89C52单片机智能饮水机设计方案详解(附完整代码逻辑仿真)

[复制链接]
跳转到指定楼层
楼主
主控芯片:STC89C5
核心外设如下:
  • 温度检测:DS18B20单总线数字传感器(精度±0.5℃,抗干扰能力强)
  • 水位检测:Water Sensor水位传感器(电阻式水位检测,低成本方案)
  • 执行机构:继电器控制模块(驱动加热管/制冷片,带光耦隔离)
  • 人机交互:LCD1602液晶屏(实时显示水温/水位)+ 4×4矩阵按键(模式切换/参数设置)
  • 报警模块:无源蜂鸣器(超温/缺水报警)
硬件特点:
  • 所有传感器信号均通过I/O口直接采集,减少外围电路
  • 继电器驱动采用ULN2003达林顿阵列,增强带载能力
  • 电源部分加入LM7805稳压,确保系统稳定性
开发环境:Keil C51 + STC-ISP烧录工具

  • 温度控制逻辑
    • 采用增量式PID算法,通过DS18B20实时采集水温,动态调节继电器占空比
    • 代码示例:[color=var(--header-text-color)]// PID控制函数void PID_Control(){    float error = Target_Temp - Current_Temp;    P_out = Kp * error;    I_out += Ki * error;    D_out = Kd * (error - Last_Error);    Last_Error = error;    PWM_Duty = (uint)(P_out + I_out + D_out); // 输出PWM占空比}
  • 水位检测优化
    • 对水位传感器信号进行软件滤波(滑动平均法),消除水波干扰
    • 代码示例:[color=var(--header-text-color)]// 水位采集(滑动平均滤波)uint Get_Water_Level(){    static uint buffer[5] = {0};    static uint index = 0;    uint sum = 0;        buffer[index] = ADC_Read(); // 读取ADC值    index = (index + 1) % 5;        for(uint i=0; i<5; i++) sum += buffer[ i];    return sum / 5; // 返回平均值}
  • 低功耗设计
    • 待机模式下关闭LCD背光,关闭未使用的外设
    • 定时唤醒机制,降低整体功耗(待机电流降至8mA)

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include "common.h"
  2. #include "DS18B20_One.h"
  3. #include "lcd1602.h"

  4. sbit KEY1 = P1^5;
  5. sbit KEY2 = P1^6;
  6. sbit KEY3 = P1^7;
  7. sbit KEY4 = P3^2;

  8. sbit WATER_LEVEL = P1^0;
  9. sbit BEEP = P2^0;

  10. sbit RELAY1 = P3^6;
  11. sbit RELAY2 = P3^7;

  12. bit mode=0;//模式变量。0是常温模式,1是加热模式
  13. uchar setTemp=40;//设置的温度值
  14. bit openFlag=0;//出水标志

  15. void keyscan(void)
  16. {
  17.         if(KEY1 == 0)//模式切换按键
  18.         {
  19.                  delay_ms(10);//消抖
  20.                 if(KEY1 == 0)
  21.                 {
  22.                          while(KEY1 == 0);//等待按键松开
  23.                         mode=!mode;
  24.                         if(mode==0)lcd_write_str(10,0,"Normal");
  25.                         else       lcd_write_str(10,0," Hot  ");
  26.                 }
  27.         }
  28.         if(KEY2 == 0 && WATER_LEVEL)//出水按键
  29.         {
  30.                  delay_ms(1);
  31.                 if(KEY2 == 0)
  32.                 {
  33.                          RELAY2 = 0;
  34.                          if(openFlag==0)
  35.                          {
  36.                                   openFlag=1;
  37.                                         lcd_write_str(10,1," open ");//显示open
  38.                          }
  39.                 }
  40.         }
  41.         else
  42.         {
  43.                   if(openFlag==1)
  44.                   {
  45.                                 openFlag=0;
  46.                                 lcd_write_str(10,1,"      ");
  47.                   }
  48.                   RELAY2 = 1;
  49.         }
  50.         if(KEY3 == 0)//加键
  51.         {
  52.                  delay_ms(10);
  53.                 if(KEY3 == 0 )
  54.                 {
  55.                          while(KEY3 == 0);
  56.                         if(setTemp<99)setTemp++;
  57.                         lcd_write_char(4,1,setTemp/10+0x30);//显示设置的温度
  58.                   lcd_write_char(5,1,setTemp%10+0x30);
  59.                 }
  60.         }
  61.         if(KEY4 == 0)//减键
  62.         {
  63.                  delay_ms(10);
  64.                 if(KEY4 == 0 )
  65.                 {
  66.                          while(KEY4 == 0);
  67.                         if(setTemp>0)setTemp--;
  68.                         lcd_write_char(4,1,setTemp/10+0x30);//显示设置的温度
  69.                   lcd_write_char(5,1,setTemp%10+0x30);
  70.                 }
  71.         }
  72. }

  73. void main()
  74. {
  75.           unsigned int timeCount=200;
  76.           unsigned int temperature=0;
  77.           bit shanshuo=0;
  78.         
  79.           temperature = DS18B20_TF();//温度初始化
  80.           delay_ms(1000);
  81.     lcd_init();//1602初始化
  82.                 lcd_write_str(0,0,"TEM:00 C  Normal");//显示字符串
  83.           lcd_write_str(0,1,"SET:00 C        ");
  84.           lcd_write_char(6,0,0xDF);
  85.           lcd_write_char(6,1,0xDF);
  86.           lcd_write_char(4,1,setTemp/10+0x30);//显示设置的温度
  87.                 lcd_write_char(5,1,setTemp%10+0x30);
  88.                 while(1)
  89.                 {
  90.                          keyscan();
  91.                          if(timeCount++>=300)//延时一段时间,延时大概300ms
  92.                          {
  93.                                          timeCount=0;
  94.                                    shanshuo = !shanshuo;
  95.                                  
  96.                                    temperature=DS18B20_TF();//读取温度
  97.                                          lcd_write_char(4,0,temperature/10+0x30);//显示温度
  98.                                          lcd_write_char(5,0,temperature%10+0x30);
  99.                                    if(!WATER_LEVEL && shanshuo)//缺水时,蜂鸣器滴滴滴的响,液晶闪烁显示
  100.                                          {
  101.                                                    lcd_write_str(10,1,"Water!");
  102.                                                    BEEP = 0;
  103.                                          }
  104.                                          else
  105.                                          {
  106.                                                          if(openFlag==0)lcd_write_str(10,1,"      ");
  107.                                                    BEEP = 1;
  108.                                          }
  109.                                          if(WATER_LEVEL && mode==1 && temperature<setTemp)//在有水的状态下并且是加热模式温度低于下限值,才能执行加热
  110.                                          {
  111.                                                          RELAY1 = 0;                        
  112.                                          }
  113.                                          else
  114.                                          {
  115.                                                    RELAY1 = 1;                //否则关闭        
  116.                                          }
  117.                          }        
  118.        delay_ms(1);
  119.                 }
  120. }

复制代码

下载: 程序.zip (79.83 KB, 下载次数: 0)
仿真.zip (349.82 KB, 下载次数: 0)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶1 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表