基于DS18B20的温度传感器设计报告Word格式文档下载.docx
《基于DS18B20的温度传感器设计报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《基于DS18B20的温度传感器设计报告Word格式文档下载.docx(20页珍藏版)》请在冰豆网上搜索。
该模块由AT89C52单片机组成在设计方面,AT89C52的EA接高电平,其外围电路提供能使之工作的晶振脉冲、复位按键,四个I/O分别接8路的单列IP座方便与外围设备连接。
当AT89C52芯片接到来自温度传感器的信号时,其内部程序将根据信号的类型进行处理,并且将处理的结果送到显示模块,发送控制信号控制各模块。
b、温度传感器模块
DS18B20相关资料
1、DS18B20原理与分析DS18B20是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。
与传统的热敏电阻相比,它能够直接读出被测温度并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
可以分别在93.75ms和750ms内完成9位和12位的数字量,并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,温度变换功率来源于数据总线,总线本身也可以向所挂接的DS18B20供电,而无需额外电源。
因而使用DS18B20可使系统结构更趋简单,可靠性更高。
他在测温精度、转换时间、传输距离、分辨率等方面较DS1820有了很大的改进,给用户带来了更方便的使用和更令人满意的效果。
以下是DS18B20的特点:
(1)独特的单线接口方式:
DS18B20与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
(2)在使用中不需要任何外围元件。
(3)可用数据线供电,电压范围:
+3.0~+5.5V。
(4)测温范围:
-55-+125℃。
固有测温分辨率为0.5℃。
(5)通过编程可实现9-12位的数字读数方式。
(6)用户可自设定非易失性的报警上下限值。
(7)支持多点组网功能,多个DS18B20可以并联在惟一的三线上,实现多点测温。
(8)负压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。
2、DS18B20的测温原理DS18B20的测温原理上图所示,图中低温度系数晶振的振荡频率受温度的影响很小,用于产生固定频率的脉冲信号送给减法计数器1,高温度系数晶振随温度变化其震荡频率明显改变,所产生的信号作为减法计数器2的脉冲输入,图中还隐含着计数门,当计数门打开时,DS18B20就对低温度系数振荡器产生的时钟脉冲后进行计数,进而完成温度测量。
计数门的开启时间由高温度系数振荡器来决定,每次测量前,首先将-55℃所对应的基数分别置入减法计数器1和温度寄存器中,减法计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
减法计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时温度寄存器的值将加1,减法计数器1的预置将重新被装入,减法计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到减法计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
图中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正减法计数器的预置值,只要计数门仍未关闭就重复上述过程,直至温度寄存器值达到被测温度值,这就是DS18B20的测温原理。
另外,由于DS18B20单线通信功能是分时完成的,他有严格的时隙概念,因此读写时序很重要。
系统对DS18B20的各种操作必须按协议进行。
操作协议为:
初始化DS18B20(发复位脉冲)→发ROM功能命令→发存储器操作命令→处理数据。
DS18B20工作过程一般遵循以下协议:
初始化——ROM操作命令——存储器操作命令——处理数据①初始化单总线上的所有处理均从初始化序列开始。
初始化序列包括总线主机发出一复位脉冲,接着由从属器件送出存在脉冲。
存在脉冲让总线控制器知道DS1820在总线上且已准备好操作。
②ROM操作命令一旦总线主机检测到从属器件的存在,它便可以发出器件ROM操作命令之一。
所有ROM操作命令均为8位长。
③存储器操作命令
④处理数据
DS18B20的高速暂存存储器由9个字节组成,其分配如图3所示。
当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。
单片机可通过单线接口读到该数据,读取时低位在前,高位在后。
DS18B20温度数据表
上表是DS18B20温度采集转化后得到的12位数据,存储在DS18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于或等于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;
如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。
温度转换计算方法举例:
例如当DS18B20采集到+125℃的实际温度后,输出为07D0H,则:
实际温度=07D0H╳0.0625=2000╳0.0625=1250C。
例如当DS18B20采集到-55℃的实际温度后,输出为FC90H,则应先将11位数据位取反加1得370H(符号位不变,也不作为计算),则:
实际温度=370H╳0.0625=880╳0.0625=550C。
2、显示模块LCD1602资料(这里主要介绍下指令说明及时序)
1602液晶模块内部的控制器共有11条控制指令,如表10-14所示:
序号
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清显示
2
光标返回
*
3
置输入模式
I/D
S
4
显示开/关控制
D
C
B
5
光标或字符移位
S/C
R/L
6
置功能
DL
N
F
7
置字符发生存贮器地址
字符发生存贮器地址
8
置数据存贮器地址
显示数据存贮器地址
9
读忙标志或地址
BF
计数器地址
10
写数到CGRAM或DDRAM)
要写的数据内容
11
从CGRAM或DDRAM读数
读出的数据内容
表10-14:
控制命令表
1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
(说明:
1为高电平、0为低电平)
指令1:
清显示,指令码01H,光标复位到地址00H位置。
指令2:
光标复位,光标返回到地址00H。
指令3:
光标和显示模式设置I/D:
光标移动方向,高电平右移,低电平左移S:
屏幕上所有文字是否左移或者右移。
高电平表示有效,低电平则无效。
指令4:
显示开关控制。
D:
控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:
控制光标的开与关,高电平表示有光标,低电平表示无光标B:
控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:
光标或显示移位S/C:
高电平时移动显示的文字,低电平时移动光标。
指令6:
功能设置命令DL:
高电平时为4位总线,低电平时为8位总线N:
低电平时为单行显示,高电平时双行显示F:
低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:
字符发生器RAM地址设置。
指令8:
DDRAM地址设置。
指令9:
读忙信号和光标地址BF:
为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:
写数据。
指令11:
读数据。
与HD44780相兼容的芯片时序表如下:
读状态
输入
RS=L,R/W=H,E=H
输出
D0—D7=状态字
写指令
RS=L,R/W=L,D0—D7=指令码,E=高脉冲
无
读数据
RS=H,R/W=H,E=H
D0—D7=数据
写数据
RS=H,R/W=L,D0—D7=数据,E=高脉冲
表10-15:
基本操作时序表
读写操作时序如图10-55和10-56所示:
图10-55读操作时序
图10-56写操作时序
四、软件设计
系统程序主要包括主程序、读出温度子程序、温度转换子程序、计算温度子程序、显示等等。
1、主程序
主要功能是完成DS18B20的初始化工作,并进行读温度,将温度转化成为压缩BCD码并在显示器上显示传感器所测得的实际温度。
2、读出温度子程序
读出温度子程序的主要功能是读出RAM中的9字节,在读出时需要进行CRC校验,校验有错时不进行温度数据的改写。
其程序流程图如下图所示。
3、温度转换命令子程序
温度转换命令子程序主要是发温度转换开始命令,当采用12位分辩率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。
流程图图如下
4、计算温度子程序
计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定。
流程图如下:
五、完整程序如下:
#include<
reg52.h>
intrins.h>
typedefunsignedcharuint8;
#defineuintunsignedint
#defineucharunsignedchar
sbitDQ=P3^3;
//定义DQ引脚为P3.3
ucharcodeBw[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
//百位编码
ucharcodeXsw[16]={0x30,0x31,0x31,0x32,0x33,0x33,0x34,0x34,0x35,0x36,0x36,0x37,0x38,0x38,0x39,0x39};
//小数位编码
sbitRS=P2^0;
sbitRW=P2^1;
sbitEN=P2^2;
sbitBUSY=P0^7;
ucharwendu;
uchartemp_g,temp_d;
unsignedcharcodeword1[]={"
Temperature:
"
};
voiddelay(uintxms)
{uinti,j;
for(i=xms;
i>
0;
--i)
for(j=110;
j>
--j);
}
voidDelayus(intt)//在11.059MHz晶振下调用本函数要24μs,每次计数需16μs
{ints;
for(s=0;
s<
t;
s++);
}
等待繁忙标志
voidwait(void)
{P0=0xFF;
do
{RS=0;
RW=1;
EN=0;
EN=1;
}while(BUSY==1);
EN=0;
写数据
voidw_dat(uint8dat)
{wait();
P0=dat;
RS=1;
RW=0;
写命令
voidw_cmd(uint8cmd)
P0=cmd;
RS=0;
发送字符串到LCD
voidw_string(uint8addr_start,uint8*p)
{w_cmd(addr_start);
while(*p!
='
\0'
)
{w_dat(*p++);
}
}
初始化1602
voidInit_LCD1602(void)
{w_cmd(0x38);
//16*2显示,5*7点阵,8位数据接口
w_cmd(0x0c);
//显示器开、光标开、光标允许闪烁
w_cmd(0x06);
//文字不动,光标自动右移
w_cmd(0x01);
//清屏
ucharReset()//完成单总线的复位操作。
{uchard;
DQ=0;
//将DQ线拉低
Delayus(29);
//保持480μs复位时间延时时间(480-24)/16=28.5,取29μs。
DQ=1;
//DQ返回高电平
Delayus(3);
//等待脉冲过70μs之后检测存在脉冲,因此延时时间为(70-24)/16=2.875,取3μs。
d=DQ;
//获得存在信号
Delayus(25);
//等待时间隙结束
return(d);
//返回存在信号,0=器件存在,1=无器件
voidwrite_bit(ucharbitval)//向单总线写入1位值:
bitval
{DQ=0;
//将DQ拉低开始写时间隙
if(bitval==1)
DQ=1;
//如果写1,DQ返回高电平
Delayus(5);
//在时间隙内保持电平值,
//Delayus函数每次循环延时16μs因此Delayus(5)=5*16+24=104μs
}
voidds18write_byte(charval)//向单总线写入一个字节值:
val
{uchari;
uchartemp;
for(i=0;
i<
8;
i++)//写入字节,每次写入一位
{temp=val>
>
i;
temp&
=0x01;
write_bit(temp);
Delayus(5);
ucharread_bit()//从单总线上读取一位信号,需延时时间15μs,无法调用前面定义
{//的Delayus()函数,而采用一个for()循环来实现延时。
uchari;
DQ=0;
//将DQ拉低开始读时间隙
DQ=1;
//然后返回高电平
for(i=0;
3;
i++);
//延时15μs
return(DQ);
//返回DQ线上的电平值
uchards18read_byte()//从单总线读取一个字节的值
{
uchari;
ucharvalue=0;
i<
i++)
{//读取字节,每次读取一个字节
if(read_bit())
value|=0x01<
<
//然后将其左移
Delayus(6);
return(value);
intReadtemperature()//如果单总线节点上只有一个器件则可以直接掉用本函数。
如果节点上有多个器
{//件,为了避免数据冲突,应使用MatchROM函数来选中特定器件。
uchartemp_d,temp_g,k,get[2],temp;
Reset();
ds18write_byte(0xcc);
//跳过ROM
ds18write_byte(0x44);
//启动温度转换
ds18write_byte(0xbe);
//读暂存器
for(k=0;
k<
2;
k++)
{
get[k]=ds18read_byte();
temp_d=get[0];
//低位
temp_g=get[1];
//高位
if((temp_g&
0xf0)==0xf0)//正负号判断
temp_d=~temp_d;
if(temp_d==0xff)//保证-48(1111110100000000)、-32和-16显示正常
temp_d=temp_d+0x01;
//00000000
temp_g=~temp_g;
//00000010
temp_g=temp_g+0x01;
//00000011
else
temp_d=temp_d+0x01;
}
w_cmd(0xc5);
w_dat(Xsw[temp_d&
0x0f]);
//查表得小数位的值
temp=((temp_d&
0xf0)>
4)|((temp_g&
0x0f)<
4);
w_cmd(0xc1);
w_dat(0x2d);
//负号
else//正数
w_dat(Bw[temp/100]);
returntemp;
main()
Init_LCD1602();
w_string(0x80,word1);
while
(1)
wendu=Readtemperature();
temp_g=wendu%100/10+'
0'
;
//这里要特别注意啊少了%100就差很多
temp_d=wendu%10+'
w_cmd(0xc2);
delay
(2);
w_dat(temp_g);
w_dat(temp_d);
w_cmd(0xc4);
w_dat(0x2e);
//小数点
w_cmd(0xc6);
w_dat(0xdf);
//温度符号
w_dat(0x43);
六、设计体会
通过这次基于DS18B20传感器测量温度的设计,我学会了把课堂上学习的知识运用到实物中来,很好的锻炼了我的动手能力,同时也考验了自己的耐心和仔细的能力。
首先,这次设计让我把书本上学到的理论知识转化成为现实生活中有价值的实物。
如果没有这次设计为我搭建的平台,我就不能对书本上的知识进行很好的理解,也不能熟练的把它们应用到现实生活中。
还有,我们学会不能手高眼低,要踏踏实实,从基础学起、做起。
但是,具体到设计时,我遇到了很多麻烦,比如如何将传感器得到的温度转换成为对应的电信号,如何将电信号输送到单片机进行控制,如何把测得的温度用数字显示出来等等。
这就要求我们学习要一步一个脚印,掌握扎实的理论基础了。
最重要的一点是,我在这次设计中培养了自己的学习能力。
由于好多知识超出了我们的课本范围,这就要求我们自己通过资料来增加我们的知识,解决遇到的一些问题。
在短时间内从书本资料中筛选出我们所需要的知识,对我们的自主学习能力有很大的帮助。
就拿DS18B20来说,我们书本上没有介绍到这种温度传感器,所以我们就通过学习DS18B20的说明书,了解它工作的原理以及特性,清楚在实际应用时要注意的事项,对DS18B20进行初始化、编程的要求和规定等。
培养了自主学习的能力,无论以后我要做什么样的设计,我都能够通过查阅资料来实现。
在焊接的过程中由于引脚的接线慌忙,造成了第一次完成焊接后显示屏没有亮,检查了一遍后发现引脚的高低电平接反了,于是重新接了那两根线,最后,液晶显示屏