温度监控.docx
《温度监控.docx》由会员分享,可在线阅读,更多相关《温度监控.docx(23页珍藏版)》请在冰豆网上搜索。
温度监控
1.概述-2-
2.题目及意义-3-
2.1题目及基本要求-3-
2.2设计的目的与意义-3-
3.设计方案-3-
3.1设计思路-4-
3.2设计方案框图-4-
3.3设计原理图-5-
4.芯片简介-6-
4.1DS18B20的介绍-6-
4.1.1DS18B20主要特性:
-6-
4.1.2DS18B20引脚功能:
-7-
4.1.3工作原理-7-
4.1.4DS18B20的写操作-7-
4.1.5DS18B20的读操作-8-
4.2DS1302的介绍-8-
5.程序设计-9-
5.1程序设计思路-9-
5.1.1对应用系统的需求分析-9-
5.1.2程序模块设计-9-
5.2主程序流程图-9-
6.基于proteus的仿真-10-
6.1仿真结果-10-
6.2仿真结果分析-11-
7.总结-11-
8.源程序-12-
1.概述
单片机的出现是近代计算机技术发展史上的重要里程碑。
单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。
近年来随着电子技术和微型计算机技术的迅速发展,单片机档次的不断提高,其应用领域也在不断扩大,在工业测控、尖端科学、智能仪器仪表、日用家电、汽车电子系统、办公自动化设备、个人通信终端及通信产品中得到了广泛应用,已成为现代电子系统中最重要的智能化核心部件。
随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从数单片机技术入手,一切向着数字化控制,智能化控制方向发展。
2.题目及意义
2.1题目及基本要求
1.基于单片机的温度监控系统;
2.测温范围是-20℃---70℃;
3.分辨率小于0.5℃;
4.所测的温度值可以由LCD液晶直接显示;
5.可以任意设置上下限温度的报警功能;
6.显示日期和时间到LCD液晶;
7.使用proteus,protel软件的功能仿真和画原理图;
2.2设计的目的与意义
本课程设计是在学习了单片机的基本原理的基础上进行的,综合利用所学单片机知识完成一个单片机应用系统设计并仿真实现,从而加深对单片机软硬知识的理解,获得初步的应用经验;进一步熟悉和掌握单片机的内部结构和工作原理,了解单片机应用系统设计的基本方法和步骤。
本设计的目标是用单片机和温度传感器及相关部件实现温度的测量和数字显示,测量精度小于0.5℃,可以设置温度测量的上下限,超出测温范围可以由蜂鸣器报警,并且显示日期和时间。
本设计首先是确定目标,接下来是各个功能模块的设计和相应程序的编写。
再在proteus软件上进行仿真,若结果满足要求,则本设计达到了预期的目标。
有条件的话可以焊接硬件,若不满足继续修改,最终完成数字温度计的整个设计任务。
3.设计方案
3.1设计思路
总体设计大致可分为两部分组成:
一·温度采集模块。
二·实时时钟电路模块。
温度测量部分用数字温度芯片DS18B20测量温度,输出信号全数字化,DS18B20采用了单总线的数据传输。
由数字温度计DS18B20和单片机构成的温度测量装置,它直接输出温度的数字信号。
采用单片机控制,软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制,而且体积小,硬件实现简单,安装方便。
该系统利用芯片控制温度传感器DS18B20进行实时温度检测并显示,能够实现快速测量环境温度,并可以根据需要设定上下限温度。
该系统扩展性非常强。
该测温系统电路简单、精确度较高、实现方便、软件设计也比较简单。
时间显示电路采用由美国DALLAS公司推出的实时时钟芯片DS1302。
它可以对年、月、日、周、日、时、分、秒进行计时,且具有闰年补偿等多种功能。
传统的数据记录方式是隔时采样或定时采样,没有具体的时间记录,因此,只能记录数据而无法准确记录其出现的时间;若采用单片机计时,一方面需要采用计数器,占用硬件资源,另一方面需要设置中断、查询等,同样耗费单片机的资源,而且,某些测控系统可能不允许。
但是,如果在系统中采用时钟芯片DS1302,则能很好地解决这个问题。
3.2设计方案框图
采用8051单片机控制温度传感器DS18B20、时钟芯片DS1302和16*4的LCD完成基于单片机的库房温度监控系统。
系统框图如下所示。
图a
3.3设计原理图
图b
4.芯片简介
4.1DS18B20的介绍
DS18B20数字温度传感器由美国的DALLAS生产,它具有体积小,硬件开销低,抗干扰能力强,附加功能强的优点。
4.1.1DS18B20主要特性:
•全数字温度转换及输出。
•先进的单总线数据通信。
•最高12位分辨率,精度可达土0.5摄氏度。
•12位分辨率时的最大工作周期为750毫秒。
•可选择寄生工作方式。
•检测温度范围为–55°C~+125°C(–67°F~+257°F)
•内置EEPROM,限温报警功能。
•64位光刻ROM,内置产品序列号,方便多机挂接。
•多样封装形式,适应不同硬件系统。
4.1.2DS18B20引脚功能:
•GND电源地
•DQ单数据总线数字信号输入/输出端
•VDD外接供电电源输入端
4.1.3工作原理
DS18B20内部有两个晶振,分别是低温度系数晶振和高温度系数晶振低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。
高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。
计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
4.1.4DS18B20的写操作
(1)数据线先置低电平“0”。
(2)延时确定的时间为15微秒。
(3)按从低位到高位的顺序发送字节(一次只发送一位)。
(4)延时时间为45微秒。
(5)将数据线拉到高电平。
(6)重复上
(1)到(6)的操作直到所有的字节全部发送完为止。
(7)最后将数据线拉高。
4.1.5DS18B20的读操作
(1)将数据线拉高“1”。
(2)延时2微秒。
(3)将数据线拉低“0”。
(4)延时15微秒。
(5)将数据线拉高“1”。
(6)延时15微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时30微秒。
4.2DS1302的介绍
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
5.程序设计
5.1程序设计思路
单片机开发最重要的工作是程序设计,其思路就是利用单片机的指令系统,根据应用系统的要求编写单片机的应用程序。
5.1.1对应用系统的需求分析
改温度计可以实现数字显示被测温度,测量温度范围是-55~100℃,分辨率可以达到0.1℃,并且利用时钟电路显示时间,有高低两路限温控制功能,限温控制点可以在范围内自由设置,温度超过要求的温度,会自动报警。
5.1.2程序模块设计
1.编写单片机接受温度数据和向温度传感器写命令的函数。
2编写单片机向LCD写数据和写命令的函数。
3.编写单片机向时钟电路读数据和写命令的函数。
4.主函数设计。
5.把这些模块再进一步分解为具体的小目标,把每一个小目标
采用自顶向下,逐步求精设计方法。
5.2主程序流程图
6.基于proteus的仿真
6.1仿真结果
6.2仿真结果分析
本设计达到了预期要求
(1)能数字显示被测温度,测量温度范围可以达到0~100℃
(2)分辨率不低于0.5℃;
(3)带有计时和时间显示功能;
(4)高、低两路限温控制点可在0~100℃范围内独立设置;
(5)当温度达到高、低限温控制点发出声光报警。
7.总结
通过这次对数字温度计的设计与制作,让我了解了设计电路的程序,也让我了解了关于数字温度计的原理与设计理念,要设计一个电路总要先用仿真仿真成功之后才实际接线的。
我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,这就是我这次课程设计中的最大收获。
8.源程序
/////////////////////DS1302头文件/////////////////////////////////////////
#ifndef_REAL_TIMER_DS1302_2003_7_21_
sbitDS1302_CLK=P1^6;//实时时钟时钟线引脚
sbitDS1302_IO=P1^7;//实时时钟数据线引脚
sbitDS1302_RST=P1^5;//实时时钟复位线引脚
sbitACC0=ACC^0;
sbitACC7=ACC^7;
typedefstruct__SYSTEMTIME__
{
unsignedcharSecond;
unsignedcharMinute;
unsignedcharHour;
unsignedcharWeek;
unsignedcharDay;
unsignedcharMonth;
unsignedcharYear;
unsignedcharDateString[9];
unsignedcharTimeString[9];
}SYSTEMTIME;//定义的时间类型
#defineAM(X)X
#definePM(X)(X+12)//转成24小时制
#defineDS1302_SECOND0x80
#defineDS1302_MINUTE0x82
#defineDS1302_HOUR0x84
#defineDS1302_WEEK0x8A
#defineDS1302_DAY0x86
#defineDS1302_MONTH0x88
#defineDS1302_YEAR0x8C
#defineDS1302_RAM(X)(0xC0+(X)*2)//用于计算DS1302_RAM地址的宏
voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)
{
unsignedchari;
ACC=d;
for(i=8;i>0;i--)
{
DS1302_IO=ACC0;//相当于汇编中的RRC
DS1302_CLK=1;
DS1302_CLK=0;
ACC=ACC>>1;
}
unsignedcharDS1302OutputByte()//实时时钟读取一字节(内部函数)
{
unsignedchari;
for(i=8;i>0;i--)
{
ACC=ACC>>1;
ACC7=DS1302_IO;
DS1302_CLK=1;
DS1302_CLK=0;
}
return(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:
DS1302地址,ucData:
要写的数据
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);//地址,命令
DS1302InputByte(ucDa);//写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
}
unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr|0x01);//地址,命令
ucData=DS1302OutputByte();//读1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)//是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address,((Value/10)<<4|(Value%10)));
}
voidDS1302_GetTime(SYSTEMTIME*Time)
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_WEEK);
Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
}
voidDateToStr(SYSTEMTIME*Time)
{
Time->DateString[0]=Time->Year/10+'0';
Time->DateString[1]=Time->Year%10+'0';
Time->DateString[2]='-';
Time->DateString[3]=Time->Month/10+'0';
Time->DateString[4]=Time->Month%10+'0';
Time->DateString[5]='-';
Time->DateString[6]=Time->Day/10+'0';
Time->DateString[7]=Time->Day%10+'0';
Time->DateString[8]='\0';
}
voidTimeToStr(SYSTEMTIME*Time)
{
Time->TimeString[0]=Time->Hour/10+'0';
Time->TimeString[1]=Time->Hour%10+'0';
Time->TimeString[2]=':
';
Time->TimeString[3]=Time->Minute/10+'0';
Time->TimeString[4]=Time->Minute%10+'0';
Time->TimeString[5]=':
';
Time->TimeString[6]=Time->Second/10+'0';
Time->TimeString[7]=Time->Second%10+'0';
Time->DateString[8]='\0';
}
voidInitial_DS1302()
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)
DS1302_SetTime(DS1302_SECOND,0);
}
#endif
////////////////////////////LCD1602头文件//////////////////////////////
#ifndefLCD_CHAR_1602_2005_4_9
#include
//PortDefinitions**********************************************************
sbitLcdRs=P2^0;
sbitLcdRw=P2^1;
sbitLcdEn=P2^2;
sfrDBPort=0xB0;//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
unsignedcharLCD_Wait()
{
LcdRs=0;
LcdRw=1;_nop_();
LcdEn=1;_nop_();
LcdEn=0;
returnDBPort;
}
//向LCD写入命令或数据************************************************************
#defineLCD_COMMAND0//Command
#defineLCD_DATA1//Data
#defineLCD_CLEAR_SCREEN0x01//清屏
#defineLCD_HOMING0x02//光标返回原点
voidLCD_Write(bitstyle,unsignedcharinput)
{
LcdEn=0;
LcdRs=style;
LcdRw=0;_nop_();
DBPort=input;_nop_();//注意顺序
LcdEn=1;_nop_();//注意顺序
LcdEn=0;_nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#defineLCD_SHOW0x04//显示开
#defineLCD_HIDE0x00//显示关
#defineLCD_CURSOR0x02//显示光标
#defineLCD_NO_CURSOR0x00//无光标
#defineLCD_FLASH0x01//光标闪动
#defineLCD_NO_FLASH0x00//光标不闪动
voidLCD_SetDisplay(unsignedcharDisplayMode)
{
LCD_Write(LCD_COMMAND,0x08|DisplayMode);
}
//设置输入模式************************************************************
#defineLCD_AC_UP0x02
#defineLCD_AC_DOWN0x00//default
#defineLCD_MOVE0x01//画面可平移
#defineLCD_NO_MOVE0x00//default
voidLCD_SetInput(unsignedcharInputMode)
{
LCD_Write(LCD_COMMAND,0x04|InputMode);
}
//初始化LCD************************************************************
voidLCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38);//8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);//开启显示,无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);//清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);//AC递增,画面不动
}
voidGotoXY(unsignedcharx,unsignedchary)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0xC0|x);
if(y==2)
LCD_Write(LCD_COMMAND,0x90|x);
if(y==3)
LCD_Write(LCD_COMMAND,0XD0|x);
}
voidPrint(unsignedchar*str)
{
while(*str!