找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1565|回复: 1
收起左侧

基于51单片机的水温控制系统Proteus仿真设计文档

[复制链接]
ID:651971 发表于 2022-4-24 09:49 | 显示全部楼层 |阅读模式
里面只有仿真原理图,不含程序,希望可以帮到大家

本系统以AT89C51单片机为核心,有按键控制电路,DS18B20温度检测电路,LCD1602显示电路,加热电路。DS18B20温度传感器实时检测温度并进行转化,检测到的温度值通过LCD1602液晶屏进行实时显示,并可以通过单片机AT89C51外部扩展的按键电路来设定温度值,通过加热电路对水温进行控制,升温时开启加热电路,降温时关闭加热电路,实现对温度在0℃~100℃控制的自动化。
主要技术指标及要求:
1、单片机实现水温度控制,水温范围为0~100℃,测量精度为1℃;
2、实时显示当前的温度值;
3、具有温度设定和加热功能。
设计内容:
1、分析设计要求,明确性能指标;查阅资料、设计方案分析对比。
2、论证并确定合理的总体设计方案,绘制总体结构框图,分析工作原理。
3、完成各单元具体电路的设计:单片机最小系统、温度测量与控制、按键、显示等电路。包括元器件选择、工作原理分析。
4、设计软件流程图及源程序,完成系统的Proteus仿真调试。

2.1核心电路设计与论证
方案一:采用AT89C51单片机设计的水温控制器,AT89C51运算速度高,外围扩展电路容易,软件编程简单容易,功耗低,体积小,成本低。
方案二:采用FPGA,它的名称是现场可编程门列阵,它是集成度最高的一种电路,一些较为复杂的数学式子和逻辑运算都可以通过它来完成,运算精度高。可通过EDA软件进行仿真。
本系统选用方案一作为设计方案。在水温控制系统中稳定性好,且制作成本较低,符合设计要求。
2.2 显示模块论证
方案一:用四位数码管显示,需要数码管驱动电路,需要占用8条数据线和4条地址线,共12个引脚。显示内容较少,而且需要选择动态扫描方式。
方案二:选用LCD1602显示密码。显示内容丰富,可以显示字符,程序配套,易于编程,8条数据线和rw读写、en片选、rs数据/命令选择线,共需11个引脚,无驱动电路。
综上所述,选择方案二显示。
2.3 温度检测电路模块
方案一:采用温度传感器AD590,AD590检测输出的信号是模拟信号,因此需要变成数字信号,需要A/D转换电路。
方案二:采用DS18B20。DS18B20将半导体温敏器件、A/D转换器、存储器等做在一个很小的集成电路芯片上。测温范围为-55℃~+125℃,测温精度为士0.5℃。
方案二与方案一相比,设计电路简单,无需进行A/D转换,所以选择方案二。
综上,本文采用AT89C51单片机位主控元件,LCD1602液晶屏显示方式,以温度传感器DS18B20为温度检测电路,加上按键电路对温度值设定以及加热电路,构成一个安全可靠的水温控制系统。

2.4总体设计
本设计采用以AT89C51单片机控制方案。 利用单片机灵活的编程设计和丰富的I/O端口,及其控制的准确性,不但能实现基本的温度显示与检测功能,还能根据实际需要添加键盘控制电路、加热功能。系统结构框图如图2.1所示。

图2.1系统结构框图

第3章 单元电路设计

3.1按键控制模块
本设计中共设置了3个按键,分别为温度设置按键、加温度按键、减温度按键。如图3.1所示,为按键控制电路。从上到下分别为按键K1、K2、K3 ,K1为温度设置按键,K2为加温度按键,K3为减温度按键。通过温度设置按键K1、K2、K3可以设置温度,在液晶屏上显示出来,并且可根据设置的温度与实际温度进行大小比较,进而控制加热电路。

图3.1 按键控制电路
3.2显示模块
本设计采用LCD1602作为显示装置,LCD1602显示屏具有体积小、功耗低、显示内容丰富、超薄轻巧等优点,因此,在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用,现在字符型液晶显示模块已经是单片机应用设计中最常用的信息显示器件了。可以显示两行,每行16个字符,采用单+5V电源供电,外围电路配置简单,价格便宜,具有很高的性价比。
如图3.2所示,为LCD1602液晶显示电路。其中液晶屏的RS、RW、EN引脚分别接到单片机的2.2、2.1、2.0引脚,D0~D7引脚分别与单片机的P0.0~P0.7口相接。RP1为电阻排,上拉电压。LCD1602在运行时显示两行字,第一行显示字为英文字母“Temperture”,第二行的显示为温度值。


图3.2 显示电路
3.3温度检测模块
连续3次输入密码错误将产生报警,通过蜂鸣器来实现报警功能。每当有按键按下时,蜂鸣器都会鸣叫一声。当密码输入正确,顺利开锁时,发光二极管就会被点亮,上锁时,二极管熄灭。电路图如图3.3所示。

图3.3 温度检测电路
3.4加热模块
当设置温度高于当前温度传感器DS18B20检测到的温度时,单片机AT89C51的P1.6引脚会输出低电平,使继电器开关闭合,加热电路接通。加热电路如图3.4所示。

图3.4 加热电路
3.5单片机最小系统
AT89C51 是一种带 4K 字节闪烁可编程可擦除只读存储器的低电压,高性能 CMOS8 位微处理器,俗称单片机。该器件采用 ATMEL 高密度非易失存储器制造技术制造,与工业标准的 MCS-51 指令集和输出管脚相兼容。由于将多功能 8位 CPU 和闪烁存储器组合在单个芯片中,ATMEL 的AT89C51 是一种高效微控制器。单片机 XIAL1 和XIAL2 别接 30PF 的电容,中间再并联一个12MHz的晶振,形成单片机的晶振电路。由AT89C51,晶振电路和复位电路共同组成了单片机最小系统,如图3.5所示,单片机最小系统电路图。

图3.5 单片机最小系统电路图

第4章 系统软件设计

4.1 主程序的设计
本设计第一次进入此系统的时候,开始会进行初始化操作,首先由温度传感器DS18B20开始检测温度,然后在液晶屏LCD上显示检测到的温度,当有按键按下时,系统会对设置的温度进行检测,并与实际温度比较大小,判断是否开启加热电路。具体流程如图4.1所示。
            

图4.1 主程序流程图
4.2 DS18B20程序设计
DS18B20温度传感器程序的主要功能包括初始化,数据读取与写入数据,执行完一系列的命令后返回。如图4.2所示,为DS18B20程序设计图。


图4.2 DS18B20程序设计图
第5章 系统仿真与调试
使用Proteus绘制原理图,然后将Keil生成的hex程序文件载入到单片机中,点击运行:
  • 开机检测温度仿真
如图5.1所示,为常温时显示温度图。常温时温度传感器检测到的温度,显示在液晶屏LCD1602上。

图5.1 常温时显示温度
如图5.2 所示,为常温时,温度传感器检测温度的仿真图。

图5.2 温度传感器检测温度

2.按键控制仿真
当设置温度高于传感器检测到的温度时,系统会启动加热电路。用灯泡代替加热器,灯泡发光,说明加热器在工作,灯泡不发光,说明加热器未工作。如图5.3所示,为设置温度为95℃时的仿真图,图5.4为设置温度后,加热电路加热时的仿真图。


图5.3 设置升温仿真图

图5.4 加热电路开启加热
温度低于传感器检测到的温度时,加热电路自动关闭,如图5.4所示,为设置降温仿真图,如图5.5所示,为加热电路关闭加热。

图5.4 设置降温仿真图

图5.5 加热电路关闭加热

              主要代码是:
  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit tempt=P2^3;
  5. uint u_temp;   //定义无符号整型形参
  6. float f_temp;  //定义浮点型形参
  7. void display_tempt(uint date)                //温度数据显示
  8.                             {
  9.                                           uchar i,j,k;
  10.                                           i=date/100;                                          //十位
  11.                                           j=date%100/10;                            //个位
  12.                                           k=date%100%10;                            //小数位
  13.                                           write_com(0x80+0x40+5);
  14.                                           write_data(disp[i]);
  15.                                           write_data(disp[j]);
  16.                                           write_data('.');
  17.                                           write_data(disp[k]);            
  18.                             }
  19.                             void reset_tempt()                              //DS18B20复位,初始化
  20.                             {
  21.                                           uint i;
  22.                                           tempt=0;
  23.                                           i=90;                                          //延时
  24.                                           while(i>0)i--;
  25.                                           tempt=1;
  26.                                           i=4;                                                        //延时
  27.                                           while(i>0)i--;
  28.                             }
  29.                             bit read_bit()                                          //读一位DS18B20数据
  30.                             {
  31.                                           uint i;
  32.                                           bit dat;
  33.                                           tempt=0;
  34.                                           i++;                                                        //延时
  35.                                           tempt=1;
  36.                                           i++;                                                        //延时
  37.                                           i++;
  38.                                           dat=tempt;
  39.                                           i=8;                                                        //延时
  40.                                           while(i>0)i--;
  41.                                           return dat;
  42.                             }
  43.                             uchar read_tempt()                            //读一个字节DS18B20数据
  44.                             {
  45.                                           uchar i,j,dat;
  46.                                           dat=0;
  47.                                           for(i=1;i<=8;i++)
  48.                                           {
  49.                                                         j=read_bit();
  50.                                                         dat=(j<<7)|(dat>>1); //将读取的数据位按读取先后顺序,
  51.                                           }                                                                      //从低位到高位(从右往左)排列保存到dat
  52.                                           return dat;
  53.                             }
  54.                             void write_byte(uchar dat)                            //写一个字节数据到DS18B20
  55.                             {
  56.                                           uint i;
  57.                                           uchar j;
  58.                                           bit testbit;
  59.                                           for(j=1;j<=8;j++)
  60.                                           {
  61.                                                         testbit=dat&0x01;                            //每次只写一位数据
  62.                                                         dat=dat>>1;
  63.                                                         if(testbit)
  64.                                                         {
  65.                                                                       tempt=0;
  66.                                                                       i++;                                                        //延时
  67.                                                                       tempt=1;
  68.                                                                       i=8;                                                        //延时
  69.                                                                       while(i>0)i--;
  70.                                                         }            
  71.                                                         else
  72.                                                         {
  73.                                                                       tempt=0;
  74.                                                                       i=8;                                                        //延时
  75.                                                                       while(i>0)i--;
  76.                                                                       tempt=1;
  77.                                                                       i++;                            i++;                            //延时}  }  }
  78.                                void convert_tempt()              //DS18B20开始获取温度并进行转换
  79.                             {
  80.                                           reset_tempt();
  81.                                           delay(1);
  82.                                           write_byte(0xcc);
  83.                                           write_byte(0x44);
  84.                             }
  85.                             uint get_tempt()                            //读取DS18B20寄存器中的温度数据
  86.                             {
  87.                                           uchar a,b;
  88.                                           reset_tempt();
  89.                                           delay(1);
  90.                                           write_byte(0xcc);
  91.                                           write_byte(0xbe);
  92.                                           a=read_tempt();
  93.                                           b=read_tempt();
  94.                                           u_temp=b;
  95.                                           u_temp<<=8;
  96.                                           u_temp=u_temp|a;
  97.                                           f_temp=u_temp*0.0625;  //精度为12位,所以分辨率为0.0625
  98.                                           u_temp=f_temp*10 ;                 //乘以10,将实际温度扩大10倍                                                                                    return u_temp;                               //返回的u_temp是整型数据
  99.                             }
  100.                             void display()                                          //静态文字显示
  101.                             {
  102.                                           uchar i,j;
  103.                                           write_com(0x80+3);
  104.                                           for(i=0;i<10;i++)
  105.                                           {
  106.                                                         write_data(disp2[i]);
  107.                                           }
  108.                                           write_com(0x80+0x40+10);
  109.                                           for(j=0;j<2;j++)
  110.                                           {
  111.                                                         write_data(disp3[j]);
  112.                                           }
  113.                             }
复制代码


4.3 按键程序设计
              开始的时候,系统会判断是否有按键按下,如果没有按键按下,系统会返回,若有按键按下,系统会判断,加温度按键和减温度按键,然后根据要求判断是否启动加热电路。具体流程如4.3所示。

图4.3 按键程序流程图
C语言程序代码:
sbit SET=P1^0;                                              //定义调整键
sbit DEC=P1^1;                                              //定义减少键
sbit ADD=P1^2;                                              //定义增加键
sbit ALAM=P1^4;                                                        //定义继电器加热引脚
uchar x=0;                                                            
signed char m;                                                             //温度值全局变量
uchar n;                                                                            //温度值全局变量
uchar set_st=0;                                               //设置状态标志
signed char shangxian=80;                              //上限报警温度,默认值为80
signed char xiaxian=20;                               //下限报警温度,默认值为20
void main(void)
{
              uint z;
              InitTimer();    //初始化定时器
              EA=1;      //全局中断开关
              TR0=1;                            //打开定时器定时开关
              ET0=1;      //开启定时器0
              IT0=1;      //外部中断下降沿有效
              IT1=1;
              check_wendu();
              check_wendu();                //读取两次温度,防止开机读取到85°C,使继电器误操作
              for(z=0;z<300;z++)              //开机画面
              {
                            Disp_init();      
              }
              while(1)                               //while循环
              {
                            if(SET==0)                 //判断设置键是否按下
                            {
                                          Delay(2000);              //延时去抖
                                          do{}while(SET==0);              //执行空语句,判断按键是否松开
                            set_st++;x=0;shanshuo_st=1;              //设置键松开后将设置变量加1                                          if(set_st>2)set_st=0;              //当设置完成时,退出设置
                            }
                            if(set_st==0) //正常工作时
                            {
                                          EX0=0;    //关闭外部中断0
                                          EX1=0;    //关闭外部中断1
                                          check_wendu();
                                          Disp_Temperature();              //检测温度
                            }
                            else if(set_st==1)              //设置上限时
                            {
                                          ALAM=1;
                                          EX0=1;    //开启外部中断0
                                          EX1=1;    //开启外部中断1
                                          if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
              else if(set_st==2)              //设置下限时
                            {
                                          ALAM=1;
                                          EX0=1;    //开启外部中断0
                                          EX1=1;    //开启外部中断1
                                          if(x>=10){shanshuo_st=~shanshuo_st;x=0;}
                            }
              }
}
void timer0(void) interrupt 1
{
TH0=0x3c;
TL0=0xb0;                            //12MHz晶振时定时50ms
x++;
}
void int0(void) interrupt 0
{
              EX0=0;      //关外部中断0
              if(DEC==0&&set_st==1)                 //设置上限时按下减按键
              {
                            do{ Disp_alarm(shangxian);              //显示设置}
                            while(DEC==0);
                            shangxian--;                                                        //将上限值减1
                            if(shangxian<=xiaxian)shangxian=xiaxian+1;                //上限值最小比下限值大1
              }
              else if(DEC==0&&set_st==2)              //设置下限时按下减按键
              {
                            do
                            {
                                          Disp_alarm(xiaxian);
                            }
                            while(DEC==0);
                            xiaxian--;                                                          //下限减1
                            if(xiaxian<0)xiaxian=0;                //减到0时停止
              }
}
void int1(void) interrupt 2
{
              EX1=0;      //关外部中断1
              if(ADD==0&&set_st==1)                            //设置上限时按下加按键
              {
                            do
                            {
                                          Disp_alarm(shangxian);
                            }
                            while(ADD==0);
                            shangxian++;                                                        //上限值加1
                            if(shangxian>100)shangxian=100;//最大加到100
              }
              else if(ADD==0&&set_st==2)                 //设置下限时按下加按键
              {
                            do{ Disp_alarm(xiaxian); }
                            while(ADD==0);
                            xiaxian++;                                                           //下限加
                            if(xiaxian>=shangxian)xiaxian=shangxian-1;              //下限最大加到上限值减1
              }
}

本系统由单片机最小系统、按键电路、LCD显示和温度检测电路组成。系统能完成温度的检测、设置温度、加热的功能,采用DS18B20温度传感器实时检测温度并进行转化,检测到的温度值通过LCD1602液晶屏进行实时显示,并可以通过单片机AT89C51外部扩展的按键电路来设定温度值,通过加热电路对水温进行控制,升温时开启加热电路,降温时关闭加热电路,实现对温度在0℃~100℃控制的自动化。
本文设计的基于单片机AT89C51的水温控制器具有简单的软硬件设计电路、低廉的开发成本、简便的操作方法,并通过Proteus仿真实现了预期的功能,还能添加蜂鸣器报警、制冷电路等功能。
但是设计水温控制器需要结合实际综合考虑很多因素,因此该水温控制器设计需要在实际中进一步完善和改进。另外,在系统应用程序方面,该设计只实现了对水进行加热、LCD显示、简单按键控制等功能,要想在现实生活中推广,还必须针对实际应用场合的需要,进一步完善系统功能的程序具有一定的推广价值。

本人初学,仅供参考,存在错误和不足之处,请大家回帖多多指教,切勿照搬,文件下载:
注意附件里面只有仿真和hex,没有代码,求补全 求指导: 只有仿真图,没有代码.7z (231.59 KB, 下载次数: 26)
回复

使用道具 举报

ID:923472 发表于 2022-6-2 19:59 | 显示全部楼层
楼主用的proteus是什么版本的阿,按钮点击后没有反应
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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