太阳能热水器控制器的设计作业_(2).doc
太阳能热水器控制器的设计摘要: 本系统是为太阳能热水器水温水位的检测和控制而设计的。在整个控制系统中,以STC89C52为主控芯片,由DS18B20传感器分别检测水温和水位,实现对水温和水位、上水测量、显示、报警等功能,并以电磁阀、继电器为阀门开关实现全自动加热、上水。整个系统精度高,耐高温性强,易于调整,测试方便,达到设计要求。关键词: STC89C52 DS18B20传感器 水温水位检测与控制引言当前能源紧缺,用电紧,太阳能是绿色能源,得到广大用户的喜爱。使用太阳能热水器时存在的问题:不可缺水,空晒情况下上水会爆炸;春、秋天,水温升高蒸发,造成热能损失;冬温不够,须用电等等。采用太阳能热水器智能仪(也称太阳能热水器水温水位监控仪),能解决上述问题。使用户省心,使用方便,智能运行,用户不必作任何操作。太阳能热水器是一种利用太阳辐射能通过温室效应把水加热的装置。利用聚积的高温来加热水。太阳能热水器不仅可以为家庭提供低温用热水(4060),还可以为暖房、温室、干燥、蒸馏、制冷等热动力系统和工农业生产提供较高温度的热水。太阳能热水器由于具有绿色环保特色而在人民生活和生产中得到了很多应用,它为百姓提供环保、安全节能、卫生的新型热水器产品,太阳能热水器就是吸收太阳的辐射热能,加热冷水提供给人们在生活、生产中使用的节能设备。进步源于竞争,在我国太阳能拥有广阔的市场,当然也有更大的竞争,各大商家为了使自己的产品在市场上立足并长远发展,不断提高太阳能热水器的性能,其中太阳能热水器控制器以其灵活、贴近客户成为商家竞争的热点。目前,各大商家纷纷提高太阳能热水器的智能化程度来满足消费者的需求。许多太阳能热水器的功能有:开机自检、温控上水、强制上水、水位预置、水质设置、水温指示、低水压上水、水位显示、防高温空晒、缺水报警、自动防溢流、缺水上水、手动上水、故障提示等许多贴近客户需求的功能。一、基本设计框图本系统的组成框图如图1所示。本系统的主要设计思路是:设计太阳能热水器控制器,要现测温,高中低水位点测(开关量),加水控制,电加热控制、计算机监控等功能。在此框图中由PC上位机实现对控制部分的监控,由单片机实现现场部分的控制。PC上位机部分由VB监控界面实现实时监控,其中包括太阳能热水器当前的温度,当前水位,自动/手动控制,开始加水/停止加水,开始加热/停止加热,设置温度并加热,保温控制等。由单片机实现硬件电路的控制,从而实现太阳能热水器控制器的控制功能。图1 电路设计框图二、硬件电路的设计 由单片机实现硬件电路的控制,其中硬件部分主要由DS18B20水温采集部分,LCD显示水温水位部分,按键控制部分(实现相应的功能控制),水温水位报警电路等组成。硬件电路设计图见附录一。1、水温采集部分1)DS18B20基本知识 DS18B20数字温度计是DALLAS公司生产的1Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。 (1) DS18B20产品的特点 只要求一个端口即可实现通信;在DS18B20中的每个器件上都有独一无二的序列号;实际应用中不需要外部任何元器件即可实现测温;测量温度围在55°C到125°C之间;数字温度计的分辨率用户可以从9位到12位选择;部有温度上、下限告警设置。 (2)DS18B20工作原理与应用:DS18B20的温度检测与数字数据输出全集成于一个芯片之上,从而抗干扰力更强。其一个工作周期可分为两个部分,即温度检测和数据处理。在讲解其工作流程之前我们有必要了解DS18B20的部存储器资源。DS18B20共有三种形态的存储器资源,它们分别是: ROM只读存储器,用于存放DS18B201D编码,其前8位是单线系列编码(DS18B20的编码是19H),后面48位是芯片唯一的序列号,最后8位是以上56的位的CRC码(冗余校验)。数据在出产时设置不由用户更改。DS18B20共64位ROM。RAM数据暂存器,用于部计算和数据存取,数据在掉电后丢失,DS18B20共9个字节RAM,每个字节为8位。第1, 2个字节是温度转换后的数据值信息,第3, 4个字节是用户EEPROM(常用于温度报警值储存)的镜像。在上电复位时其值将被刷新。第5个字节序列是用户第3个EEPROM的镜像。第6, 7, 8个字节为计数寄存器,是为了让用户得到更高的温度分辨率而设计的,同样也是部温度转换、计算的暂存单元。第9个字节为前8个字节的CRC码。EEPROM非易失性记忆体,用于存放长期需要保存的数据,上下限温度报警值和校验数据,DS18B20共3位EEPROM,并在RAM都存在镜像,以方便用户操作。基于DS18B20的水温采集电路如图2所示:图2 水温采集电路由单片机P1.4引脚控制温度信息采集,DS18B20采集的温度数据送到单片机部,由单片机部判断对现有的温度是否进行加热,保温处理。2、 LCD显示水温水位部分液晶显示器以其微功耗、体积小、显示容丰富、超薄轻巧的诸多优点在袖珍式仪表和低功耗应用系统中得到越来越广泛的应用。但是通用型液晶正常工作温度为0°C-+55°C,存储温度围为-20°C-+60°C,温度过高时,不能正常显示。LCD1602液晶为5V电压驱动,带背光,可显示两行,每行16个字符,不能显示汉字,置含128个字符的ASCII字符集字库,只有并行接口,无串行接口。LCD1602引脚功能介绍:第1脚:VSS为地电源第2脚:VDD接5V止电源第3脚:VO为液晶显示器对比度调整端,接止电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个l0K的电位器调整对比度.第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和RW共同为低电平时可以写入指令或者显示地址,当RS为低电平RW为高电平时可以读忙信号,当RS为高电平RW为低电平时可以写入数据。第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。第7 脚-14脚:D0-D7为8位双向数据线。第15一16脚:空脚图3是水温水位显示部分:图3 水温水位显示在LCD上显示水温,高中低水位,与当前的时间,通过LCD可以实现实时监控,知道目前太阳能热水器的水温水位的变化。3、 按键控制部分这部分主要是运用按键实现太阳能热水器的实时控制的一些观测,由于没有实际的太阳能热水器用于实验,采用此种方式可以观察是否实现了预期的效果。通过按键按下判断是手动/自动控制,加水/加热控制,停止加水/加热控制,高中低水位控制。当按下某一按键时,对应的二极管亮,表示此功能实现。如图4所示:图4 按键控制部分4、 水温水位报警电路当水温低于某一设定值时,报警电路发出警告,与要求进行加热,这是可以采用电加热的方式实现温度值的提高。当水位高于或低于某一水位值时,报警电路报警,此时可以采用自动或手动上水的方式上水。如图5所示:图5 水温水位报警电路三、 软件部分的设计软件部分的设计主要是包括两大模块,即主程序的设计和处理程序的设计。在主程序中首先进行初始化设计:按键的初始化,LCD的初始化,串口通信的初始化,定时器的初始化。还要进行LCD的清零,接下来进入大循环,进行按键的处理与相关程序的调用。系统程序流程图如图6所示:系统上电后,系统即进行输入输出口的初始化,再等待用户按检测键,在扫描到用户已经按过检测间后,单片机调用读数子程序,将水温和控制温度通过A/D转换后,处理判断水是否需要加热。如果需要加热测低温灯亮,并等待用户按加热键。用户按加热键后,系统制动继电器,是加热器通电。再加热过程中,系统循环检测水温,并控制加热时间。整个系统在上电后将无限循环检测水温,实现实时加热。如用户需要关闭,则可通过总电源操作。在软件设计部分,按键处理程序、LCD 1602程序、串口通信模块、DS18B20模块的设计与相应的处理程序部分,这几个模块的编写过程比较复杂,写成的过程中要小心细致,同时也要敢于尝试。具体的程序设计见附录二。图6 系统流程图四、太阳能热水器控制器串口通信协议1、通信模式电脑和CPU通过串口进行全双工命令与数据传递,一方发送数据,另一方接收数据即可,没有回答。串口速率:BPS= 96002、通信协议格式发送方发送数据/命令/状态的协议为:地址,数据。(1)地址为一字节数据,数值围80HFFH,标志是最高位定为1(2)数据长度可变,但每一个字节的数值一定小于80H,即字节的最高位=0(3)所有命令中的数值均为一字节,且小于等于FFH。 命令没有应答,且每传一个数据时前面都要有地址。3、通信协议的容下位机传给上位机:1)、太阳能热水器的当前温度 地址:“A0” 命令:A000:当前温度为0摄氏度 A001:当前温度为1摄氏度 A002:当前温度为2摄氏度 A099:当前温度为99摄氏度 注: 命令是以字符的形式传送,每传送温度时都要加上地址。当前温度大于80摄氏度时报警。 2)、太阳能热水器水位检测: 地址:”A1” 命令:A110:水位达到低水位 A111:水位达到中水位 A112:水位达到高水位 注:命令传送是以单个字符的形式,每传送一组温度数值时都要加上地址。水位达到高水位时报警。上位机传给下位机:1、太阳能热水器加热命令与温度设置、热水器保温地址:”B0”命令:B014:加热到20度 B015:加热到21度 B016:加热到22度 B017:加热到23度 B04F:加热到79度 B050:加热到80度地址: B1H:停止加热 命令传送是以单个字符的形式,每传送一组温度数值时都要加上地址。 注:上位机传温度时,把十进制温度数据以十六进制的形式传给下位机。设置的温度是从2080度,超此围,设置温度窗口会报错。 2)、太阳能热水器加水设置 命令:”C0”:开始加水“C1”:停止加水3)、太阳能热水器自动/手动设置 命令:”D0”:自动“D1”:手动VB监控界面见附录三:五、小结本系统硬件部分简单,主要数据都有软件处理,且具有安全性、可靠性以与实用性。在此次的设计中,我学到了很多知识,之前单片机的知识几乎忘记,经过这次小课题设计,我做到了温故而知新,同时也锻炼了自己的编程的能力。虽然在这次课题设计中我遇到了许多难题,通过与同学的讨论,基本上得到了解决,之后会再接再厉,争取做得更好!在此也要感此次设计过程中帮助过我的同学与老师们。附录一:整体电路图附录二:软件设计程序#include "reg52.h"#include "key.h"#include "lcd1602.h"#include "usart.h"#include "ds18b20.h"#include "time.h"#include "dispose.h"void Init (void)KeyInit();LcdInit();UsartInit();TimeInit();void main (void)unsigned key;Init();LcdClr();while (1)key = KeyScan();DisposeKey(key);#include "dispose.h"sbit di=P20;sbit zhong=P21; sbit gao=P22;char RunMode;char SetTemp;char SetTempbuf;char BaojingEn;unsigned char shuiliang(void);void DisposeAuto(void)if (tempi < SetTempbuf)jiare = 0;elsejiare = 1;if (shuiliang() = 0)jiashui = 0;else if (shuiliang() = 1) && (SetTempbuf - tempi < 30)jiashui = 0;else if (shuiliang() = 2) && (SetTempbuf - tempi < 20)jiashui = 0;else if (shuiliang() = 3) && (SetTempbuf - tempi < 10)jiashui = 0;elsejiashui = 1;void DisposeKey(unsigned char key)switch (key)case 8:/手动/自动RunMode = !RunMode;break;case 9:/加热if (!RunMode)jiare = 0;break;case 10:/+if (SetTemp)if (SetTempbuf < 100)SetTempbuf+;LcdPos(14);LcdWdat(SetTempbuf/10+48);LcdWdat(SetTempbuf%10+48);break;case 11:/-if (SetTemp)if (SetTempbuf > 0)SetTempbuf-;LcdPos(14);LcdWdat(SetTempbuf/10+48);LcdWdat(SetTempbuf%10+48);break;case 12:/设置温度SetTemp = !SetTemp;if (SetTemp)LcdClr();LcdPos(0);LcdWdat('S');LcdWdat('e');LcdWdat('t');LcdWdat('T');LcdWdat('e');LcdWdat('m');LcdWdat('p');LcdWdat(':');LcdPos(14);LcdWdat(SetTempbuf/10+48);LcdWdat(SetTempbuf%10+48);elseLcdClr();LcdPos(0);LcdWdat('T');LcdWdat('e');LcdWdat('m');LcdWdat('p');LcdWdat(':');LcdPos(14);LcdWdat(tempi/10+48);LcdWdat(tempi%10+48);break;case 13:/报警音开/关BaojingEn = !BaojingEn;break;case 14:/加水if (!RunMode)jiashui = 0;break;case 15:/停止if (!RunMode)jiare = 1;jiashui = 1;break;default :break;unsigned char shuiliang(void)static unsigned char shuiliang;di=0;zhong=0;gao=0;/static unsigned char j;P3 |= 0x38;/j+;/if (j >= 2)/j = 0;/if (di = 1)shuiliang = 0;else if (zhong = 1)shuiliang = 1;else if (gao = 1)shuiliang = 2;/if (shuiliang0 != shuiliang1)switch (shuiliang)case 0 :LcdPos(0x40);LcdWdat('W');LcdWdat('a');LcdWdat('t');LcdWdat('e');LcdWdat('r');LcdWdat(' ');LcdWdat('L');LcdWdat('e');LcdWdat('v');LcdWdat('e');LcdWdat('l');LcdWdat(':');LcdWdat('0');UsartSendShuiwei(0);break;case 1 :LcdPos(0x40);LcdWdat('W');LcdWdat('a');LcdWdat('t');LcdWdat('e');LcdWdat('r');LcdWdat(' ');LcdWdat('L');LcdWdat('e');LcdWdat('v');LcdWdat('e');LcdWdat('l');LcdWdat(':');LcdWdat('1');UsartSendShuiwei(1);break;case 2 :LcdPos(0x40);LcdWdat('W');LcdWdat('a');LcdWdat('t');LcdWdat('e');LcdWdat('r');LcdWdat(' ');LcdWdat('L');LcdWdat('e');LcdWdat('v');LcdWdat('e');LcdWdat('l');LcdWdat(':');LcdWdat('2');UsartSendShuiwei(2);break;case 3 :LcdPos(0x40);LcdWdat('W');LcdWdat('a');LcdWdat('t');LcdWdat('e');LcdWdat('r');LcdWdat(' ');LcdWdat('L');LcdWdat('e');LcdWdat('v');LcdWdat('e');LcdWdat('l');LcdWdat(':');LcdWdat('3');UsartSendShuiwei(3);break;default :break;/return shuiliang; 按键处理部分#include "key.h"void KeyDelay (unsigned int z)unsigned int i;while(z-)for(i=0;i<120;i+);void KeyInit (void)P2=0xfe;P0=0xff;ad0=0;ad1=0;ad2=0;ad3=1;unsigned char KeyScan (void)unsigned char temp,num;num=16;ad0=0;ad1=0;ad2=1;ad3=1;P2=0xfe; /扫描第一行P0=0xff;temp=P0;if(temp!=0xff)KeyDelay(5);temp=P0;if(temp!=0xff)switch(temp)case 0xfe: num=0; break;case 0xfd: num=1; break;case 0xfb: num=2; break;case 0xf7: num=3; break;case 0xef: num=4; break;case 0xdf: num=5; break;case 0xbf: num=6; break;case 0x7f: num=7; break;while(temp!=0xff)P0=0xff;temp=P0;P2=0xfd; /扫描第二行P0=0xff;temp=P0;if(temp!=0xff)KeyDelay(5);temp=P0;if(temp!=0xff)switch(temp)case 0xfe: num=8; break;case 0xfd: num=9; break;case 0xfb: num=10; break;case 0xf7: num=11; break;case 0xef: num=12; break;case 0xdf: num=13; break;case 0xbf: num=14; break;case 0x7f: num=15; break;while(temp!=0xff)P0=0xff;temp=P0;ad3=0;return num;LCD1602程序#include "lcd1602.h"unsigned char code dis1 = " Welcome B6 "/第一行显示容unsigned char dispbuf5;/第二行显示容float count1=34.56;/*/* /* 延时子程序 /* /*/void LcdDelay (int ms) int i; while(ms-) for(i = 0; i< 250; i+) _nop_(); _nop_(); _nop_(); _nop_(); /*/* */ /*检查LCD忙状态 */ /*LcdBusy为1时,忙,等待。LcdBusy为0时,闲,可写指令与数据。 */ /* */ /*/bit LcdBusy (void) bit result; lck = 0; LCD_RW =1; lcd_rs=0; LCD_EN=1;/0x91;/LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; lck = 1; /锁存数据到HC574 _nop_(); _nop_(); _nop_(); _nop_(); result = (bit)(P0&0x80); lck = 0; LCD_EN = 0;/ LCD_EN = 0; lck = 1; return result; /*/* */ /*写指令数据到LCD */ /*RS=L,RW=L,E=上升沿,D0-D7=指令码。 */ /* */ /*/void LcdWcmd (unsigned char cmd) while (LcdBusy(); lck = 0; LCD_RW =0; lcd_rs=0; LCD_EN=0;/ LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; lck = 1; _nop_(); _nop_(); P0 = cmd; _nop_(); _nop_(); _nop_(); _nop_(); lck = 0; LCD_EN = 1; / LCD_EN = 1; lck = 1; _nop_(); _nop_(); _nop_(); _nop_(); lck = 0; LCD_EN = 0; / LCD_EN = 0; lck = 1;/*/* */ /*写显示数据到LCD */ /*RS=H,RW=L,E=上升沿,D0-D7=数据。 */* */ /*/void LcdWdat (unsigned char dat) while (LcdBusy(); lck = 0; lcd_rs = 1; LCD_RW = 0; LCD_EN = 0; / LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; lck = 1; P0 = dat; _nop_(); _nop_(); _nop_(); _nop_(); lck = 0; LCD_EN = 1;/ LCD_EN = 1; lck = 1; _nop_(); _nop_(); _nop_(); _nop_(); lck = 0; LCD_EN = 0; /LCD_EN = 0; lck = 1; /*/* */ /* 设定显示位置 */ /* */ /*/void LcdPos (unsigned char pos) LcdWcmd(pos|0x80); /数据指针=0x80+地址变量/*/* */