课程设计(论文)基于DS18B20的多点温度测量系统.doc
课 程 设 计 报 告( 2010 2011 年度 第 2学期 ) 题 目:基于DS18B20的多点温度测量系统 院 系: 姓 名: 学 号: 专 业: 指导老师: 2011年 5 月 22 日一、设计任务及要求设计任务:设计一个基于DS18B20的多点温度测量系统。要 求: 1)测量点为多点(做2点);2)测量的温度范围为;3)测量的精度在;4)系统响应时间为1s;5)数据传输方式:采用串行数据传送的方式。2011年 5 月 22 日 目录1设计要求2设计的作用、目的3设计的具体实现.3.1系统概述.3.2 单元电路设计与分析3.3电路的安装与调试4 心得体会及建议4.1 心得体会4.2 建议5 附录6参考文献基于DS12B20的多点温度测量系统设计报告1 设计要求运用DS12B20温度测量芯片实现一个多点温度测量系统,要求如下:(1)测量点为两点。(2)测量的温度为-40+40°C(3)温度测量的精度为±0.5°C(4)测量系统的响应时间要小于1S。(5)温度数据的传输方式采用串行数据传送的方式。2 设计的作用、目的通过本设计可以进一步了解熟悉单片机的控制原理以及外设与单片机的数据通信方法,尤其是串行通信方法以及单片机与外设间的接口问题。本设计旨在提高学生的实际应用系统开发能力,增长学生动手实践经验,激起学生学以致用的兴趣。3设计的具体实现3.1系统概述本系统分为温度采集模块、核心处理模块、控制模块和显示模块。温度采集模块由DS18B20温度测量芯片构成,它负责测量温度后将温度量转化为数字信号,传输到数据处理模块;核心处理模块由AT89S52单片机组成,它负责与温度采集模块进行数据通信、对数据进行操作处理已经对各种外设的响应与控制;控制模块由几个按键组成,实现对测量点的选择以及电路复位的操作;显示模块由一块四位的八段译码显示管和驱动芯片组成,它的作用是显示测量的温度值。系统模块组成图:核心处理模块温度采集模块显示模块控制模块3.2 单元电路设计与分析 一、模块详解:1. 温度采集单元。采用DALLAS公司的DS18B20温度传感器,该温度传感器将温度检测与数字数据输出全集成于一个芯片上,它的一个工作周期分为温度检测和数据处理两个部分,它采用单数据总线进行数据传输,由于本设计采用两点测量温度,两个温度传感器的输出数据脚共连在单片机的数据引脚上,因此在进行温度检测和数据处理中需要首先利用DS18B20的ROM操作指令对温度传感器的ROMID进行识别,以针对特定的温度传感器进行操作。(对DS18B20的操作指令见附录文件,识别ROM-ID的子程序见附录程序)DS18B20的主要特征:·全数字温度转换及输出·先进的单总线技术·最高12位的分辨率时的最大工作周期为750毫秒·可选择寄生工作方式·检测温度范围为-55°C+125°C·内置EEPROM,限温度报警·64位光刻ROM,内置产品序列号,方便多机挂接·多种封装形式,适应不同硬件2 核心处理单元。采用Atmel公司的AT89S52单片机,它作为系统的核心部分,和温度采集单元之间,它直接对温度传感器进行指令操作,获取温度传感器的温度数据后进行各种处理,然后通过显示模块显示出温度值,工作过程中,接收来自控制模块的信号,并对其作出相应的响应。 AT89S52是一种低功耗、高性能CMOS 8位微控制器,具有8K 在系统可编程Flash 存储器。使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。3. 控制模块。采用几个按钮开关和相应的几个10K电阻组成,当按下按钮是,得到一个低电平信号送入单片机,松开开关后变回高电平信号,单片机识别此信号并对此做出响应。 4. 显示模块。采用一个四位的八段译码管和一块八位锁存器74HC373组成,采用扫描显示的方式显示四位数据。 (a)八段数码管结构 (b)共阴型数码管 (c)共阳型数码管 八段LED数码显示管原理和结构数码管分为共阳型和共阴型,共阳极型就是发光管的正极都连在一起 ,作为一条引线,负极分开。八段数码发光管就是8个发光二极管组成的,在空间排列成为8字型带个小数点,只要将电压加在阳极和阴极之间相应的笔画就会发光。8个发光二极管的阳极并接在一起,8个阴极分开,因此称为共阳八段数码管。相反则为共阴八段数码管。共阴极八段译码管显码表:(输入为sp、g、f、e、d、c、b、a)输入输出输入输出3FH07FH806H16FH95BH277HA4FH37CHB66H439HC6DH55EHD7DH679HE07H771HF*显示小数点时sp位置为1就可以了。*二、电路仿真:使用PROTEUS仿真软件对设计电路进行仿真,程序部分用KEIL软件进行编写。仿真图如下:仿真中,调整DS18B20的温度,可以看到显示器上面的温度也相应的变为调整后的温度,通过按下button2或者button1可以更换温度传感器的选择。仿真中的单片机使用的程序数据文件由KEIL软件编译生成,详细的程序参考附录中的主程序。由于实际电路中要用到DS18B20的ROM_ID码,所以专门设计了提取ID码的电路,提取ID码得程序在参考附录中的提取ROM_ID码程序。提取的ID码会在显码管上以一次显示一个字节的方式显示出来,显示八组,一共是八字节的ID码。电路图如下:3.3电路的安装与调试 电路仿真通过后,开始实际的焊接过程,焊接过程比较繁琐,需要认真小心操作,确保焊接的线路不出现错误,由于缺乏焊接经验,焊接线路比较混乱,焊接过程花费比较长的时间,完成焊接后,就是开始检查调试了,使用万用表检查电源电路无故障后,就开始安装芯片开始调试了。初次调试时发现数码管显示非常不稳定,现实的非常不连续,过分析,确定应该是程序中的扫描时间不合适,经过几次的程序修改和实物调试观察后,最终解决了这个问题。然后就是电路性能检测,使用普通的温度计,测量室内温度后,再用制作的电路测量室内温度,数据分别为32.5和32.8,几次测量后得出的结论,精度满足0.5的要求。响应时间直接利用感官判断,系统的响应时间在1s内。两个温度传感器掘客正常测量温度,各个控制开关功能正常。经过一段时间的运行测试,工作正常,完成调试过程。4 心得体会及建议4.1 心得体会经过本次设计实验,充分认识到了自身再动手实际操作方面的不足,单片机程序的编写不够熟练,电路焊接很生疏,需要多加练习。4.2 建议希望在以后的学习中能过再多做类似本设计的练习,提高动手能力,夯实基础知识。5 附录 5.1 原件明细表DS18B20两个、AT89S52一块、74HC573一块、按钮开关3个、10K电阻三个、4.7K电阻两个、10uf电解电容一个、四位八段数码管一个。5.2 设计原理图 参看上面的仿真图。5.3 设计的主程序:#include <reg51.h>#define uchar unsigned char#define uint unsigned intsbit DS=P20; /定义温度传感器的数据引脚 sbit button1=P35; /定义按钮开关的控制位脚sbit button2=P36; uint temp; / 温度值sbit dula=P26;uchar code table=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;uchar code table1=0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd, 0x87,0xff,0xef;uchar code ROM_CODE1=0x28,0xaa,0x4b,0x27,0x03,0x00,0x00,0x06;uchar code ROM_CODE2=0x28,0x1b,0x40,0x12,0x03,0x00,0x00,0x8f;void delay(uint count) /延时函数 uint i; while(count) i=200; while(i>0) i-; count-; void dsreset() /18B20复位,初始化函数 uint i; DS=0; i=103; while(i>0)i-; DS=1; i=6; while(i>0)i-;bit tmpreadbit() / 读1位数据函数 uint i; bit dat; DS=0; i+;i+; DS=1; i+;i+; dat=DS; i=8; / 短延时 while(i>0)i-; return (dat);uchar tmpread() /读1字节函数 uchar i,j,dat; dat=0; for(i=1;i<=8;i+) j=tmpreadbit(); dat=(j<<7)|(dat>>1); /读出的数据最低位在最前面,这样刚好一个字节在DAT里 return(dat);void tmpwritebyte(uchar dat) /write a byte to ds18b20 向1820写一个字节数据函数 uint i; uchar j; bit testb; for(j=1;j<=8;j+) testb=dat&0x01; dat=dat>>1; if(testb) /write 1 DS=0; i+;i+; DS=1; i=8;while(i>0)i-; else DS=0; /write 0 i=8;while(i>0)i-; DS=1; i+;i+; void match_rom(uchar fp) /匹配ROM IDchar k;tmpwritebyte(0x55); / 发送匹配ROM命令if(fp) for(k=0;k<8;k+) tmpwritebyte(ROM_CODE1k);/发送18B20的序列号,先发送低字节 else for(k=0;k<8;k+) tmpwritebyte(ROM_CODE2k);void tmpchange(uchar a) /转换温度 dsreset(); delay(1); match_rom(a); tmpwritebyte(0x44);uint tmp(uchar fp) /读取寄存器中存储的温度数据 float tt; uchar a,b; dsreset(); delay(1); match_rom(fp); tmpwritebyte(0xbe); a=tmpread(); /读低8位 b=tmpread(); /读高8位 temp=b; temp<<=8; /two byte compose a int variable 两个字节组合为1个字 temp=temp|a; tt=temp*0.0625; /温度在寄存器中是12位,分辨率是0.0625 temp=tt*10+0.5; /乘10表示小数点后只取1位,加0.5是四折五入 return temp;void display(uint temp)/显示程序 uchar A0,A1,A2,A2t,A3,ser; ser=temp/10; SBUF=ser; A0=temp/1000; A1=temp%1000/100; A2t=temp%100; A2=A2t/10; A3=A2t%10; dula=1; P1=tableA0;/显示千位 P3=0Xfe; dula=0; delay(1); dula=1; P1=tableA1;/显示百位 P3=0Xfd; dula=0; delay(1); dula=1; P1=table1A2;/显示十位 P3=0xfb; dula=0; delay(1); dula=1; P1=tableA3;/显示个位 P3=0xf7; dula=0; delay(1); dula=1; void main() uchar fp=1; uint x=0; while(1) if(button1=0|(button1=1&&button2=1) /按下一号键或者不按键时显示A的温度测量值 delay(1); /延时去抖动 if(button1=0|(button1=1&&button2=1) do fp=1; tmpchange(fp); display(x); display(x); x=tmp(fp); display(x);display(x); while(button2=1); if(button2=0) /按下二号键测量B的温度 delay(1); if(button2=0) do fp=0; tmpchange(fp); display(x);display(x); x=tmp(fp); display(x);display(x); while(button1=1); 5.4用来提取DS18B20的ROM-ID码子程序物理电路公用上面的原理电路,但是提取ID码时每次只能接一个DS18B20在上面,不然就没法提取了。程序如下:#include <reg51.h> #define uchar unsigned char#define uint unsigned intsbit DS=P20; sbit dula=P26;uint temp; uchar tab16=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;uchar t18;void delay_ms(uchar i) /延时(j*2+1+2)*i+5 个机器周期 uchar j; /12MHz时,延时 0.5*i ms doj=248; doj-;while(j); i-; while(i); void DS_init(void) /18B20复位,初始化函数 uint i; DS=0; i=103;while(i>0)i-; DS=1; i=4;while(i>0)i-;bit read_bit(void) /读1位数据函数 uint i; bit dat; DS=0;i+; DS=1;i+;i+; dat=DS; i=8;while(i>0)i-; return (dat);uchar read_byte(void) /读1字节函数 uchar i,j,dat; dat=0; for(i=1;i<=8;i+) j=read_bit(); dat=(j<<7)|(dat>>1); /读出的数据最低位在最前面,这样刚好一个字节在DAT里 return(dat);void write_byte(uchar dat) /向1820写一个字节数据函数 uint i; uchar j; bit testb; for(j=1;j<=8;j+) testb=dat&0x01; dat=dat>>1; if(testb) /write 1 DS=0; i+;i+; DS=1; i=8;while(i>0)i-; else DS=0; /write 0 i=8;while(i>0)i-; DS=1; i+;i+; void main() uchar i,a,b,j; dula=0; DS_init(); delay_ms(16); write_byte(0x33); for(i=0;i<8;i+) t1i=read_byte(); for(i=0;i<8;i+) /显示64位的ID码 for(j=90;j>0;j-) a=t1i; a>>=4; b=t1i&0x0f; P3=0xfe; P1=taba; delay_ms(10); P3=0xfd; P1=tabb; delay_ms(10); P3=0xf7; P1=tabi; delay_ms(10); 6参考文献1李群芳. 单片机微型计算机与接口技术第三版.电子工业出版社,2010.12 谢自美电子线路设计实验测试(第二版)M武汉:华中科技大学出版社,20003 丘玉娟 用串行ROM和AT89C51实现电子密码锁J电脑知识与技术2005,11(3):34364李金平·电子系统设计·电子工业出版社·2009