当前位置:文档之家› 基于单片机AT89C51芯片DS18B20传感器的智能温度计设计

基于单片机AT89C51芯片DS18B20传感器的智能温度计设计

专业课程设计报告题目:基于单片机的数字温度计设计所在学院专业班级学生姓名学生学号同组队员指导教师提交日期2012年12月13 日电气工程学院专业课程设计评阅表学生姓名学生学号同组队员专业班级题目名称基于单片机的数字温度计设计一、学生自我总结二、指导教师评定目录一、设计目的 (1)二、设计要求和设计指标 (1)三、设计内容 (1)3.1主控制电路 (2)3.1.1 晶振电路 (2)3.1.2 复位电路 (2)3.2 测温电路 (3)3.3 显示电路 (3)3.4 仿真分析 (4)四、本设计改进建议 (5)五、总结 (5)六、主要参考文献 (6)附录6一、设计目的这次基于单片机的温度计设计,加强了我对单片机的理论了解,也深入学习了单片机线路的设计和编程。

理论联系实际,通过自己对基于51芯片的单片机板设计,熟悉了各元件的识别和作用,也掌握了如何使用Protues画线路图。

还加强掌握了C语言的编程应用,学习了使用Keil对单片机编程,并通过Protues进行仿真。

通过这次实训,学到东西之余,也增强了动手能力,提高了学习的兴趣,培养了创新意识。

二、设计要求和设计指标(1) 设计一个数字温度计,实现温度的采集,范围0-100℃,误差小于0.1℃;(2)选择单片机作为主控器;(3)选择合适的温度传感器进行温度测试;(4)能把采集到的温度显示出来。

三、设计内容这次设计,我们采用了AT89C51单片机芯片,做一个采温、显示功能的数字温度计。

在测温电路上,可以采用热敏电阻(如PT100)之类的器件,利用其感温效应,然后采集不同温度下的电压或者电流,进行A/D转换,然后通过单片机的数据处理,就可以获得所测的温度。

但这种设计电路较为复杂,还涉及到A/D转换,在程序的设计上面也相应变得复杂一些。

因此这次设计不予采用。

而是选择温度传感器DS18B20,DS18B20读书较为方便,通过对温度的采集,经过单片机的处理,用四位的共阴极数码管显示温度值。

这样设计电路简单,测量精度高,量程宽,而且单片机的接口便于扩展。

图3-1 单片机总体方框图3.1.1 晶振电路晶振采用12MHz,分别接入到XTAL1与XTAL2端中。

同时在晶振两端各接一个30uF的电容,每个电容的另一端再接入到地。

图3-2 晶振电路3.1.2 复位电路复位电路采用的是上电复位。

如图所示,在RST复位输入引脚上接一电容至Vcc 端,下接一个电阻到底。

线路上接一按钮,通过按下按钮,复位电路通过电容给RST 一个短暂的高电平信号。

达到复位状态。

图3-3 复位电路测温电路方面,我选择的温度传感器是DS18B20.这是美国DALLAS半导体公司最新推出的一种改进型只能温度传感器,不同于传统的热敏电阻,DS18B20能够直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字读书方式。

DS18B20 可以采用两种方式供电,一种是采用电源供电方式,此时DS18B20 的1 脚接地,2 脚作为信号线,3 脚接电源。

另一种是寄生电源供电方式,如图4 所示单片机端口接单线总线,为保证在有效的DS18B20 时钟周期内提供足够的电流,可用一个MOSFET 管来完成对总线的上拉。

当DS18B20 处于写存储器操作和温度A/D 转换操作时,总线上必须有强的上拉,上拉开启时间最大为10us。

采用寄生电源供电方式时VDD 端接地。

由于单线制只有一根线,因此发送接口必须是三态的。

这里我们把温度传感器的DQ端与P2.7相接,以P2.7作为温度输入口。

温度传感器VCC端接电源,GND端接地端。

如下图所示图3-4 温度传感器与单片机连接3.3 显示电路显示电路采用4 位共阴极LED 数码管,P0 口由上拉电阻提高驱动能力,作为段码输出并作为数码管的驱动。

P2 口的低四位作为数码管的位选端。

采用动态扫描的方式显示。

图3-5 数码管显示电路3.4 仿真分析进入Protues以后,打开我们画好的电路,并且把我们编写好的程序下载进去。

然后设置DS18B20的分辨率为0.1,设置模拟温度为29.6℃。

图3-6 DS18B20参数设置图然后启动仿真电路,执行仿真,电路正常工作。

从图中可以看出,四位共阴极LED 数码管上面显示出来的温度与我们预先设置传感器的模拟温度一致,电路能实现正常温度采集并正确显示在数码管上面,达到我们所需要的要求。

并且通过改变传感器模拟温度,显示温度能够实现实时更新,误差小于0.1℃,延时小于0.1s。

图3-7 温度计仿真电路图四、本设计改进建议本次设计用AT89C51芯片控制控制温度传感器DS18B20做成的数字温度计,电路较为简单,精度也较高。

虽然DS18B20的精度只有0.5℃,但是可以通过补偿的方法提高精度,最大精度能达到0.06℃。

但是该电路的测温范围有一定限制,只能测量-55℃~+125℃,不能在一些特定的场合来使用。

但是如果采用热电阻PT100,再加入A/D 转换电路,经单片机对采集的数据处理以后,测温范围能扩大到-200~850℃。

同时,改数字温度计只是单纯的温度检测,并没有设置相关的报警功能,可以结合单片机,加入报警功能,在达到设定温度以后触发电铃或者电灯,达到报警作用。

五、总结这次设计,首次动手自己设计电路。

把以往所学的理论知识投入到实际应用当中,加强了对课本上面知识的了解。

在设计过程中,针对测温电路这方面,研究了很长一段时间。

一开始的选择是采用传统的热电阻,然后采集对应温度下的电流和电压,通过A/D电路进单片机处理来得出温度。

这种方案的精度虽然高很多,测温范围也广,但是电路的设计复杂了很多,在编程方面也复杂了很多。

后来参考相关资料,最终选定了以DS18B20作为温度传感器来设计测温电路,通过补偿提高精度。

在设计过程中,遇到了最大的问题就是对单片机芯片不熟。

各端口的作用搞不清,在设计过程中需要不断翻书查看。

通过这样,加固了对以前所学知识的了解。

经过两个星期的设计,通过不断翻查资料,不断学习,终于完成了这次的设计,并成功仿真。

不仅提高了我们的学习兴趣,也让我真正懂得,要理论联系实际,对于以前学习的东西,如果不真正自己动手做一回,是很难真正弄懂的,只有自己认认真真动手做一回,学以致用,才能算是真正搞懂。

六、主要参考文献[1]毕淑娥. 路分析基础.机械工业出版社,2010[2]喻萍郭文川.单片机原理与接口技术.化学工业出版社,2006[3]谭浩强. C++程序设计.清华大学出版社,2009附录//温度计读写程序源代码//#include "reg51.h"#include "intrins.h"#define dm P0 //以P0口作为LED段码输出口#define uchar unsigned char#define uint unsigned intsbit DQ=P2^7; //以P2.7口作为温度传感器输入口sbit w0=P2^0; //数码管4sbit w1=P2^1; //数码管3sbit w2=P2^2; //数码管2sbit w3=P2^3; //数码管1int temp1=0; //显示当前温度和设置温度的标志位为0 时显示当前温度uint h;uint temp;uchar r;uchar high=35,low=20;uchar sign;uchar q=0;uchar tt=0;uchar scale;uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; uchar code table_dm[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40}; uchar table_dm1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};uchar data temp_data[2]={0x00,0x00};uchar data display[5]={0x00,0x00,0x00,0x00,0x00};//延时电路程序//void delay(uint t){for (;t>0;t--);}void scan(){int j;for(j=0;j<4;j++){switch (j){case 0: dm=table_dm[display[0]];w0=0;delay(50);w0=1;//xiaoshucase 1: dm=table_dm1[display[1]];w1=0;delay(50);w1=1;//geweicase 2: dm=table_dm[display[2]];w2=0;delay(50);w2=1;//shiweicase 3: dm=table_dm[display[3]];w3=0;delay(50);w3=1;//baiwei// else{dm=table_dm[b3];w3=0;delay(50);w3=1;}}}}//复位电路程序/ow_reset(void){char presence=1;while(presence){while(presence){DQ=1;_nop_();_nop_();DQ=0;---==delay(50);DQ=1;presence=DQ; //presence=0}delay(45);presence=~DQ;}DQ=1;}//DS18B20 写命令函数//void write_byte(uchar val){uchar i;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us DQ=val&0x01;delay(6);val=val/2;}DQ=1;delay(1);}//DS18B20 读1 字节函数//uchar read_byte(void){uchar i;uchar value=0;for(i=8;i>0;i--){DQ=1;_nop_();_nop_();value>>=1;DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us if(DQ)value|=0x80;delay(6); //66 us}DQ=1;return(value);}//读出温度函数//read_temp(){ow_reset();write_byte(0xcc);write_byte(0x44);ow_reset();delay(1);write_byte(0xcc);write_byte(0xbe);temp_data[0]=read_byte();temp_data[1]=read_byte();temp=temp_data[1];temp<<=8;temp=temp|temp_data[0];return temp;}//温度数据处理函数//work_temp(uint tem){uchar n=0;if(tem>6348) // 温度值正负判断{tem=65536-tem;n=1;} // 负温度求补码,标志位置1 display[4]=tem&0x0f; // 取小数部分的值display[0]=ditab[display[4]]; // 存入小数部分显示值display[4]=tem>>4; // 取中间八位,即整数部分的值display[3]=display[4]/100; // 取百位数据暂存display[1]=display[4]%100; // 取后两位数据暂存display[2]=display[1]/10; // 取十位数据暂存display[1]=display[1]%10; //个位数据r=display[1]+display[2]*10+display[3]*100;/////符号位显示判断/////if(!display[3]){display[3]=0x0a; //最高位为0 时不显示if(!display[2]){display[2]=0x0a; //次高位为0 时不显示}}if(n){display[3]=0x0b;} //负温度时最高位显示"-" }//*********设置温度显示转换************// void xianshi(int horl){int n=0;{horl=256-horl;n=1;}display[3]=horl/100;display[3]=display[3]&0x0f;display[2]=horl%100/10;display[1]=horl%10;display[0]=0;if(!display[3]){display[3]=0x0a; //最高位为0 时不显示if(!display[2]){display[2]=0x0a; //次高位为0 时不显示}}if(n){display[3]=0x0b; //负温度时最高位显示"-"}}/****************主函数************************/ void main(){dm=0x00; //初始化端口w0=0;w1=0;w2=0;w3=0;for(h=0;h<4;h++) //开机显示"0000"{display[h]=0;}ow_reset(); //开机先转换一次write_byte(0xcc); //Skip ROMwrite_byte(0x44); //发转换命令for(h=0;h<100;h++) //开机显示"0000"{scan();}while(1){if (temp1==0){work_temp(read_temp()); //处理温度数据scan(); //显示温度值}elsescan();}}。

相关主题