基于单片机的多点温度采集与记录系统.docx
《基于单片机的多点温度采集与记录系统.docx》由会员分享,可在线阅读,更多相关《基于单片机的多点温度采集与记录系统.docx(25页珍藏版)》请在冰豆网上搜索。
![基于单片机的多点温度采集与记录系统.docx](https://file1.bdocx.com/fileroot1/2023-2/24/160efba7-5abd-4fea-8ff2-c6ac78ae7739/160efba7-5abd-4fea-8ff2-c6ac78ae77391.gif)
基于单片机的多点温度采集与记录系统
多点温度采集与记录系统
一、引言4
二、硬件设计5
三、软件设计9
四、总结11
五、参考文献12
六、程序附录13
一、引言
温度(K)是一个和人们生活环境有着密切关系的物理量,也是一种在生产、科研、生活中需要测量和控制的重要物理量。
在工、农业生产和日常生活中,占据着极其重要地位。
工业发展与是否能掌握温度有着密切的联系。
在冶金、钢铁、石化、水泥、玻璃、医药等行业都与之有关,可以说几乎80%的工业部门都不得不考虑温度对自身系统的影响。
本设计是基于单片机的多点温度采集系统设计,多点温度测量显示是近几年的研究课题,随着传感技术与通讯技术的发展,单片机的出现,温度测量仪器应运而生,最近几年的研究更是迅速。
采用单片机来对温度进行控制,不仅具有控制方便、组态简单和灵活性大等优点,而且可以大幅度提高被控温度的技术指标,从而能够大大提高产品的质量和数量。
单片机以其功能强、体积小、可靠性高、造价低和开发周期短等优点,成为自动化和各个测控领域中必不可少且广泛应用的器件,尤其在日常生活中也发挥越来越大的作用。
因此,本课题的研究在实际应用中意义十分重大。
二、硬件设计
2.1总体方案
硬件设计主要是温度测量模块的内容,本设计由AT89C51单片机,LCD1602液晶显示屏,DS18B20温度传感器,以及DB9通信接口。
一共包括三大模块:
控制模块,温度采集模块,温度显示模块。
总体方案如下图所示:
1.1系统总方案图
2.1.1控制模块功能
控制模块在系统的功能是控制温度采集模块完成温度采集并将采集到的温度读入控制模块的数据寄存器,再将从温度采集模块读取的温度数据写入显示模块并控制显示模块完成温度的显示。
其中主控单位是AT89C52。
2.1.2温度采集模块功能
温度采集模块的主要功能是通过温度传感器感应温室温度并转化成模拟信号,通过转化模块将模拟信号转化成数字信号,并存取温度数据。
本设计采用2个DS18B20温度传感器,温度传感器DS18B20采用的电压是内部电压,大小为5V,一个引脚接地,一个引脚接+5V电源,中间的引脚是数据的输入输出口。
由于每个单片机开发板上有两个温度传感器,所以一个传感器的输出是P1.4,另一个传感器的输出是P1.5。
使用时将一个传感器接到单片机的18b20接口,接口的1脚接18b20的地端,接口的3脚接18b20的电源,另一个温度传感器的电源接到P0.0口,数据读写端接到P1.5口,地端接到单片机的接地端,下面是温度传感器DS18B20的时序图。
图1.2温度传感器DS18B20时序图
2.1.3温度显示模块功能
温度显示模块的主要功能是在控制模块的控制下将控制模块写入的数据显示在液晶屏上,便于读取温度数值。
显示模块采用LCD1602液晶屏。
1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:
RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。
以下具体阐述这三个管脚:
RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。
R/W为读写选择,高电平进行读操作,低电平进行写操作。
E端为使能端,后面和时序联系在一起。
除此外,D0~D7分别为8位双向数据线。
其操作时序如下图所示:
图1.3LCD1602时序图
2.1.4温读报警模块
温度报警模块主要由2个led灯组成,当温度的采集值高于设定的温度上限或者低于设定的温度下限时,led灯将由暗变亮进行报警,此时此时设计者就可以改变室外的温度满足温度的需求,此报警简单易懂,可操作性强。
2、硬件电路仿真
根据设计的总方案在pretues中仿真,其结果如图所示;
图1.4硬件电路仿真
当温度超过高于设定的温度上限(此处设定38℃)或者低于下限(此处设定12℃)时,led灯发生报警。
其仿真图如下所示:
图1.3温度报警显示
三、软件设计
软件设计包括下位机编程和PC机编程,下位机编程完成ds18b20的温度采集、数据处理、数码管显示,串口中断处理及硬件初始化,通信协议的制定及数据的收发。
通过串口通信将温度数据在上位机上面显示,并且编译VB程序,实现报警显示。
上位机程序工程:
图3.1上位机工程显示
当温度1是35℃,温度计2是13℃时:
当温度1是39℃,温度计2是11℃时:
四、总结
通过这次课程学习制作,令我学到了很多东西受益匪浅,仿佛又经历了一次系统学习,在作做课程前,我的导师也要求我做一些温度采集的设计,我一直在查找相关资料,这次的设计让我对多点温度采集的知识了解了许多,同时也上位机编程有了初步的概念。
一直来认为做这些设计没什么困难,但在实际运作过程中才清楚地认识到自己的不足和短练,端正了学习态度。
这次设计使我加深巩固了基础知识,更加深刻的把握到基础知识的重要,提高了动手和实际解决问题的能力,提高了对问题整体规划的意识。
能把握重点设计的核心,并提高查阅资料的能力,培养了团队合作精神和人际交往能力。
由于本人水平有限,难免有考虑不足之处,所以恳请老师同学们批评指正。
五、参考文献
[1]谭浩强《C程序设计》,清华大学出版社
[2]童诗白《模拟电子技术基础(第四版)》,高等教育出版社
[3]杨恢先、黄辉先《单片机原理及应用》,人民邮电出版社
[4]何立民《单片机高级教程--应用于设计(第二版)》,北京航空航天大学出版社
[5]蔡朝阳《单片机控制实习与专题制作》,北京航空航天大学出版社
[6]蒋伏加、张林峰《VisualBasic程序设计教程(第4版)》,北京邮电大学出版社
六、程序附录
单片机c语言代码:
#include
#include//标准输入输出
#include
#defineucharunsignedchar
#defineuintunsignedint;
#defineulongunsignedlong;
/******************************************************************/
/*定义端口*/
/******************************************************************/
#defineDataP0//数据端口
sbitRS=P2^4;//Pin4
sbitRW=P2^5;//Pin5
sbitE=P2^6;//Pin6
sbitDQ=P1^3;//ds18b20端口
sbitDQ1=P1^4;//ds18b20端口改动
sbitD0=P1^6;
sbitD1=P1^5;
/******************************************************************/
/*全局变量*/
/******************************************************************/
uinttemp=0,temp1=0;
floatt0,t1;
floathigh=38,low=12,change=0;
unsignedcharpoint_flag=0,key_flag=0;
unsignedcharreceive[5];
unsignedcharreceive_no=0;
unsignedcharreceive_flag=0;
charText[]="";
ucharcodeTPoint[16]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
/*函数声明*/
/******************************************************************/
/******************************************************************/
/*微秒延时函数*/
/******************************************************************/
voidDelayUs(unsignedcharus)//delayus
{
unsignedcharuscnt;
uscnt=us>>1;/*12MHz频率*/
while(--uscnt);
}
/******************************************************************/
/*毫秒函数声明*/
/******************************************************************/
voidDelayMs(unsignedcharms)
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
/******************************************************************/
/*1602写入命令函数*/
/******************************************************************/
voidWriteCommand(unsignedcharc)
{
DelayMs(5);//操作前短暂延时,保证信号稳定
E=0;
RS=0;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
}
/******************************************************************/
/*1602写入数据函数*/
/******************************************************************/
voidWriteData(unsignedcharc)
{
DelayMs(5);//操作前短暂延时,保证信号稳定
E=0;
RS=1;
RW=0;
_nop_();
E=1;
Data=c;
E=0;
RS=0;
}
/******************************************************************/
/*1602写入字节函数*/
/******************************************************************/
voidShowChar(unsignedcharpos,unsignedcharc)
{
unsignedcharp;
if(pos>=0x10)
p=pos+0xb0;//是第二行则命令代码高4位为0xc
else
p=pos+0x80;//是第二行则命令代码高4位为0x8
WriteCommand(p);//写命令
WriteData(c);//写数据
}
/******************************************************************/
/*1602写入字符串函数*/
/******************************************************************/
voidShowString(unsignedcharline,char*ptr)
{
unsignedcharl,i;
l=line<<4;
for(i=0;i<16;i++)
ShowChar(l++,*(ptr+i));//循环显示16个字符
}
/******************************************************************/
/*1602初始化函数*/
/******************************************************************/
voidInitLcd()
{
DelayMs(15);
WriteCommand(0x38);//displaymode
WriteCommand(0x38);//displaymode
WriteCommand(0x38);//displaymode
WriteCommand(0x06);//显示光标移动位置
WriteCommand(0x0c);//显示开及光标设置
WriteCommand(0x01);//显示清屏
}
/******************************************************************/
/*18b20延时函数*/
/******************************************************************/
voiddelay(unsignedinti)//延时函数
{
while(i--);
}
/******************************************************************/
/*18b20初始化*/
/******************************************************************/
voidInit_DS18B20(void)
{
unsignedcharx=0;
DQ=1;//DQ复位
delay(8);//稍做延时
DQ=0;//单片机将DQ拉低
delay(80);//精确延时大于480us
DQ=1;//拉高总线
delay(10);
x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败
delay(5);
}
voidInit_DS18B201(void)
{
unsignedcharx=0;
DQ1=1;//DQ复位
delay(8);//稍做延时
DQ1=0;//单片机将DQ1拉低
delay(80);//精确延时大于480us
DQ1=1;//拉高总线
delay(10);
x=DQ1;//稍做延时后如果x=0则初始化成功x=1则初始化失败
delay(5);
}
/******************************************************************/
/*18b20读一个字节*/
/******************************************************************/
unsignedcharReadOneChar(void)
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay(5);
}
return(dat);
}
unsignedcharReadOneChar1(void)
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ1=0;//给脉冲信号
dat>>=1;
DQ1=1;//给脉冲信号
if(DQ1)
dat|=0x80;
delay(5);
}
return(dat);
}
/******************************************************************/
/*18b20写一个字节*/
/******************************************************************/
voidWriteOneChar(unsignedchardat)
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(5);
}
voidWriteOneChar1(unsignedchardat)
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ1=0;
DQ1=dat&0x01;
delay(5);
DQ1=1;
dat>>=1;
}
delay(5);
}
/******************************************************************/
/*18b20读取温度*/
/******************************************************************/
unsignedintReadTemperature(void)
{
unsignedchara=0;
unsignedintb=0;
unsignedintt=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);
}
unsignedintReadTemperature1(void)
{
unsignedchara=0;
unsignedintb=0;
unsignedintt=0;
Init_DS18B201();
WriteOneChar1(0xCC);//跳过读序号列号的操作
WriteOneChar1(0x44);//启动温度转换
delay(200);
Init_DS18B201();
WriteOneChar1(0xCC);//跳过读序号列号的操作
WriteOneChar1(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度
a=ReadOneChar1();//低位
b=ReadOneChar1();//高位
b<<=8;
t=a+b;
return(t);
}
voidUartInit(void)//******************
{
SCON=0x50;
TMOD|=0x20;
TL1=0xFD;
TH1=0xFD;
TR1=1;
ES=1;
EA=1;
}
/******************************************************************/
/*主函数*/
/******************************************************************/
main()
{
unsignedintTempL,TempH,TempL1,TempH1;//state,i,j,k;
floatwendu;
InitLcd();//初始化LCD
DelayMs(15);//延时保证信号稳定
UartInit();
EX0=1;
IT0=1;
while
(1)
{
temp=ReadTemperature();
temp1=ReadTemperature1();
t0=temp*0.0625;
t1=temp1*0.0625;
TempH=temp>>4;
TempL=TPoint[temp&0x0F];
TempH1=temp1>>4;
TempL1=TPoint[temp1&0x0F];
if(t0high)
{
D0=0;
}
else
{
D0=1;
}
if(t1high)
{
D1=0;
}
else
{
D1=1;
}
SBUF=0xff;//校验
while(!
TI);
TI=0;
SBUF=TempH;
while(!
TI);
TI=0;
SBUF=TempL;
while(!
TI);
TI=0;
SBUF=TempH1;
while(!
TI);
TI=0;
SBUF=TempL1;
while(!
TI);
TI=0;
SBUF=(int)wendu;
while(!
TI);
TI=0;
SBUF=(int)(wendu*10)%10;
while(!
TI);
TI=0;
SBUF=(int)high;
while(!
TI);
TI=0;
SBUF=(int)(high*10)%10;
while(!
TI);
TI=0;
SBUF=(int)low;
while(!
TI);
TI=0;
SBUF=(int)(low*10)%10;
while(!
TI);
TI=0;
ShowString(0,Text);
if(key_flag==0)
sprintf(Text,"%d.%d%cC,%d.%d%cC",TempH,TempL,0xdf,TempH1,TempL1,0xdf);//打印输出第二行信息
else
sprintf(Text,"U:
%d.%d%%,D:
%d.%d%%",(int)high