环境监测系统实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

信息与通信工程学院
单片机系统课程设计报告完成日期:2012年 11 月 16 日
目录
目录 (1)
一、设计任务和要求 (1)
1.1设计任务 (1)
1.2性能指标 (1)
二、设计方案 (2)
2.1.方案设计 (2)
2.1.1单片机控制模块的选择论证 (2)
2.1.2温度湿度检测模块的选择与论证 (2)
2.1.3显示模块的选择与论证 (2)
2.2本设计采用方案及原理 (3)
三、系统硬件设计 (4)
3.1单片机最小系统设计 (4)
3.2温湿度采集电路 (5)
3.3电源电路 (6)
3.4光敏电阻接入电路 (7)
3.5键盘电路 (8)
3.6LCD显示电路 (8)
3.7报警电路 (9)
3.8串行接口电路 (10)
四.系统软件设计 (10)
4.1主程序设计 (10)
4.2LCD12864模块程序 (11)
4.3DHT11模块程序 (12)
4.4光敏电阻模块程序 (14)
五.调试及性能分析 (15)
5.1调试过程中出现的问题 (15)
5.2性能分析 (15)
六.心得体会 (16)
参考文献 (17)
附录1 程序清单 (18)
附录2 电路原理图 (24)
附录3 PCB图 (25)
附录4 硬件电路板图 (26)
一、设计任务和要求
1.1 设计任务
基本要求:
(1)利用单片机控制传感器采集环境温湿度,光照强度等参数,并在液晶屏上显示环境参数值。

(2)系统设有键盘,可实现系统参数的设置。

提高部分:
(1)将上述环境数据记录在SD或TF卡上;
(2)采集并显示三轴加速度值;
(3)无线传输所测环境参数。

1.2 性能指标
(1)温度湿度光照强度显示:用LCD12864进行显示。

(2)环境温度:单位/℃。

(3)环境湿度:单位/%RH。

(4)环境光强:单位/lux
(5)键盘
(6)报警
二、设计方案
2.1.方案设计
2.1.1 单片机控制模块的选择论证
方案一:单片机选用STC12C5A60S2,这款单片机有第二串口,有A/D转换,有PWM/PCA 功能,有内部EEPROM可内部实现A/D转换。

方案二:采用XC9000系列的FPGA。

该类器件具有并行处理能力,能快速的响应外部的各种数字信号。

综上所述,单片机数学运算功能较强。

在程序相互调用方面,处理方便灵活,性能稳定,适合实际应用。

且单片机技术发展较为成熟,价格便宜,而FPGA芯片价格较昂贵。

则选择方案一。

2.1.2 温度湿度检测模块的选择与论证
方案一:温度湿度的采集模块采用DHT11。

DHT11是一款数字输出的复合传感器,包含一个电阻式感湿元件和NTC式温度检测元件,可测20~90%RH湿度,误差5%RH,0~50摄氏度,误差2摄氏度。

方案二:选用DS18B20温度传感器和HS1101湿度传感器。

DS18B20是一线式数字温度传感器,具有独特的单线式接口方式,测量范围在55℃~125℃,误差为±0.5℃。

最高精度可达0.0625℃。

HS1101是电容式湿度传感器,可测相对湿度范围在0%~100%RH,误差为±2%RH
综上所述,虽然方案二的测试范围和精度都比较好,但DHT11综合性比较强,则选择方案一。

2.1.3 显示模块的选择与论证
方案一:采用12864液晶模块显示测得的数据,可显示较多组的数据,字体较大,可清晰读数,12864为四行八列中文显示器,可以很清晰的显示温度湿度光照强度等的指标。

方案二:采用1602液晶模块显示所测数据,1602液晶接线简单方便,但所显示的不清
楚,没有条理性。

综上所述选择方案一。

2.2 本设计采用方案及原理
按照系统设计的功能的要求,初步确定设计系统由单片机主控模块、电源模块、显示模块、DHT11环境温湿度检测模块、光敏电阻模块、报警、按键等模块组成。

原理框图:
三、系统硬件设计
3.1 单片机最小系统设计
图3-1-1
图3-1-2
图3-1-3
采用STC12C5A60S2单片机,P0口接上拉电阻,10K*8排阻,晶振电路采用11.0592M,33pF
电容,单片机晶振的作用是为系统提供基本的时钟信号。

通常一个系统共用一个晶振,便于各部分保持同步。

有些通讯系统的基频和射频使用不同的晶振,而通过电子调整频率的方法保持同步。

3.2 温湿度采集电路
图3-2-1
单总线数字温湿度传感器DHT11。

这款传感器由广州奥松电子科技有限公司研发,与单片机的通信十分简洁方便,无需外接时钟信号,通信如图发
除此之外,它还有很多突出的优点:
(1)温湿度传感器的一体化结构能同时对相对湿度和温度进行测量,并以数字信号输出,从而减少用户对信号的预处理负担
(2)独特的单总线数据传输线协议使得读取传感器更加便捷,而且还有全部校准数据字节,编码方式为8位二进制数。

(3)40位二进制数据输出,高位先出,格式为:湿度整数部分8位,小数部分8位;温度整数部分8位,小数部分8位,最后8位为校验字节,为前32位数据的和。

(4)宽工作电压,几乎与AT89S52的电压相同,为3~5.5V,而且功耗较低,通信最大电流为2.5mA。

其简要的性能参数如下表所示:
从表中可以看出,它的测量范围较小,但对实验或民用已经足够了,如果要工业使用的话,可选用该公司的同类工业级产品AM323,测量范围为-55.0~+125.0度,测量范围为0.0~100.0%RH,并且可以和DHT11完全互换。

按照说明书的要求,DHT11与单片机的连接距离小于20米时,需要在VCC和DATA引脚之间接一个5K左右的电阻,则电路如图所示。

3.3 电源电路
图3-3-1
用J1 USB供电,D1为上电指示灯,J2为六脚按键,用来控制板子上电。

3.4 光敏电阻接入电路
图3-4-1
光敏电阻的主要特性及参数:
(1)光电流、亮电阻。

光敏电阻器在一定的外加电压下当有光照射时,流过的电流称为光电流,外加电压与光电流之比称为亮电阻,常用“100LX”表示。

(2)暗电流、暗电阻。

光敏电阻在一定的外加电压下,当没有光照射的时候,流过的电流称为暗电流。

外加电压与暗电流之比称为暗电阻,常用“0LX”表示。

(3)灵敏度。

灵敏度是指光敏电阻不受光照射时的电阻值(暗电阻)受光照射时的电阻值(亮电阻)的相对变化值。

(4)在一定外加电压下,光敏电阻的光电流和光通量之间的关系。

不同类型光敏电阻光照特性不同,但光照特性曲线均呈非线性。

因此它不宜作定量检测元件,这是光敏电阻的不足之处。

一般在自动控制系统中用作光电开关。

(5)光敏电阻的光谱特性光谱特性与光敏电阻的材料有关。

硫化铅光敏电阻在较宽的光谱范围内均有较高的灵敏度,峰值在红外区域,化镉、硒化镉的峰值在可见光区域。

因此,在选用光敏电阻时,应把光敏电阻的材料和光源的种类结合起来考虑,才能获得满意的效果。

(6)光敏电阻的伏安特性:在一定照度下,加在光敏电阻两端的电压与电流之间的关系称为伏安特性。

在给定偏压下,光照度较大,光电流也越大。

在一定的光照度下,所加的电压越大,光电流越大,而且无饱和现象。

但是电压不能无限地增大,因为任何光敏电阻都受额定功率、最高工作电和额定电流的限制。

超过最高工作电压和最大额定电流,可能导致光敏
电阻永久性损坏。

(7)当光敏电阻受到脉冲光照射时,光电流要经过一段时间才能达到稳定值,而在停止光照后,光电流也不立刻为零,这就是光敏电阻的时延特性。

由于不同材料的光敏,电阻时延特性不同,所以它们的频率特性也不同,硫化铅的使用频率比硫化镉高得多,但多数光敏电阻的时延都比较大,所以,它不能用在要求快速响应的场合。

3.5 键盘电路
图3-5-1
本设计的控制输入部分为简单的四个按键:由于单片机默认状态下端口引脚为高电平,可以接上按键与地相连。

单片机检测按键端口的电平情况来决定是否有按键按下和哪个按键被按下,抖动问题采用软件延时方式,减少硬件电路设计,电路如图所示。

3.6 LCD显示电路
由引脚的应用考虑,LCD接为串行显示,当模块的PSB脚接低电平时,模块即进入串行接口模式。

串行模式使用串行数据线SID与串行时钟线SCLK来传送数据,即构成2线串行模式。

图3-6-1
3.7 报警电路
图3-7-1
根据蜂鸣器的参数,电压1.3~1.5V,电流20~80mA,电阻6~8Ω知,可用选用集成放大芯片LM386 驱动,但更经济的是用一个三极管9012 或8550 驱动即可,电路如图所示。

3.8 串行接口电路
图3-8-1
四.系统软件设计
4.1 主程序设计
void main()
{
uchar k,j;
LCD_init();
LCD_dis_code(0,1,lcd);
LCD_dis_code(1,0,lcd1);
LCD_dis_code(2,0,lcd2);
LCD_dis_code(3,0,lcd3);
while(1)
{
read_io();//读取温湿度数据
//clear_gcrom();
//湿度
for(k=0; k<2; k++)
{
lcd_pos(3,k+3);
write_data(str1[k]);
}
//clear_gcrom();
//温度
for(j=0; j<2; j++)
{
lcd_pos(2,j+2);
write_data(str2[j]);
}
delay(500);
}
}
4.2 LCD12864模块程序
void LCD_dis_code(uchar x,uchar y,uchar code *s)
{
write_cmd(addr_tab[8*x+y]); //写地址
while(*s>0)
{
write_data(*s); //写数据
s++;
}
}
/******初始化LCD******/
void Lcd_init(void)
{
delay(50);
write_cmd(0x30); //选择基本指令集
delay(1);
write_cmd(0x30); //选择8bit数据流
delay(1);
write_cmd(0x0c); //开显示(无游标、不反白)
delay(1);
write_cmd(0x01); //清除显示,并且设定地址指针为00H delay(30);
}
/******串行发送一个字节******/
void send_byte(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
SCLK = 0;
byte=byte<<1; //左移一位先发送高位的数据
SID = CY; //移出的位给SID
SCLK = 1; //上升沿触发发送
SCLK = 0;
}
}
/******写指令*****/
void write_cmd(uchar cmd)
{
delay(1);
SID = 0;
SCLK = 0;
delay(5);
P0 = cmd;
delay(5);
SCLK = 1;
delay(5);
SCLK = 0;
}
/******写数据******/
void write_data(uchar dat)
{
delay(1);
SID = 0;
SCLK = 0;
P0 = dat;
delay(5);
SCLK = 1;
delay(5);
SCLK = 0;
}
/******延时子程序******/
void delay(uint a)
{
uint i;
while(a--)
{
for(i=0; i<113; i++);
}
}
4.3 DHT11模块程序
uchar receive_byte()//接收一个字节{
uchar i,temp;
for(i=0;i<8; i++)
{
count = 2;
while((!io) && count++)//等待50us低电平结束,并防止死循环
temp = 0;
delay1();
delay1();
delay1();
if (io==1)
{
temp = 1;
count = 2;
while(io && count++);
}
else
temp = 0;
data_byte<<=1;
data_byte=temp;
}
return (data_byte);
}
/******开始信号******/
void read_io()//开始信号,读数据并校验
{
io = 0;
delay(18);//主机拉低18ms
io = 1;//DATA总线由上拉电阻拉高主机延时20us
delay1();
delay1();
delay1();
delay1();
io = 1;//主机设置为输入高电平,判断从机响应信号
if(!io)
{
count = 2;
while((!io)&&count++);//判断DHT11发出80us低电平响应信号是否结束
count = 2;
while(io && count++);//判断DHT11拉高总线80us高电平是否结束
RH_temp = receive_byte();
RL_temp = receive_byte();
TH_temp = receive_byte();
TL_temp = receive_byte();
CK_temp = receive_byte();
io = 1;
num = (RH_temp + RL_temp + TH_temp + TL_temp);//数据校验
if(num == CK_temp)
{
RH_data = RH_temp;
RL_data = RL_temp;
TH_data = TH_temp;
TL_data = TL_temp;
CK_data = CK_temp;
}
}
//湿度整数部分
str1[0] = (char)(0x30 + RH_data/10);
str1[1] = (char)(0x30 + RH_data%10);
//温度整数部分
str2[0] = (char)(0x30 + TH_data/10);
str2[1] = (char)(0x30 + TH_data%10);
}
/**********************E N D**********************/
4.4 光敏电阻模块程序
unsigned char adc0804( void ) //读AD0804子程序
{ unsigned char addata,i; rd=1;wr=1;//int1=1; //读ADC0804前准备 P1=0xff; //P1全部置一准备
cs=0;wr=0;wr=1; //启动ADC0804开始测电压
rd=0; //开始读转换后数据
i=i; i=i; //无意义语句,用于延时等待ADC0804读数完毕
addata=P1;//读出的数据赋与
addate rd=1;cs=1;//读数完毕
addata=addata/2;
return(addata);//返回最后读出的数据
}
五.调试及性能分析
5.1调试过程中出现的问题
首先,在调试时,先下载一个LCD显示程序,但LCD没有结果,经过测量,发现由于滑动变阻器的阻值太大,导致LCD背光太低,致使LCD没有显示,把滑动变阻器阻值调小后,则程序出现结果。

5.2 性能分析
此系统实现的是环境温湿度光照强度的显示,以及报警功能,按键设计等。

单总线数字温度、湿度传感器,应用单片机原理,LCD显示技术,实现了实验室多点温湿度参数的实时显示和超限报警系统,保障了实验室环境的可靠性,有效地提高了实验成功率。

系统集成度高,操作容易,可靠性好,具有较高的实用价值,实践表明,该系统能够对温度、湿度进行检测,适合于对数据采样频率要求不是很高的应用场合
六.心得体会
为了设计出基于单片机的环境温湿度检测系统,搜集了大量的芯片手册,查阅了较多的图书资料,复习了所学的课本教材,分两个阶段对系统进行了设计——前期的基本设计和后期的探索设计。

前期的设计,在种类繁多的温度和湿度传感器中选定了由广州奥松公司生产的单总线数字温湿度传感器DHT11,这款传感器的优势在于通信协议相对来说比较简洁,产品价格低廉,这对设计低成本,高精度的温湿度检测系统十分有必要。

对于功能方面的要求,在调查了市场上的同类产品之后,根据实际需求来设计的。

市场上的温湿度检测系统的功能为,检测并显示温湿度数据,设置报警点并报警,与上层监控设备通信。

因此设计正是,从这几个方面的要求出发,利用单片机本身的特点,来实现系统的功能。

后期的探索设计,提升了系统的性能。

由于第一次设计基于单片机的系统,虽然完成了基本的设计要求,但在设计过程中遇到了许多硬件和软件问题还没有完全解决,设计的过程也是模块式的,没有完整系统的总体规划,后期的探索设计只是从理论上进行了可行性分析,没有做出相应的硬件并调试符合预期构想。

因此,以后还必须加强单片机系统设计的能力,毕业设计只是一个浅薄的入门。

当然,在设计过程中,应虚心听取他人的建议和意见,对解决设计过程中的问题都很有帮助。

展望未来,最终的系统应该为基于单片机的多功能环境检测系统,它不仅可以检测环境的温度、湿度、照度等所需的环境变量并显示在液晶屏幕上,可以根据设定的限值进行报警提示,可以以时间顺序存储大量的检测数据,并根据需要发送给上层分析处理设备,还可以用红外遥控实行远程无线控制,除此之外,电源系统可以适应各种供电场合,并存储部分电能,断电后确保系统可继续工作一定时间。

参考文献
[1]李瀚荪.简明电路分析.北京:高等教育出版社2002
[2]康光华.电子技术基础-模拟部分.北京:高等教育出版社1979
[3]康光华.电子技术基础-数字部分.北京:高等教育出版社1980
[4]马金龙.信号与系统.北京:科学出版社2006
[5]唐颖.单片机原理与应用.北京:北京大学出版社2008
[6]郑莉.董渊.张瑞丰.C++语言程序设计.北京:清华大学出版社2004
[7]唐文彦.传感器.北京:机械工业出版社2010
[8]陈尔绍等.电子控制电路实例.北京:电子工业出版社2004
[9]姜威.实用电子系统设计基础.北京:北京理工大学出版社2008
[10]毛兴武等.新型电子器件及其应用技术.北京:中国电力出版社2010
[11]孟贵华.电子元器件选用入门.北京:机械工业出版社2004
[12]黎小桃等.Protel99 入门与提高.北京:电子工业出版社2009
[13]郭强.液晶显示模块应用与调试.北京:电子工业出版社2010
[14]陈涛.单片机应用及C51 程序设计.北京:机械工业出版社2008
[15]钟睿.MCS-51 单片机原理及应用开发技术.北京:中国铁道出版社2006
附录1 程序清单
/**********************DHT11与12864LCD************************/ /* DHT11总线接P1^0 */ /* 晶振 11.0592M */ /*************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar lcd_x,lcd_y,data_byte=0,count;
uint TH_data,TL_data,RH_data,RL_data,CK_data;
uint TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
uchar num;
void read_io();
void delay(uint a);//延时子函数
void lcd_pos(unsigned char X,unsigned char Y);
void LCD_init();//LCD初始化程序
void LCD_dis_code(uchar x,uchar y,uchar code *s);//显示函数
void write_data(uchar dat);//写数据
void write_cmd(uchar cmd);//写指令
void delay1();//10us延时
/*****汉字地址表*****/
uchar code addr_tab[]={
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,//第一行汉字位置
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,//第二行汉字位置
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,//第三行汉字位置
0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,//第四行汉字位置
};
sbit SID = P0^1;//读写信号
sbit SCLK = P0^0;//串行时钟信号
sbit io = P1^3;//DHT11总线
uchar code lcd[]={"环境监测系统"};
uchar code lcd1[]={"温度: ℃"};
uchar code lcd2[]={"湿度: %RH"};
uchar code lcd3[]={"光强: lux"};
uchar str1[]={" "};
uchar str2[]={" "};
/******主程序******/
void main()
{
uchar k,j;
LCD_init();
LCD_dis_code(0,1,lcd);
LCD_dis_code(1,0,lcd1);
LCD_dis_code(2,0,lcd2);
LCD_dis_code(3,0,lcd3);
while(1)
{
read_io();//读取温湿度数据
//clear_gcrom();
//湿度
for(k=0; k<2; k++)
{
lcd_pos(3,k+3);
write_data(str1[k]);
}
//clear_gcrom();
//温度
for(j=0; j<2; j++)
{
lcd_pos(2,j+3);
write_data(str2[j]);
}
delay(500);
}
}
/******延时程序******/
void delay1()//延时10us
{
unsigned char i;
for(i=0; i<3; i++);
}
/******显示程序******/
void lcd_pos(unsigned char X,unsigned char Y) {
unsigned char pos;
if ( X == 1 )
{ pos = 0x80 ; }
else if ( X == 2 )
{ pos = 0x90 ; }
else if ( X == 3 )
{ pos = 0x88 ; }
else
{ pos = 0x98 ; }
write_cmd(Y | pos); //数据指针=80+地址变量
}
/**********************DHT11模块**********************/
uchar receive_byte()//接收一个字节
{
uchar i,temp;
for(i=0;i<8; i++)
{
count = 2;
while((!io) && count++)//等待50us低电平结束,并防止死循环
temp = 0;
delay1();
delay1();
delay1();
if (io==1)
{
temp = 1;
count = 2;
while(io && count++);
}
else
temp = 0;
data_byte<<=1;
data_byte|=temp;
}
return (data_byte);
}
/******开始信号******/
void read_io()//开始信号,读数据并校验
{
io = 0;
delay(18);//主机拉低18ms
io = 1;//DATA总线由上拉电阻拉高主机延时20us
delay1();
delay1();
delay1();
delay1();
io = 1;//主机设置为输入高电平,判断从机响应信号
if(!io)
{
count = 2;
while((!io)&&count++);//判断DHT11发出80us低电平响应信号是否结束
count = 2;
while(io && count++);//判断DHT11拉高总线80us高电平是否结束
RH_temp = receive_byte();
RL_temp = receive_byte();
TH_temp = receive_byte();
TL_temp = receive_byte();
CK_temp = receive_byte();
io = 1;
num = (RH_temp + RL_temp + TH_temp + TL_temp);//数据校验
if(num == CK_temp)
{
RH_data = RH_temp;
RL_data = RL_temp;
TH_data = TH_temp;
TL_data = TL_temp;
CK_data = CK_temp;
}
}
//湿度整数部分
str1[0] = (char)(0x30 + RH_data/10);
str1[1] = (char)(0x30 + RH_data%10);
//温度整数部分
str2[0] = (char)(0x30 + TH_data/10);
str2[1] = (char)(0x30 + TH_data%10);
}
/**********************E N D**********************/
/**********************12864模块程序**********************/
/*void clear_gcrom()
{
uchar i,j,k;
lcd_x = 0x80;
lcd_y = 0x80;
write_cmd(0x34);
for(i = 0 ; i < 2 ; i++) //上下两屏幕
{
for(j = 0 ; j < 32 ; j++)
{
write_cmd(lcd_y+j);
write_cmd(lcd_x);
for(k = 0 ; k < 16 ; k++)
{
write_data(0x00);
}
}
lcd_x = 0x88;
}
write_cmd(0x36);
write_cmd(0x30);
}*/
/******显示函数******/
void LCD_dis_code(uchar x,uchar y,uchar code *s)
{
write_cmd(addr_tab[8*x+y]); //写地址
while(*s>0)
{
write_data(*s); //写数据
s++;
}
}
/******初始化LCD******/
void Lcd_init(void)
{
delay(50);
write_cmd(0x30); //选择基本指令集
delay(1);
write_cmd(0x30); //选择8bit数据流
delay(1);
write_cmd(0x0c); //开显示(无游标、不反白)
delay(1);
write_cmd(0x01); //清除显示,并且设定地址指针为00H delay(30);
}
/******串行发送一个字节******/
void send_byte(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
SCLK = 0;
byte=byte<<1; //左移一位先发送高位的数据
SID = CY; //移出的位给SID
SCLK = 1; //上升沿触发发送
SCLK = 0;
}
}
/*****写指令*****/
void write_cmd(uchar Cbyte )
{
delay(1);//检测忙的子程序我们就不写了,因为串行的不支持读操作,我们就用个延时吧
send_byte(0xf8); //11111,RW(0),RS(0),0
delay(1);
send_byte(0xf0&Cbyte); //高四位
send_byte(0xf0&Cbyte<<4); //低四位(先执行<<)
}
/*****写数据*****/
void Write_data(uchar Dbyte )
{
delay(1);
send_byte(0xfa);
delay(1); //11111,RW(0),RS(1),0
send_byte(0xf0&Dbyte); //高四位
send_byte(0xf0&Dbyte<<4); //低四位(先执行<<)
}
/******延时子程序******/
void delay(uint a)
{
uint i;
while(a--)
{
for(i=0; i<113; i++);
}
}
/**********************E N D**********************/
附录2 电路原理图
附录3 PCB图
附录4 硬件电路板图。

相关文档
最新文档