资源描述
(完整word版)智能温室监控系统的课程设计技术报告
智能温室监视系统
[摘要]本文介绍了基于AT89C51单片机的智能温室监视系统的硬件结构和软硬件设计方法。系统以AT89C51单片机为控制器,以温度传感器DS1820实现当前温度的采集,能够显示当前温度值,当显示温度超出上限设定范围,蜂鸣器就发出报警(附加功能)通过继电器控制电风扇、实现高温降温。当显示温度超出下限设定范围,蜂鸣器就发出报警(附加功能)电阻加热器低温加热。智能温室监视系统采用直观的数字显示,可以在LED上同时显示上限温度,下限温度和当前温度,仅有三个控制按钮,操作简单易懂,此智能温室监视系统控制具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,具有广阔的市场前景。
[关键词]AT89C51 智能温室监视系统 DS1820
1 任务提出与方案论证
1.1课题研究的背景
随着时代科技的迅猛发展,微电子学和计算机等现代电子技术的成就给传统的电子测量与仪器带来了巨大的冲击和革命性的影响。常规的测试仪器仪表和控制装置被更先进的智能仪器所取代,使得传统的电子测量仪器在远离、功能、精度及自动化水平定方面发生了巨大变化,并相应的出现了各种各样的智能仪器控制系统,使得科学实验和应用工程的自动化程度得以显著提高。
1.2课题的研究目的与意义
我国幅员辽阔,各地气候差异很大,同一地区在不同季节、不同天气条件下光照度,温度等因子亦不相同。大多植物的生长适宜温度在12摄氏度到33摄氏度之间。植物不同生长期对环境的要求有所不同,不同植物对环境因子的要求也不同,仅靠自然条件很难满足和调节。截止2009年,我国温室面积为1500余万亩,拥有环境智能监控系统的温室只占0.4%左右,多数温室仍为简易设施,对环境因子的控制多为人工控制为主。却反科学的技术指标,更缺乏控制的手段和设备,所以研制一套符合我国国情、拥有独立知识产权、性价比高的智能温室检查系统是对于改变我国农业经济增长方式和实现农业的可持续发展具有十分重要的现实意义。
1.3课题解决的主要内容
(1)能够显示当前温度值的温度计。(2.)当显示温度超出上限设定范围,蜂鸣器就发出报警(附加功能)通过继电器控制电风扇、实现高温降温。(3).当显示温度超出下限设定范围,蜂鸣器就发出报警(附加功能)电阻加热器低温加热。
1.4课题的方案论证
本设计是一个基于数字温度传感器的温室控制仪,能测量室内温度,并且能设定上下线温度,在超限的情况下报警,并且进行控制与调整,保证环境始终保持在限定的温度中。
根据设计的要求,要利用数字温度传感器实时测量温度,并且能手动设定温度上下限。当温度高于设定的温度时,触发报警电路,同时触发降温装置进行调整,使温度降低到设定的温度范围内。当温度低于设定的温度时,触发报警电路,同时触发升温装置进行调整,使温度升高到设定的温度范围内。本设计采用AT89C52单片机来控制温度,因此要有温度传感电路,温度显示电路,温度报警电路,温度控制电路等几个部分。
2 系统的总体设计
2.1智能温室控制系统的功能要求
(1)能够显示当前温度值的温度计。(2.)当显示温度超出上限设定范围,蜂鸣器就发出报警(附加功能)通过继电器控制电风扇、实现高温降温。(3).当显示温度超出下限设定范围,蜂鸣器就发出报警(附加功能)电阻加热器低温加热。
2.2 电路的总体设计思路
本设计的总体设计思路如下:DS18B20温度传感器把所测得的温度发送到AT89C52单片机上,经过52单片机处理,将把温度在LCD1602液晶显示屏上显示。除了显示温度以外还可以设置一个温度上下限,对所测量的温度进行监控,当温度高于或低于限定温度时,开始报警并启动温度控制电路,将温度始终控制在限定范围以内。
中央微处理器AT89C52单片机: AT89C52是一个低功耗,高性能CMOS 8位单片机,含可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-52指令系统及80S52引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的AT89C52可为许多嵌入式控制应用系统提供高性价比的解决方案。
2.3 电路的总体工作原理
本设计采用AT89C52单片机作为微处理单元进行控制,通过按键完成温度检测功能的转换,设定上下限温度,将数字通过电路输入单片机,通过LCD1602液晶显示屏进行温度显示。DS18B20温度传感器把采集的温度信号与单片机里的数据相比较,从而触发温度控制器与报警系统。然后采用电阻加热器和继电器(驱动电风扇)将温度控制在限定温度之间。
根据系统的设计要求,选择DS18B20温度传感器作为本系统的温度传感器,选择AT89C52单片机作为温度测量控制系统的核心来完成数据采集、处理、显示、报警等功能。选用DS18B20温度传感器,省去了采样保持电路、运放电路、数模转换电路以及进行长距离传输时的串并转换电路,从而简化了电路,缩短了系统的工作时间,降低了系统的硬件成本。
3 系统硬件的设计
3.1系统硬件电路设计
图4 系统硬件电路设计
3.2 器件的选用
3.2.1单片机的选择 AT89C52
如图1所示,为AT89C52的硬件结构图。AT89C52单片机的内部结构与MCS-51系列单片机的构成基本相同。CPU是由运算器和控制器所构成的。运算器主要用来对操作数进行算术、逻辑运算和位操作的。控制器是单片机的指挥控制部件,主要任务的识别指令,并根据指令的性质控制单片机各功能部件,从而保证单片机各部分能自动而协调地工作。它的程序存储器为8K字节可重擦写Flash闪速存储器,闪烁存储器允许在线+5V电擦除、电写入或使用编程器对其重复编程。数据存储器比51系列的单片机相比大了许多为256字节RAM。AT89C52单片机的指令系统和引脚功能与MCS-51的完全兼容。
图1 AT89C52的硬件结构图
图2 AT89C52外部引脚图
3.2.2 LM7805 稳压芯片
三端稳压集成电路lm7805。电子产品中,常见的三端稳压集成电路有正电压输出的lm78 ×× 系列和负电压输出的lm79××系列。顾名思义,三端IC是指这种稳压用的集成电路,只有三条引脚输出,分别是输入端、接地端和输出端。它的样子象是普通的三极管,TO- 220 的标准封装,也有lm9013样子的TO-92封装。
用lm78/lm79系列三端稳压IC来组成稳压电源所需的外围元件极少,电路内部还有过流、过热及调整管的保护电路,使用起来可靠、方便,而且价格便宜。该系列集成稳压IC型号中的lm78或lm79后面的数字代表该三端集成稳压电路的输出电压,如lm7806表示输出电压为正6V,lm7909表示输出电压为负9V。因为三端固定集成稳压电路的使用方便,电子制作中经常采用。如图3所示
图3 LM7805
3.2.3 DS18B20 温度传感器
DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20、 DS1822 “一线总线”数字化温度传感器 同DS1820一样,DS18B20也 支持“一线总线”接口,测量温度范围为 -55°C~+125°C,在-10~+85°C范围内,精度为±0.5°C。DS1822的精度较差为± 2°C 。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。适合于恶劣环境的现场温度测量,如:环境控制、设备或过程控制、测温类消费电子产品等。与前一代产品不同,新的产品支持3V~5.5V的电压范围,使系统设计更灵活、方便。而且新一代产品更便宜,体积更小。 DS18B20、 DS1822 的特性 DS18B20可以程序设定9~12位的分辨率,精度为±0.5°C。可选更小的封装方式,更宽的电压适用范围。分辨率设定,及用户设定的报警温度存储在EEPROM中,掉电后依然保存。DS18B20的性能是新一代产品中最好的!性能价格比也非常出色! DS1822与 DS18B20软件兼容,是DS18B20的简化版本。省略了存储用户定义报警温度、分辨率参数的EEPROM,精度降低为±2°C,适用于对性能要求不高,成本控制严格的应用,是经济型产品。 继“一线总线”的早期产品后,DS1820开辟了温度传感器技术的新概念。DS18B20和DS1822使电压、特性及封装有更多的选择,让我们可以构建适合自己的经济的测温系统。
3.2.4温度显示器的选择
本设计采用LCD1602液晶显示屏进行显示。LCD1602液晶显示屏是一种低压、微功耗的显示器件,只要2~3伏就可以工作,工作电流仅为几微安,是任何显示器无法比拟的。同时可以显示大量信息,除数字外,还可以显示文字、曲线,比传统的数码LED显示器显示的界面有了质的提高。其一,显示质量高,由于液晶显示器的每一个点收到信号后就一直保持那种色彩和亮度恒定发光,因此液晶显示器的画质高而且不会闪烁。其二, 数字式接口,液晶显示器都是数字式的,和单片机的接口简单操作也很方便。其三,功率消耗小,相比而言,液晶显示器的主要功耗在内部电极和驱动IC上,因而耗电量比其他器件要小很多。
虽然LCD1602液晶显示屏的价格比数码LED显示器要贵,但它的显示效果好,是当今显示器的主流,所以,本设计温度显示器采用LCD1602液晶显示屏。
4 系统的软件设计
4.1 系统的主程序设计
主程序是系统的监控程序,在程序运行的过程中必须先经过初始化,包括按键程序,中断程序,以及各个控制端口的初始化工作。系统在初始化完成后就进入温度测量程序,实时的测量当前的温度并通过显示电路在LCD上显示。程序中以中断的方式来重新设定温度的上下限。根据硬件设计完成对温度的控制。
系统软件设计的总体流程图如8 所示。
开始
系统初始化
开中断
Int0=0?
Y
N
温度上下限设定
温度测量
温度测量
显示系统
图 4 系统总体设计流程图
5 PROTEUS使用
5.1用PROTEUS ISIS对智能温室检查系统的仿真测试
图5 仿真图
6 作品功能及调试情况
7 总结
通过本次课程设计,我们有如下收获:
1. 综合运用相关课程中所学到的理论知识完成了“智能温室检测系统”这一设计课题;
2. 通过查阅手册和相关文献资料,培养了我们独立分析和解决问题的能力;
3. 进一步熟悉常用芯片和电子器件的类型及特性,并掌握合理选用器件的原则;
4. 学会电路的安装与调试;
5. 进一步熟悉电子仪器的正确使用;
6. 学会撰写课程设计的总结报告;
7. 培养了我们严肃认真的工作作风和严谨的科学态度。
[参考文献]
[1] 康华光,陈大钦. 电子技术基础—模拟部分(第五版)[M]. 北京:高等教育出版社,2005[2] 皮文兵. 一种宽输入范围的Gillbert模拟乘法器设计[J]. 电子设计应用,2007.13(1):88-90
[3]姜锡洲.一种温热外敷药制备方案[P].中国专利:881056078,1983-08-12
[4] 张筑生. 微分半动力系统的不变集 [D]. 北京: 北京大学数学系数学研究所,1983
附录
主程序
#include<stdio.h> //标准输入输出
#include<intrins.h>
#include "lcd1602.h"
#include "ds18b20.h"
#include "key.h"
#include "judge.h"
void InitTimer0(void)
{
TMOD = 0x01;
TH0 = 0x0D8;
TL0 = 0x0F0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
/******************************************************************/
/* 主函数 */
/******************************************************************/
void main(void)
{
P3=0X00;
start_disp();
while(!start_flag)
{
key();
}
while(start_flag)
{
InitTimer0();
display();
judge();
}
}
void Timer0Interrupt(void) interrupt 1
{
TH0 = 0x0D8;
TL0 = 0x0F0;
temp = ReadTemperature();
}
LCD程序
#include "lcd1602.h"
#include<intrins.h>
#include<stdio.h>
unsigned int temp;
unsigned char tempH,tempL;
char data TimeNum[]=" ";
char data Test1[]=" ";
/******************************************************************/
/* 函数声明 */
/******************************************************************/
/******************************************************************/
/* 微秒延时函数 */
/******************************************************************/
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt;
uscnt=us>>1; /*12MHz频率*/
while(--uscnt);
}
/******************************************************************/
/* 毫秒函数声明 */
/******************************************************************/
void DelayMs(unsigned char ms)
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
/******************************************************************/
/* 写入命令函数 */
/******************************************************************/
void WriteCommand(unsigned char c)
{
DelayMs(5);//操作前短暂延时,保证信号稳定
E=0;
RS=0;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
}
/******************************************************************/
/* 写入数据函数 */
/******************************************************************/
void WriteData(unsigned char c)
{
DelayMs(5); //操作前短暂延时,保证信号稳定
E=0;
RS=1;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
RS=0;
}
/******************************************************************/
/* 写入字节函数 */
/******************************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p;
if (pos>=0x10)
p=pos+0xb0; //是第二行则命令代码高4位为0xc
else
p=pos+0x80; //是第二行则命令代码高4位为0x8
WriteCommand (p);//写命令
WriteData (c); //写数据
}
/******************************************************************/
/* 写入字符串函数 */
/******************************************************************/
void ShowString (unsigned char line,char *ptr)
{
unsigned char l,i;
l=line<<4;
for (i=0;i<16;i++)
ShowChar (l++,*(ptr+i));//循环显示16个字符
}
/******************************************************************/
/* 初始化函数 */
/******************************************************************/
void InitLcd()
{
DelayMs(15);
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动位置
WriteCommand(0x0c); //显示开及光标设置
WriteCommand(0x01); //显示清屏
}
void start_disp(void)
{
InitLcd(); //初始化LCD
DelayMs(15); //延时保证信号稳定
sprintf(Test1,"H:30C L:10C"); //打印输出第一行信息
ShowString(0,Test1);
sprintf(TimeNum,"current: ");//打印输出第二行信息
ShowString(1,TimeNum);
}
void disp_set(unsigned char addr,unsigned char a)
{
unsigned char g,d;
g = '0' + a/10; //gaoshiwei
d = '0' + a%10;
WriteCommand(addr); //高位地址
WriteData(g);
WriteCommand(addr+1); //低位地址
WriteData(d);
}
void display(void)
{
unsigned char str[7];
if(temp & 0x8000)
{
str[0] = '-';
temp = ~temp;
temp += 1;
}
else str[0] = '0';
tempH = temp >>4;
tempL = temp & 0x0f;
tempL = tempL * 6/10; //近似处理
str[1] = '0' + tempH/100; //bai
str[2] = '0' + tempH/10; //shi
str[3] = '0' + tempH%10; //ge
str[4] = '.'; //.
str[5] = '0' + tempL;
str[6] = 'C';
WriteCommand(0xc8);
WriteData(str[0]);
WriteCommand(0xc9);
WriteData(str[1]);
WriteCommand(0xca);
WriteData(str[2]);
WriteCommand(0xcb);
WriteData(str[3]);
WriteCommand(0xcc);
WriteData(str[4]);
WriteCommand(0xcd);
WriteData(str[5]);
WriteCommand(0xce);
WriteData(str[6]);
}
DS18B20程序
#include "ds18b20.h"
/******************************************************************/
/* 延时函数 */
/******************************************************************/
void delay(unsigned int i)//延时函数
{
while(i--);
}
/******************************************************************/
/* 初始化 */
/******************************************************************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay(5);
}
/******************************************************************/
/* 读一个字节 */
/******************************************************************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
delay(5);
DQ = 1;
dat>>=1;
}
delay(5);
}
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay(200);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
按键key程序
#include "key.h"
#include "reg52.h"
#include "lcd1602.h" //WriteCommand WriteData
#include "ds18b20.h" //delay
sbit key1 = P1^0; //增加
sbit key2 = P1^1; //减少
sbit key3 = P1^2; //确定
unsigned char High_temp=30;
unsigned char Low_temp=10;
unsigned char key_num=0;
unsigned char start_flag=0;
void key(void)
{
P1=0XFF;
if(!key3)
{
delay(20);
if(!key3)
{
while(!key3);
key_num++;
}
}
if(key_num == 0)
{
if(key1 != 1)
{
delay(20);
if(key1 != 1)
{
while(key1 != 1);
High_temp++;
disp_set(0x82,High_temp);
}
}
if(!key2)
{
delay(20);
if(!key2)
{
while(!key2);
High_temp--;
disp_set(0x82,High_temp);
}
}
}
else if(key_num == 1)
{
if(key1 != 1)
{
delay(20);
if(key1 != 1)
{
while(key1 != 1);
Low_temp++;
disp_set(0x8d,Low_temp);
}
}
if(!key2)
{
delay(20);
if(!key2)
{
while(!key2);
Low_temp--;
disp_set(0x8d,Low_temp);
}
}
}
else
{
start_flag = 1;
28
展开阅读全文