基于单片机的多点温度采集与记录系统.doc
多点温度采集与记录系统目 录一、 引言4二、硬件设计5三、软件设计9四、总结 11五、参考文献 12六、程序附录 13一、引言 温度K是一个和人们生活环境有着密切关系的物理量,也是一种在生产、科研、生活中需要测量和控制的重要物理量。在工、农业生产和日常生活中,占据着极其重要地位。工业发展与是否能掌握温度有着密切的联系。在冶金、钢铁、石化、水泥、玻璃、医药等行业都与之有关,可以说几乎80%的工业部门都不得不考虑温度对自身系统的影响。本设计是基于单片机的多点温度采集系统设计,多点温度测量显示是近几年的研究课题,随着传感技术与通讯技术的发展,单片机的出现,温度测量仪器应运而生,最近几年的研究更是迅速。采用单片机来对温度进行控制,不仅具有控制方便、组态简单和灵活性大等优点,而且可以大幅度提高被控温度的技术指标,从而能够大大提高产品的质量和数量。单片机以其功能强、体积小、可靠性高、造价低和开发周期短等优点,成为自动化和各个测控领域中必不可少且广泛应用的器件,尤其在日常生活中也发挥越来越大的作用。因此,本课题的研究在实际应用中意义十分重大。二、 硬件设计总体方案硬件设计主要是温度测量模块的内容,本设计由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的时序图。图 温度传感器DS18B20时序图2.1.3 温度显示模块功能温度显示模块的主要功能是在控制模块的控制下将控制模块写入的数据显示在液晶屏上,便于读取温度数值。显示模块采用LCD1602液晶屏。1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W读写选择端,E使能信号;以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。以下具体阐述这三个管脚:RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。R/W为读写选择,高电平进行读操作,低电平进行写操作。E端为使能端,后面和时序联系在一起。除此外,D0D7分别为8位双向数据线。其操作时序如下列图所示:图1.3 LCD1602时序图温度报警模块主要由2个led灯组成,当温度的采集值高于设定的温度上限或者低于设定的温度下限时,led灯将由暗变亮进行报警,此时此时设计者就可以改变室外的温度满足温度的需求,此报警简单易懂,可操作性强。2、 硬件电路仿真根据设计的总方案在pretues中仿真,其结果如下图;当温度超过高于设定的温度上限此处设定38或者低于下限此处设定12时,led灯发生报警。其仿真图如下所示:图1.3 温度报警显示三、 软件设计 软件设计包括下位机编程和PC机编程,下位机编程完成ds18b20的温度采集、数据处理、数码管显示,串口中断处理及硬件初始化,通信协议的制定及数据的收发。通过串口通信将温度数据在上位机上面显示,并且编译VB程序,实现报警显示。上位机程序工程:当温度1是35,温度计2是13时:当温度1是39,温度计2是11时:四、 总结通过这次课程学习制作,令我学到了很多东西受益匪浅,仿佛又经历了一次系统学习,在作做课程前,我的导师也要求我做一些温度采集的设计,我一直在查找相关资料,这次的设计让我对多点温度采集的知识了解了许多,同时也上位机编程有了初步的概念。一直来认为做这些设计没什么困难,但在实际运作过程中才清楚地认识到自己的不足和短练,端正了学习态度。这次设计使我加深稳固了基础知识,更加深刻的把握到基础知识的重要,提高了动手和实际解决问题的能力,提高了对问题整体规划的意识。能把握重点设计的核心,并提高查阅资料的能力,培养了团队合作精神和人际交往能力。由于本人水平有限,难免有考虑不足之处,所以恳请老师同学们批评指正。五、 参考文献1谭浩强C程序设计,清华大学出版社2童诗白模拟电子技术基础第四版,高等教育出版社3杨恢先、黄辉先单片机原理及应用,人民邮电出版社4何立民单片机高级教程-应用于设计第二版,北京航空航天大学出版社5蔡朝阳单片机控制实习与专题制作,北京航空航天大学出版社6蒋伏加、张林峰Visual Basic程序设计教程第4版,北京邮电大学出版社六、 程序附录单片机c语言代码:#include<reg52.h> #include<stdio.h> /标准输入输出#include<intrins.h>#define uchar unsigned char#define uint unsigned int;#define ulong unsigned long;/*/* 定义端口 */*/#define Data P0/数据端口sbit RS = P24; /Pin4sbit RW = P25; /Pin5sbit E = P26; /Pin6sbit DQ=P13;/ds18b20 端口sbit DQ1=P14;/ds18b20 端口 改动sbit D0=P16;sbit D1=P15;/*/* 全局变量 */*/uint temp=0,temp1=0;float t0,t1;float high=38,low=12,change=0;unsigned char point_flag=0,key_flag=0;unsigned char receive5;unsigned char receive_no=0;unsigned char receive_flag=0;char Text=" "uchar code TPoint16=0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9 ;/* 函数声明 */*/*/* 微秒延时函数 */*/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); /*/* 1602写入命令函数 */*/void WriteCommand(unsigned char c) DelayMs(5);/操作前短暂延时,保证信号稳定 E=0; RS=0; RW=0; _nop_(); E=1; Data=c; E=0;/*/* 1602写入数据函数 */*/void WriteData(unsigned char c) DelayMs(5); /操作前短暂延时,保证信号稳定 E=0; RS=1; RW=0; _nop_(); E=1; Data=c; E=0; RS=0;/*/* 1602写入字节函数 */*/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); /写数据/*/* 1602写入字符串函数 */*/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个字符/*/* 1602初始化函数 */*/void InitLcd() DelayMs(15); WriteCommand(0x38); /display mode WriteCommand(0x38); /display mode WriteCommand(0x38); /display mode WriteCommand(0x06); /显示光标移动位置 WriteCommand(0x0c); /显示开及光标设置 WriteCommand(0x01); /显示清屏/*/* 18b20延时函数 */*/void delay(unsigned int i)/延时函数 while(i-);/*/* 18b20初始化 */*/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);void Init_DS18B201(void) unsigned char x=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读一个字节 */*/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);unsigned char ReadOneChar1(void)unsigned char i=0;unsigned char dat = 0;for (i=8;i>0;i-) DQ1 = 0; / 给脉冲信号 dat>>=1; DQ1 = 1; / 给脉冲信号 if(DQ1) dat|=0x80; delay(5); return(dat);/*/* 18b20写一个字节 */*/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);void WriteOneChar1(unsigned char dat)unsigned char i=0;for (i=8; i>0; i-)DQ1 = 0;DQ1 = dat&0x01;delay(5);DQ1 = 1;dat>>=1;delay(5);/*/* 18b20读取温度 */*/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);unsigned int ReadTemperature1(void) unsigned char a=0;unsigned int b=0;unsigned int t=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);SCON = 0x50;TMOD |= 0x20;TL1 = 0xFD;TH1 = 0xFD;TR1 = 1;ES = 1;EA = 1;/*/* 主函数 */*/main()unsigned int TempL,TempH,TempL1,TempH1;/state,i,j,k;float wendu;InitLcd(); /初始化LCDDelayMs(15); /延时保证信号稳定UartInit();EX0=1; IT0=1; while(1)temp=ReadTemperature();temp1=ReadTemperature1(); t0=temp*0.0625;t1=temp1*0.0625;TempH=temp>>4;TempL=TPointtemp&0x0F;TempH1=temp1>>4; TempL1=TPointtemp1&0x0F; if(t0<low|t0>high)D0=0;else D0=1;if(t1<low|t1>high)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);/打印输出第二行信息elsesprintf(Text,"U:%d.%d%,D:%d.%d% ",(int)high,(int)(high*10)%10,(int)low,(int)(low*10)%10);/打印输出第二行信息void s(void) interrupt 4if(RI)RI=0;if (receive_flag=0)receive_no=0;receivereceive_no=SBUF;if (receivereceive_no=0x63) receive_flag=1; change=0; point_flag=0;elsereceive_flag=0;receivereceive_no=SBUF;if(receivereceive_no!=0x61 && receivereceive_no!=0x62 && receivereceive_no!=0x2E && point_flag=0)change=change*10+receivereceive_no-'0'receive_no+;receive_flag=1;else if(receivereceive_no=0x2E&&change!=0)point_flag=1;receive_no+;receive_flag=1;else if(receivereceive_no!=0x61 && receivereceive_no!=0x62 && receivereceive_no!=0x2E && point_flag=1)change+=(receivereceive_no-'0')*0.1;receive_no+;receive_flag=1;point_flag=0;else if(receivereceive_no=0x61)high=change;change=0;receive_flag=0;receive_no=0;point_flag=0;else if(receivereceive_no=0x62)low=change;change=0;receive_flag=0;receive_no=0;point_flag=0; void ISR_Key(void) interrupt 0 using 1key_flag=key_flag; 学习文档 仅供参考