DS18B20温度采集报告.docx
《DS18B20温度采集报告.docx》由会员分享,可在线阅读,更多相关《DS18B20温度采集报告.docx(20页珍藏版)》请在冰豆网上搜索。
![DS18B20温度采集报告.docx](https://file1.bdocx.com/fileroot1/2023-2/1/0dd67987-489c-44a9-89eb-5af14020ea43/0dd67987-489c-44a9-89eb-5af14020ea431.gif)
DS18B20温度采集报告
南京信息工程大学
滨江学院
课程论文
(单片机原理及应用)
题目DS18B20温度采集报告
学生姓名仇丽华
学号20082305902
院系滨江学院电子工程
专业电子信息工程
指导教师朱艳萍
概述
硬件电路的单片机芯片采用AT89S52芯片,进行数据处理。
数据采集部分的传感器采用DS18B20芯片数字温度传感器。
,用七段LED数码显示器显示测量的温度值,超过预定的温度值则会产生报警。
硬件电路设计
1、AT89S52芯片
AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
使用Atmel公司高密度非易失性存储器技术制造,与工业80C51产品指令和引脚完全兼容。
片上Flash允许程序存储器在系统可编程,亦适于常规编程器。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得AT89S52在众多嵌入式控制应用系统中得到广泛应用。
2、DS18B20芯片
(1)DS18B20简介
DS18B20是由美国DALLAS公司生产的单线数字温度传感器芯片。
与传统的热敏电阻有所不同,DS18B20可直接将被测温度转化为串行数字信号,以供单片机处理,它还具有微型化、低功率、高性能、抗干扰能力强等优点。
通过编程,DS18B20可以实现9~12位的温度读数。
信息经过单线接口送入DS18B20或从DS18B20送出,因此从微处理器到DS18B20仅需连接一条信号线和地线。
读、写和执行温度变换所需的电源可以由数据线本身提供,而不需要外部电源。
(2)DS18B20的引脚功能
DS18B20的引脚(图7-10),其功能如表7-8所示。
(3)DS18B20的主要特点
v采用单线技术,与单片机通信只需一个引脚;
v通过识别芯片各自唯一的产品序列号从而实现单线多挂接,简化了分布式温度检测的应用;
v实际应用中不需要外部任何器件即可实现测温;
v可通过数据线供电,电压的范围在3~5.5V;
v不需要备份电源;
v测量范围为-55~+125℃,在-10~+85℃范围内误差为0.5℃;
v数字温度计的分辨率用户可以在9位到12位之间选择,可配置实现9~12位的温度读数;
v将12位的温度值转换为数字量所需时间不超过750ms;
v用户定义的,非易失性的温度告警设置,用用户可以自行设定告警的上下限温度。
(4)DS18B20内部结构
64位ROM的结构开始8位是产品类型的编号,接着是每个器件的惟一的序号,共有48位,最后8位是前面56位的CRC检验码,这也是多个DS18B20可以采用一线进行通信的原因。
温度报警触发器TH和TL,可通过软件写入户报警上下限。
DS18B20温度传感器的内部存储器还包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。
高速暂存RAM的结构为8字节的存储器,结构如图3所示。
头2个字节包含测得的温度信息,第3和第4字节TH和TL的拷贝,是易失的,每次上电复位时被刷新。
第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。
DS18B20工作时寄存器中的分辨率转换为相应精度的温度数值。
该字节各位的定义如下图所示。
低5位一直为1,TM是工作模式位,用于设置DS18B20在工作模式还是在测试模式,DS18B20出厂时该位被设置为0,用户要去改动,R1和R0决定温度转换的精度位数,来设置分辨率
DS18B20内部结构
3、实验原理图
AT89S52控制DS18B20完成温度转换必须经过三个步骤:
初始化、ROM操作指令、存储器操作指令,必须先启动DS18B20开始转换,再读出温度转换值,本实验系统挂接一个DS18B20芯片,可使用默认的12位转换精度,外接供电电源,单片机与DS18B20的接口用的是单片节的P2.4口。
电路焊接时按照电路图焊接,将电源部分、ISP接口、18B20、蜂鸣器、LED显示和单片机模块连接起来,按照引脚相同标号连接。
等焊接完成后将程序下载到芯片里进行调试。
查看焊接的板子有没有问题。
我们的板子刚刚下进去程序后数码管没显示,后经过检查,发现数码管的引脚焊反了,改正后板子能够正确显示。
板子显示29.8,温度没有超过设定的30,所以蜂鸣器不会响。
软件设计
实验原理
测温系统的原理主要是DS18B20去采集温度,然后单片机负责提供时钟频率,分析处理数据,送给LED显示。
DS18B20低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。
高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。
计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
原理图的18、19脚就是晶振原理图,9脚是复位原理图,可以使单片机清零。
实验内容
(1)如下的流程图,在keil编译环境下编制程序,需要采集温度并判断温度所处范围,如果超出温度范围则报警;报警通过实验板上的蜂鸣器实现,报警温度可以通过键盘设置;最后生成*.HEX文件。
(2)通过ISP将生成的*.HEX文件下载到单片机中,运行程序。
(3)观测LCD上显示的温度数据,通过键盘操作控制报警温度。
主流程图
中断流程图
程序代码
//DS18B20温度传感器程序
#include
#defineAlarm10
sbitBeep=P3^4;
sbitDQ=P2^4;
unsignedchartempL=0,tempH=0;//数据传输线接单片机的相应引脚
unsignedcharflag=0;//设全局变量
unsignedinttemperature,negtemper;//温度值保存在temperature里
unsignedcharidataaddrdat[2]={0x0,0x0};
unsignedchartab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};/*0123456789*/
unsignedchartab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsignedchardispbuf[3]={0,0,0};
unsignedcharwarning=20;
biton=0,off=1;
//*****************************************************************************
//延时子程序//**
voiddelay(unsignedinti)
{while(i--);}
voidbeep(biti)
{Beep=i;}
//*****************************************************************************
//初始化程序
Init_DS18B20(void)
{unsignedcharx=0;
DQ=1;//DQ先置高
dalay(8);//稍延时
DQ=0;//发送复位脉冲
delay(85);//延时(>480us)
DQ=1;//拉高数据线
delay(14);//等待(15~60us)
x=DQ;//用x的值来判断初始化程序有没有成功,DS18B20存在的话x=0,
//否则为1
delay(20);
}//****************************************************************************
//读一个字节
ReadOneChar(void)//主机数据线先从高电平拉至低电平,保持1ms以上,
//再使数据线升为高电平,从而产生读信号
{unsignedchari=0;//每个读周期最短的持续时间为60us,各个读周期之间
//必须有一个1ms以上的高电平恢复期
unsignedchardat=0;
for(i=8;i>0;i--)//一个字节有8位
{DQ=1;
delay
(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);}
return(dat);}
//******************************************************************
//写一个字节
WriteOneChar(unsignedchardat)
{unsignedchari=0;//数据线从高电平拉至低电平,产生写起始信号
//15ms之间将所需写的位送到数据线上
for(i=8;i>0;i--)//在15~60ms之间对数据线进行采样,如果是高电平
//就写1,低电平就写0
{DQ=0;//在开始另一个写周期前必须有1ms以上的高电平恢复期
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;}
delay(4);}
//*********************************************************************
ReadTemperature(void)
{Init_DS18B20();//初始化
WriteOneChar(0xcc);//跳过读序列号的操作
WriteOneChar(0x44);//启动温度转换
delay(125);//转换需要一点时间,延时
Init_DS18B20();//初始化
WriteOneChar(0xcc);//跳过读序列号的操作
WriteOneChar(0xbe);//读温度寄存器(头两个值分别为温度的低位和高位)
tempL=ReadOneChar();//读出温度的低位LSB
tempH=ReadOneChar();//读出温度高位MSB
temperature=(tempH*256)+tempL; //温度转换,对高、低位做相应的运算,转化为
//实际温度
return(temperature);}
//**********************************************************************
voidDispbu(unsignedinttemper)
{dispbuf[2]=(temper>>4)%10;//取十位
dispbuf[1]=(temper>>4)%10;//取个位
if(temper&0x8)//小数位
dispbuf[0]=0x55;
elsedispbuf[0]=0;
}
unsignedchargetkey()//键盘扫描程序
{P2=0xff;
P2=oxfe;
if((P2&0xff)!
=0xfe)
{delay(5000);
if((P2&0xff)!
=0xfe)
returnP2;
elseP2=0xfd;
}
elseP2=oxfd;
if(P2&0xff)!
=0xfd;
{delay(5000);
if((P2&0xff)!
=0xfd)
returnP2;
elseP2=oxfd;
}
elseP2=0xfd;
if((P2&0xff)!
=0xfd)
{delay(5000);
if((P2&0xff)!
=0xfd)
returnP2;
elseP2=0xfd;
}
elseP2=0xf7;
if((P2&0xff)!
=0xf7)
{delay(5000);
if((P2&0xff)!
=0xf7)
returnP2;
elsereturnP2=0xfe;
}
}
Inter0_process()interrupt2//外部中断1
{
unsignedcharkey;
inti;
unsignedchardis=0x01;
unsignedintj;
for(j=5000;j>0;j--)
{
key=getkey();//取键值
if(key==0xee)//如1键按下,则温度值递增
{warning++;
delay(8000);
}
if(key==0xed)
{//如5键按下,则温度值递增
warning--;
delay(8000);
}
if(key==0x77)//按下16键则退出中断
j=1;
for(i=0;i<2;i++)//设置两位报警值,并在LED上显示
{
P1=dis;
dis<<=1;
if(i==0)
P0=tab[warning%10];
else
P0=teb[warning/10];
delay(200);
}
dis=0x01;
}
}
//****************************************************************************
//主程序
main()
{unsignedchari,npos=0x01;
P0=0xff;
P2=0xff;
P1=0xff;
EX1=1;//开中断1
IT1=1;//下降沿触发
ET1=1;
EA=1;//开总中断
while
(1)
{
if((temperature&0xf000)==0xf000)//判断是否是负温度
{
ReadTemperature();
for(i=0;i<4;i++)//4位显示
{
negtemper=(~temperature)+1;//取原码
Dispbuf(negtemper);//取位值
P1=npos;
npos<<1;//循环使能
if(i==1)//第二位显示有点
{
P0=tab1[dispbuf[i]];//查表显示
delay(700);
}
elseif(i==3)//显示负号
P0=0xbf;
else
{
P0=tab[dispbuf[i]];
delay(700);
}
}
npos=0x01;
}
else//如不是负温度
{
for(i=0;i<3;i++)//为负则显示3位
{ReadTemperature();//读温度值
Dispbuf(temperature);
if(((temperature>>4)&0xff)>=warning)//温度值大于报警温度值则报警
beep(0n);//蜂鸣器响
elsebeep(off);//不响
P1=npos;
npos<<=1;//循环显示
if(i==1)
P0=tab1[dispbuf[i]];
else
P0=tab[dispbuf[i]];
delay(100);
}
npos=0x01;
}
}
}
总结
通过这次单片机实验让我知道了C语言的重要性。
以前学的时候以为只可以写写简单的程序,现在知道和单片机联合起来可以实现很多很多功能。
所以我们一定要加强这方面的知识。
板子焊的再漂亮,没有程序还等于零。
在焊接板子时先将排阻和AT89S52连接起来,排阻一边有个小点的地方时1脚,然后顺序往下焊接。
将芯片的9脚复位键焊上一个开关,开关按钮有六个端,用万用表电阻档检测,检测一端,用表笔碰触任两个,当按下去的时候万用表有偏斜,就用那两个脚连接。
在芯片的18、19脚按图焊上晶振,产生时钟频率。
在芯片的40脚焊上两个并联的电容,然后接地。
在21、22、23脚分别焊上三个开关,可以控制温度的加一、减一和退出。
然后将LED显示部分焊上,将数码管同芯片按图焊在一起,同时在P1.0、P1.1、P1.2、P1.3口焊接四个三极管将电流放大,使数码管显示更亮。
然后将蜂鸣器按图焊接,在电路图中也焊接了一个三极管,可将声音进行放大。
然后将18B20按图焊接,18B20的2脚既要和电阻连接,也要和芯片的A12脚连接起来。
然后焊接电源部分,USB接口只需焊接1、4、5和6脚,在电源电路中,将一个电阻和发光二极管串联,然后与四个电容并联,电路是否有电可以通过发光二极管是否发光得知。
最后焊接ISP接口,正面看板子,只有左上角和右下角会成为1脚,然后依次焊接,所以下载时下载线插上去时要注意,不能插反。
焊接过程中,要尽量让板子排版清晰,这样方便检查,导线排布好看,要尽量横平竖直,两个焊点之间不要搭在一起。
板子焊接完成后,我们将程序下进去,板子并没有亮,在多次检查后发现数码管的引脚焊接反了,我们将1的对脚焊成了7脚,应该是6脚的对脚。
下载程序时应先安装USB转串口驱动程序,安装时按照系统默认的路径进行安装。
板子改正后在调试就对了,显示29.8,并没有超过设定的温度30,所以蜂鸣器不会产生报警。
这次试验增加了我们动手动脑能力,让我们不只学会理论知识,要把这些用到现实生活中去。
同时也增加了我们的合作能力,我们都非常的努力,一有问题大家都坐在一起讨论,一起努力,一起攻克问题。
我想我们享受的就是这个过程,而不仅仅只是结果。
通过这次的设计,我知道了,在任何问题面前,只要我们努力,只要我们勇敢,我想,他们都不是问题,都不是困难。