基于51单片机与DS18B20的数字温度计设计.docx

上传人:b****6 文档编号:13366447 上传时间:2023-06-13 格式:DOCX 页数:36 大小:495.09KB
下载 相关 举报
基于51单片机与DS18B20的数字温度计设计.docx_第1页
第1页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第2页
第2页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第3页
第3页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第4页
第4页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第5页
第5页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第6页
第6页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第7页
第7页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第8页
第8页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第9页
第9页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第10页
第10页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第11页
第11页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第12页
第12页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第13页
第13页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第14页
第14页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第15页
第15页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第16页
第16页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第17页
第17页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第18页
第18页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第19页
第19页 / 共36页
基于51单片机与DS18B20的数字温度计设计.docx_第20页
第20页 / 共36页
亲,该文档总共36页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

基于51单片机与DS18B20的数字温度计设计.docx

《基于51单片机与DS18B20的数字温度计设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机与DS18B20的数字温度计设计.docx(36页珍藏版)》请在冰点文库上搜索。

基于51单片机与DS18B20的数字温度计设计.docx

基于51单片机与DS18B20的数字温度计设计

基于单片机的DS18B20数字温度计设计

 

内容摘要:

随着现代信息化技术的飞速发展和传统工业改造的逐步实现,能独立工作的温度检测系统已广泛应用于各种不同的领域。

本文介绍了一个基于STC89C52单片机和数字温度传感器DS18B20的测温系统,并用LED数码管显示温度值,易于读数。

系统电路简单、操作简便,能任意设定报警温度并可查询最近的10个温度值,系统具有可靠性高、成本低、功耗小等优点。

关键词:

单片机数字温度传感器温度计

 

 

1引言

随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便是不可否定的,各种数字系统的应用也使人们的生活更加舒适。

数字化控制、智能控制为现代人的工作、生活、科研等方面带来方便。

其中数字温度计就是一个典型的例子。

数字温度计与传统的温度计相比,具有读数方便、测温范围广、测温精确、功能多样话等优点。

其主要用于对测温要求准确度比较高的场所,或科研实验室使用,该设计使用STC89C52单片机作控制器,数字温度传感器DS18B20测量温度,单片机接受传感器输出,经处理用LED数码管实现温度值显示。

2设计要求

2.1基本要求

实现实时温度显示,测温范围0~500C,误差50C以内。

2.2扩展功能

温度报警,能任意设定温度范围实现声光报警;

每隔10分钟记录一次温度数据,至少能查询过去10个时刻的温度情况。

3总体方案设计

3.1方案论证

3.1.1方案一

由于本设计是测温电路,可以使用热敏电阻之类的器件,将随被测温度变化的电压或电流采样,进行A/D转换后就可以用单片机进行数据处理,实现温度显示。

这种设计需要用到A/D转换电路,增大了电路的复杂性,而且要做到高精度也比较困难。

3.1.2方案二

考虑到在单片机属于数字系统,容易想到数字温度传感器,可选用DS18B20数字温度传感器,此传感器为单总线数字温度传感器,起体积小、构成的系统结构简单,它可直接将温度转化成串行数字信号给单片机处理,即可实现温度显示。

另外DS18B20具有3引脚的小体积封装,测温范围为-55~+125摄氏度,测温分辨率可达0.0625摄氏度,其测量范围与精度都能符合设计要求。

以上两种方案相比较,第二种方案的电路、软件设计更简单,此方案设计的系统在功耗、测量精度、范围等方面都能很好地达到要求,故本设计采用方案二。

3.2总体设计框图

本方案设计的系统由单片机系统、数字温度传感器、LED显示模块、按键控制模块、温度报警模块组成,其总体架构如下图1。

图1系统总体方框图

4硬件设计

4.1单片机系统

1.本设计采用STC89C52单片机作为控制器,完成所有功能的控制,包括:

●DS18B20数字温度传感器的初始化和读取温度值

●LED数码管显示驱动与控制

●按键识别和响应控制

●温度设置和报警

●温度值的存储和读取

2.单片机系统电路原理图:

图2单片机系统原理图

4.2数字温度传感器模块

4.2.1DS18B20性能

●独特的单线接口仅需一个端口引脚进行通信

●简单的多点分布应用

●无需外部器件

●可通过数据线供电

●零待机功耗

●测温范围-55~+125℃,以0.5℃递增

●可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃

●温度数字量转换时间200ms,12位分辨率时最多在750ms内把温度转换为数字

●应用包括温度控制、工业系统、消费品、温度计和任何热感测系统

●负压特性:

电源极性接反时,传感器不会因发热而烧毁,但不能正常工作

4.2.2DS18B20外形及引脚说明

图3DS18B20外形及引脚

●GND:

●DQ:

单线运用的数据输入/输出引脚

●VD:

可选的电源引脚

4.2.3DS18B20接线原理图

单总线通常要求接一个约4.7K左右的上拉电阻,这样,当总线空闲时,其状态为高电平。

图4DS18B20接线原理图

4.2.4DS18B20时序图

主机使用时间隙来读写DS18B20的数据位和写命令字的位。

1.初始化时序如下图:

图5DS18B20初始化时序

2.DS18B20读写时序:

图6DS18B20读写时序

4.2.5数据处理

高速暂存存储器由9个字节组成,其分配如表5所示。

当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。

单片机可通过单线接口读到该数据,读取时低位在前,高位在后。

图7字节分配

下表为12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。

例如+125℃的数字输出为07D0H,

实际温度=07D0H*0.0625=2000*0.0625=125℃。

例如-55℃的数字输出为FC90H,则应先将11位数据位取反加1得370H(符号位不变,也不作运算),

实际温度=370H*0.0625=880*0.0625=55℃。

可见其中低四位为小数位。

图8DS18B20温度数据表

4.3显示电路

LED数码管显示采用动态扫描方式,能简化电路布线,节约单片机I/O端口。

段码和位码由单片机P0送出,分别用74HC673N锁存。

图9数码管驱动显示电路

4.4声光报警电路

当温度超过设定温度值时,实现声光报警,蜂鸣器鸣叫、8个发光二极管点亮。

蜂鸣器由单片机P2^3口控制,用三极管驱动,发光二极管接单片机P1口,由74HC673N锁存。

图10声光报警电路

4.5键盘输入电路

四个键分别连接单片机P3^4、P3^5、P3^6、P3^7构成独立式键盘,分别实现加、减、报警温度设定功能键和温度查询功能键。

图11键盘输入电路

5软件设计

5.1主程序模块

主程序需要调用3个子程序,分别为:

●实时温度显示子程序:

驱动数码管把实时温度值送出在LED数码管显示

●查询记录温度值子程序:

查询过去存储的温度值,最多可查询10个值

●温度设定、报警子程序:

设定报警温度值,当温度超过该值时产生报警,即驱动蜂鸣器鸣叫、8个发光二极管发光

主程序流程图:

 

图12主程序流程图

5.2读温度值模块

读温度值模块需要调用4个子程序,分别为:

●DS18B20初始化子程序:

让单片机知道DS18B20在总线上且已准备好操作

●DS18B20写字节子程序:

对DS18B20发出命令

●DS18B20读字节子程序:

读取DS18B20存储器的数据

●延时子程序:

对DS18B20操作时的时序控制

1.读温度值模块流程图:

 

 

图13读温度值子程序流程图

2.DS18B20初始化子程序流程图:

 

 

N

Y

图14DS18B20初始化子程序流程图

 

3.DS18B20写字节和读字节子程序流程图:

图15DS18B20写字节子程序流程图图16DS18B20读字节子程序流程图

 

5.3中断模块

中断采用T0方式1,初始值定时为50ms。

中断模块需调用两个子程序:

●读温度值子程序:

定时读取温度值,实时更新温度值

●记录温度值子程序:

定时记录温度值,供查询使用

把这两个子程序放在中断的原因是,不会因为调整报警温度或查询历史温度值而停止更新温度值和记录温度值。

中断模块流程图:

 

 

Y

N

 

图17中断模块流程图

5.4温度查询模块

温度查询模块需要接受按键输入,进入查询界面后,按加减键分别查询上一个和下一个历史温度值,并驱动数码管显示需要查询的温度值。

温度查询模块流程图如下:

 

N

Y

 

N

Y

 

N

Y

 

Y

N

N

Y

 

Y

N

N

Y

 

图18温度查询模块流程图

5.5温度设定、报警模块

此模块跟温度查询模块类似,需要接受按键输入,进入模块界面后,按加减键分别上调和下调设定报警温度值,当实时温度值超过设定值时驱动蜂鸣器发声,并点亮8位发光二极管,实现声光报警。

温度设定、报警模块流程图如下:

 

 

N

Y

 

N

Y

 

N

Y

 

Y

N

N

Y

 

Y

N

Y

N

 

N

Y

图19温度设定、报警模块流程图

5.6数码管驱动模块

本设计数码管通过锁存器接单片机P0口,采用动态扫描驱动7段LED数码管进行显示,需调用延时子程序以稳定显示。

模块流程图如下:

 

 

 

图20数码管驱动模块流程图

6源程序

#include

#defineucharunsignedchar

#defineuintunsignedint

/*************************变量定义************************************/

sbitDQ=P2^2;//ds18b20端口

sbitbeep=P2^3;//蜂鸣器使能端

sbitdula=P2^6;//数码管段选使能

sbitwela=P2^7;//数码管位选使能

sbitadd=P3^5;//加键

sbitsub=P3^4;//减键

sbitalarm=P3^6;//设定报警功能键

sbitrecord=P3^7;//查询温度记录功能键

ucharcodetabled[]={

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,//0~9的七段数码管段码

0x40,0x63,0x39};//-c的段码

ucharcodetablew[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//1~8个数码管的位选码

ucharrecordtable[10];//存储过去的十个温度值

uchartemperature;//温度值

ucharcountsec,recordnum,count;//计数变量

uintcountmin;//计数变量

ucharalanum=30;//报警温度值,初始值为30摄氏度

ucharz=65;//消抖延时函数入口参数

/**********************函数声明***************************************/

voiddelay1(ucharMS);//动态扫描延时子程序

voiddelay(uchari);//DS18B20工作延时子程序

voidInit_DS18B20();//DS18B20初始化子程序

voidWriteOneChar(unsignedchardat);//向DS18B20写一字节数据

ucharReadOneChar(void);//向DS18B20读一字节数据

voidGetTemperature();//由DS18B20产生温度值

voidDisplay(ucharwei,ucharduan);//数码管驱动子程序

voidAlarm();//温度报警

voidShowtemperature(uchartt);//温度显示

voidKeeprecord();//记录温度值

voidShowrecord();//显示记录的温度值

/*********************主函数*******************************************/

voidmain()

{

TMOD=0x01;//定时器初始化,定时器0方式1

TH0=(65536-50000)/256;//50ms

TL0=(65536-50000)%256;

EA=1;//开中断

ET0=1;

TR0=1;//启动定时器

while

(1)

{

Showtemperature(temperature);//显示实时温度

Alarm();//温度设定、报警

Showrecord();//查询温度记录值

}

}

 

/************************动态扫描延时函数********************************/

voiddelay1(ucharMS)

{

inti,j;

for(i=80;i>0;i--)

for(j=MS;j>0;j--);

}

/************************DS18B20工作延时函数*****************************/

voiddelay(uchari)

{

while(i--);

}

/*************************DS18B20初始化函数******************************/

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);

while(!

x)

{

x=DQ;

}

}

/*************************读一个字节**************************************/

ucharReadOneChar(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);

}

/**************************写一个字节*************************************/

voidWriteOneChar(unsignedchardat)

{

unsignedchari=0;

for(i=8;i>0;i--)

{

DQ=0;

DQ=dat&0x01;

delay(5);

DQ=1;

dat>>=1;

}

delay(5);

}

/*************************产生温度值***************************************/

voidGetTemperature()

{

uchartempL,tempH;//分别为数据低位和高位

uinttemp;

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序列号的操作

WriteOneChar(0x44);//启动温度转换

delay(200);

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度

tempL=ReadOneChar();//读出温度低位LSB

tempH=ReadOneChar();//读出温度高位MSB

temp=tempH*16+tempL/16;//tempL右移四位去掉小数位

temperature=temp&0xff;//测量0~50度,只取temp低八位

}

/**********************数码管驱动函数*************************************/

voidDisplay(ucharwei,ucharduan)

{

dula=0;

P0=0xff;

wela=1;

P0=tablew[wei];

wela=0;

P0=0;

dula=1;

P0=tabled[duan];

dula=0;

delay1

(1);

}

/**********************温度显示函数**************************************/

voidShowtemperature(uchartt)

{

Display(2,tt/10);//显示温度数值

Display(3,tt%10);

Display(4,11);//显示摄氏度单位

Display(5,12);

}

/********************温度值设定、报警函数**********************************/

voidAlarm()

{

bitflag;

if(alarm==0)

{

delay1(80);//延时消抖

if(alarm==0)

{

flag=1;//第一次按键进入设置

}

}

while(flag)

{

if(add==0)

{

delay1(z);//延时消抖

if(add==0)

{

alanum++;//add键按下,上调设定值

if(alanum==51)

{

alanum=0;//最大值为50摄氏度,循环显示

}

}

}

if(sub==0)

{

delay1(z);//延时消抖

if(sub==0)

{

alanum--;//sub键按下,下调设定值

if(alanum==255)

{

alanum=50;//最小值为0摄氏度,循环显示

}

}

}

Showtemperature(alanum);

Display(0,10);//选中数码管的其他空闲位

Display(1,10);//区别于实时温度显示“--  --”

Display(6,10);

Display(7,10);

if(alarm==0)

{

delay1(80);//延时消抖

if(alarm==0)

{

flag=0;//第二次按键退出设置

}

}

if(temperature>alanum)//此处设置报警可以保证调整设定值时即可及时报警

{

beep=0;//温度大于设定值,声光报警

P1=0;

}

else

{

beep=1;//温度不大于设定值即不报警

P1=0xff;

}

}

if(temperature>alanum)//此处设置报警即保证即使没有进入设置界面任然可以报警

{

beep=0;//温度大于设定值,声光报警

P1=0;

}

else

{

beep=1;//温度不大于设定值即不报警

P1=0xff;

}

}

/***********************温度记录函数**************************************/

voidKeeprecord()

{

uchari=9;

if(countmin==1200)//1分钟

{

countmin=0;

count++;

if(count==10)//10分钟

{

count=0;

recordnum++;//记录一次加一,最大记录10个值

if(recordnum==10)

{

recordnum=10;

}

do

{

recordtable[i]=recordtable[i-1];

}while(--i);

recordtable[0]=temperature;//最新值填入第一个位置

}

}

}/************************查询记录的温度值*************************************/

voidShowrecord()

{

bitflag;

uchara;

if(record==0)

{

delay1(80);//延时消抖

if(record==0)

{

flag=1;//record第一次按键置位进入标志

}

}

while(flag)//进入查询

{

Display(0,recordtable[a]/10);//显示温度数值

Display(1,recordtable[a]%10);

Display(2,11);//显示摄氏度单位

Display(3,12);

Display(4,10);//数码管第6、7位选中,温度值与记录数之间用--间隔

Display(5,10);

Display(6,(a+1)/10);//显示第几个记录值

Display(7,(a+1)%10);

if(add==0)

{

delay1(z);//延时消抖

if(add==0)//add按下,查看下一个值

{

if(recordnum==0)

{

a=0;

}

else

{

a++;

if(a==recordnum)//循环显示

{

a=0;

}

}

}

}

if(sub==0)//sub按下,查看上一个值

{

delay1(z);

if(sub==0)

{

if(recordnum==0)

{

a=0;

}

else

{

a--;

if(a==255)//循环显示

{

a=recordnum-1;

}

}

}

}

if(record==0)

{

delay1(80);

if(record==0)//record第二次按下,退出查看

{

flag=0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2