资源描述
一、课题名称:基于DS18B20的温度计
二.内容摘要
随着社会的进步和工业技术的发展,人们越来越重视温度因素,许多产品对温度范围要求严格,而目前市场上普遍存在的温度检测仪器大都是单点测量,同时有温度信息传递不及时、精度不够的缺点,不利于工业控制者根据温度变化及时做出决定。在这样的形式下,开发一种能够同时测量多点,并且实时性高、精度高,能够综合处理多点温度信息的测量系统就很有必要。
本课题以AT89C51单片机系统为核心,能对多点的温度进行实时巡检。DS18B20是一种可组网的高精度数字式温度传感器,由于其具有单总线的独特优点,可以使用户轻松地组建起传感器网络,并可使多点温度测量电路变得简单、可靠。本文结合实际使用经验,介绍了DS18B20数字温度传感器在单片机下的硬件连接及软件编程,并给出了软件流程图。
三:方案设计
本系统主要由三个模块组成:控制模块、温度采集模块、显示模块
3.1 控制模块
本设计采用单片机基于数字温度传感器DS18B20的系统。单片机AT89C51具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用。温度传感器DS18B20利用单总线的特点可以方便的实现多点温度的测量,组建传感器网络,且系统的抗干扰性好、设计灵活、方便,而且能在恶劣的环境下进行现场温度检测。本系统可以应用在大型工业及民用常温多点监测场合。
3.2温度采集模块
这一部分主要完成对温度信号的采集和转换工作,由DS18B20数字温度传感器及其与单片机的接口部分组成。DS18B20智能温度温度传感器进行温度采集和转换输出数字型的温度值,然后通过数据引脚传到单片机的P3.7口,单片机接受温度并存储。DS18B20是美国DALLAS半导体公司最新推出的一种单线智能温度传感器,属于新一代适配微处理器的智能温度传感器,它可将温度信号直接转换为数字信号,实现了与单片机的直接接口,从而省去了信号调理和A/D转换等复杂模/数转换电路。DS18B20构成的温度采集模块电路简单、功能可靠、测量效率高,很好地弥补了传统温度测量方法的不足可广泛用于工业、民用、军事等领域的温度测量及控制仪器、测控系统和大型设备中。它具有集成度高、模拟输入数字输出、抗干扰能力强、体积小、接口方便、传输距离远测温误差小等特点。
图3.2.1:DS18B20 PR-35式封装
3.3温度显示模块
本课程设计的显示模块采用LCD1602液晶显示器显示温度数据,整数,一位小数进行显示,从P0口送数,P2口扫描。
3.4系统框图
系统的系统设计方框图如图1.1所示,它主要由三部分组成:①控制部分主芯片采用单片机AT89S51;②显示部分采用3位共阴极LED数码管以动态扫描方式实现温度显示;③温度采集部分的温度传感器采用DS18B20智能温度温度传感器。还有按键设置报警温度值和加热降温电路。
按键设置温度
加热继电器和风扇继电器
单 片 机
多路
DS18B20
传感器
LED显示
声光报警器
图3.4.1:多路温度检测与控制总体设计框图
四:单元电路设计、参数计算和器件选择
主要器件:
(1) STC89C58RD+单片机(DIP40)
(2) Lcd1602,1个
(3) 470欧9针排阻,1个
(4) 晶振:11.0592MHz,1个
(5) 瓷片电容:30PF,2个
(6) 10K电阻,1个
(7) DS18B20温度计1个,PR-35式封装
4.1DS18B20连接
图:4.1.1ds18b20 连接
4.2DS18B20功能命令简介及用法
4.2.1功能简介
(1) 智能温度传感器DS18B20的性能特点:
1) 独特的单总线接口仅需要一个端口引脚进行通信,可以是串行口也可以是其他I/O口,无须变换,直接输出被测温度值(9位二进制,含符号位)。 多个DS18B20可以并联挂接在一条总线上,实现实现多点温度采集检测功能;
2)可测温度范围为-55~+125℃,测量分辨率为0.0625℃;
3) 内含64位经过激光修正的只读存储器ROM;
4) 内含寄生电源,可直接通过数据总线供电,电压范围为3.0~5.5V;
5) 零待机功耗;
6)用户可通过编程分别设定各路的温度上、下限温度值来实现报警功能;
7) 适配各种微处理器;
8) 报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件;
9) 负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作;
10) 可检测距离远,最远测量距离为150m 。
(2) DS18B20的内部结构
DS18B20的内部结构如图3-1所示。 DS18B20内部结构主要由四部分组成:64位光刻ROM,温度报警触发器,温度传感器以及高速缓存器。
1) 64位光刻ROM。64位光刻ROM是出厂前已被刻好的,它可以看做是该DS18B0的地址序列号,不同的器件不一样,64位的地址序列号的构成如表2-1所示。开始8位是产品序列号代表产品的序列,接着48位产品序号代表同一系列产品的不同产品,最后8位是前56位的CRC校验码,所以不同的器件的地址序列号各不一样这也是多个DS18B20可以采用一线进行通信的原因(8位CRC编码的计算公式为CRC=X+X+X+1)。在64 b ROM的最高有效字节中存储有循环冗余校验码(CRC)。主机根据ROM的前56位来计算CRC值,并和存入DS18B20中的CRC值做比较,以判断主机收到的ROM数据是否正确。
表4.2.1 64位ROM地址序列号结构
8CRC编号
48位产品序号
8位CRC编码检验
图4.2.1 DS18B20内部结构
2) 非挥发的温度报警触发器(包括上限温度触发器TH和下限温度触发器TL)。可通过软件程序写入设定用户所要求的报警上下限温度值。
3) 高速暂存器。可以设置DS18B20温度转换的精度。DS18B20出厂时该位被设置为0,用户要去改动,R1和R0决定温度转换的精度位数,来设置分辨率,如图1.4。
DS18B20温度传感器的内部存储器还包括一个高速暂存RAM和一个非易失性的可电擦除的E2PRAM。高速暂存RAM的结构为8字节的存储器,
图4.2.2 DS18B20 暂存寄存器分布
4.2.2命令简介
根据 DS18B20 的通讯协议,主机(单片机)控制 DS18B20 完成温度转换必须经过三个步骤:每一次读
写之前都要对 DS18B20 进行复位操作,复位成功后发送一条 ROM 指令,最后发送 RAM 指令,这样才能
对 DS18B20 进行预定的操作。复位要求主 CPU 将数据线下拉 500 微秒,然后释放,当 DS18B20 收到信
号后等待 16~60 微秒左右,后发出 60~240 微秒的存在低脉冲,主 CPU 收到此信号表示复位成功。
图:4.2.3 ROM指令表
图:4.2.4 RAM指令表
4.2.3简单用法
(1)DS18B20的初始化
DS18B20的所有操作均从初始化开始,初始化的过程是首先由CPU发出一个复位脉冲,复位脉冲的时间为480~960us,然后由丛属器件发出应答脉冲。初始化是主CPU发出一个复位信号,将数据总线上的所有DS18B20复位,然后释放总线,该总线位接收状态。由于接有上拉电阻,在释放总线是有15 ~60us的时间间隙,在此之后的60~240us时间内,如果CPU检测到总线为低电平的话,则说明DS18B20初始化完成。
(2)发送ROM命令
ROM的操作命令位8位二进制数,CPU对ROM的操作有读ROM命令、符合ROM命令、搜索ROM命令、跳过ROM命令、报警搜索命令共5种。其中符合ROM命令是用来识别连在总线是的DS18B20芯片,其过程是主CPU发出符合ROM命令(代码位55H)后,接着送出64位的ROM数据序列,从而使主CPU实现对单总线上的特定DS18B20进行寻址,只有与64位序列严格相符的DS18B20才能对后续的操作发出响应,符合ROM命令只对同时挂在总线上的多片DS18B20适用。
(1) 发送RAM命令
RAM命令是暂存器操作命令,共有6条,在前面已经列出,其功能是实现温度的转换、读/写、复制暂存器的内容等功能。
在具体的设计过程中,访问DS18B20也是通过程序设计来实现的。具体程序可以按照上面的工作时序图和命令的相应格式进行程序设计。
另外,由于DS18B20单线通信功能是分时完成的,他有严格的时隙概念,因此读写时序很重要。系统对DS18B20的各种操作必须按协议进行。操作协议为:初始化DS18B20(发复位脉冲)→发ROM功能命令→发存储器操作命令→处理数据。
(2) 测温流程
初始化
DS18B20
跳过ROM
匹配
温度变换
延时1S
跳过ROM
匹配
读暂存器
转换成显示码
数码管显示
图4.2.5 DS18B20测温流程
4.3 LCD1602的用法
4.31 LCD1602的特性
n +5V电压,对比度可调
n 内含复位电路
n 提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能
n 有80字节显示数据存储器DDRAM
n 内建有160个5X7点阵的字型的字符发生器CGROM
n 8个可由用户自定义的5X7的字符发生器CGRAM
4.32 LCD1602接口说明
4.33 LCD1602字符码
4.34 LCD1602 基本操作时序(11条指令)
读状态 输入:RS=L,RW=H,E=H
输出:DB0~DB7=状态字
写指令 输入:RS=L,RW=L,E=下降沿脉冲,DB0~DB7=指令码
输出:无
读数据 输入:RS=H,RW=H,E=H
输出: DB0~DB7=数据
写数据 输入:RS=H,RW=L,E=下降沿脉冲,DB0~DB7=数据
输出:无
4.35 LCD1602自定义字符(最多8个 存放于CGRAM)
我们从CGROM表上可以看到,在表的最左边是一列可以允许用户自定义的CGRAM,从上往下看着是16个,实际只有8个字节可用。它的字符码是 00000000-00000111这8个地址,表的下面还有8个字节,但因为这个CGRAM的字符码规定0-2位为地址,3位无效,4-7全为零。因此 CGRAM的字符码只有最后三位能用也就是8个字节了。等效为0000X111,X为无效位,最后三位为000-111共8个。 如果我们要想显示这8个用户自定义的字符,操作方法和显示CGROM的一样,先设置DDRAM位置,再向DDRAM写入字符码,例如“A”就是41H。现 在我们要显示CGRAM的第一个自定义字符,就向DDRAM写入00000000B(00H),如果要显示第8个就写入00000111(08H)
五:利用Proteus软件对电路进行仿真调试
六:程序流程图
开始
首先程序开始,将液晶显示器进行初始化。完毕后像lcd中写入一个自定义字符“°”,用于显示 ℃,如上图所示。调用程序显示静态不需要改变的文字。之后获取温度数据转化并送显示。
Lcd液晶初始化
接↓下页
写入自定义字符
接↑上页
静态文字显示
获取并转换温度数据
送液晶显示
图6.1 主程序流程图
开始
开始
Ds18b20初始化
设定第一行显示位置
向ds18b20琢个字节写入0xcc,实现跳过rom的功能
显示第一行
设定第二行显示位置
向ds18b20琢个字节写入0x44,下达温度转换命令
显示定义字符
显示字母C构成℃
结束
结束
图6.2 静态显示流程图 图6.3 ds18b20获取温度流程图
-----------------------------------------------------------------------
获取ds18b20的温度数据,并合成为一个12位的2进制数,然后通过精度转换为一个10进制数。通过判断其大小 判断数的正负值,若为负进行取反加1转换为正数,之后分别送显。
开始
Ds18b20复位
调用子程序read_bit,读取1位数据
调用子程序read_tempt,读取暂存器高8位
读ds18b20暂存器
跳过ds18b20rom
调用8次
返回8次
调用子程序read_bit,读取1位数据
调用子程序read_tempt,读取暂存器低8位
调用8次
返回8次
将高8为和低8位合成温度数据
转换为浮点型十进制
乘10转换为整型s_temp,使之保留1位小数
对源2进制u_temp,取反加1,然后乘10转换为整型s_temp,使之保留1位小数
判断s_temp是否小于1260?
N
Y 图6.4温度转换流程图
送到负数显示程序
结束
送到正数显示程序
将送显过来的数据接收到后,先进去取位操作,将数进行分离,然后判断数据大小,根据大小选择显示,实现友好的显示界面。
开始
开始
将数据进行分离取位
将数据进行分离取位
设定开始显示的
位置
设定开始显示的
位置
100<=date<1000?
0<date<100?
Date>=1000?
100<=date<1000?
0<=date<100?
0<=date<100
100<=date<10000
0<=date<100
100<=date<10000
Date>=1000
分别显示空格,负号,个位,小数点,小数位
分别显示负号,十位,个位,小数点,小数位
分别显示空格,空格,个位,小数点,小数位
分别显示空格,十位,个位,小数点,小数位
分别显示百位,十位,个位,小数点,小数位
结束
结束
图6.5 正数显示流程图 图6.6负数显示流程图
七:实验源程序
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code disp[]="0123456789- ";
uchar code disp2[]="Tempreture";
/* 自定义文字是8*8点阵构成的 但是前3位是无效的,如10100111
有效位是后面5位,前3位是1和0没区别,最好为0*/
uchar user[]={0x07,0x05,0x07,0x00,0x00,0x00,0x00,0x00}; //自定义”°“
sbit lcden=P2^0;
sbit lcdrw=P2^1;
sbit lcdrs=P2^2;
sbit tempt=P2^3; //数据总线
uint u_temp,s_temp; //定义无符号整型形参
float f_temp; //定义浮点型形参
void delay(uint x) //延时500ms程序
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<130;j++);
}
/* rs=0 输入指令 rs=1 输入数据*/
/* r/w=0 向lcd写入指令或数据 r/w=1 从lcd 读取信息*/
/* en=1时候 读取信息 1→0(下降沿)执行命令*/
void write_com(uchar com) //液晶写命令
{
lcdrs=0;
lcdrw=0;
P0=com;
delay(2);
lcden=1;
delay(2);
lcden=0;
}
void write_data(uchar date) //液晶写数据
{
lcdrs=1;
lcdrw=0;
P0=date;
delay(2);
lcden=1;
delay(2);
lcden=0;
}
void lcd_init() //液晶初始化
{
lcden=0;
lcdrw=0;
write_com(0x38); //初始化液晶第一行
write_com(0x0c); //开显示 不显示光标 不闪烁
write_com(0x06); //每次写入数据后 地址加1
write_com(0x01); //清屏
}
void display_tempt(uint date) //温度数据显示
{
uchar i,j,k,m;
m=date/1000; // 百位
i=(date%1000)/100; //十位
j=(date%100)/10; //个位
k=date%10; //小数位
write_com(0x80+0x40+5); //从液晶显示屏第二行的第5位开始显示
if(date>=1000)
{write_data(disp[m]);
write_data(disp[i]);
write_data(disp[j]);
write_data('.');
write_data(disp[k]);}
else if(date>=100&&date<1000)
{ write_data(disp[11]);
write_data(disp[i]);
write_data(disp[j]);
write_data('.');
write_data(disp[k]);
}
else if(date>=0&&date<100)
{ write_data(disp[11]);
write_data(disp[11]);
write_data(disp[j]);
write_data('.');
write_data(disp[k]);
}
}
void display_ftemp(uint date) // 显示负数温度
{
uchar i,j,k;
i=date/100; //十位
j=date%100/10; //个位
k=date%100%10; //小数位
write_com(0x80+0x40+5); //从液晶显示屏第二行的第4位开始显示
if(date>=100&&date<600)
{
write_data(disp[10]); //显示负号
write_data(disp[i]);
write_data(disp[j]);
write_data('.');
write_data(disp[k]);
}
else if(date>0&&date<100)
{
write_data(disp[11]);
write_data(disp[10]);
write_data(disp[j]);
write_data('.');
write_data(disp[k]);
}
}
void reset_tempt() //DS18B20复位,初始化
{
uint i;
tempt=0; //先将数据总线拉到低电平
i=90;
while(i>0)i--; //延时480到960微妙
tempt=1; //数据线拉到高电平
i=4; //延时
while(i>0)i--;
}
bit read_bit() //读一位DS18B20数据
{
uint i;
bit dat;
tempt=0;
i++; //延时
tempt=1;
i++; //延时
i++;
dat=tempt;
i=8; //延时
while(i>0)i--;
return dat;
}
uchar read_tempt() //读一个字节DS18B20数据
{
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) //写一个字节数据到DS18B20
{
uint i;
uchar j;
bit testbit;
for(j=1;j<=8;j++)
{
testbit=dat&0x01; //每次只写一位数据
dat=dat>>1;
if(testbit)
{
tempt=0;
i++; //延时
tempt=1;
i=8; //延时
while(i>0)i--;
}
else
{
tempt=0;
i=8; //延时
while(i>0)i--;
tempt=1;
i++; //延时
i++;
}
}
}
void convert_tempt() //DS18B20开始获取温度并进行转换
{
reset_tempt();
delay(1);
write_byte(0xcc); //跳过64位rom地址 直接向ds18b20下达温度转换命令
write_byte(0x44); //启动18b20进行温度转换
}
uint get_tempt() //读取DS18B20寄存器中的温度数据
{
uchar a,b;
reset_tempt(); //复位
delay(1);
write_byte(0xcc);
write_byte(0xbe); //读内部ram中9字节的内容
a=read_tempt(); //读取温度低8位
b=read_tempt(); //读取温度高8位
u_temp=b;
u_temp<<=8;
u_temp=u_temp|a;
f_temp=u_temp*0.0625; //精度为12位,所以分辨率为0.0625
s_temp=f_temp*10 ; //乘以10,将实际温度扩大10倍
if(s_temp<1260)
display_tempt(s_temp);
if(s_temp>1260)
{
u_temp=~u_temp+1;
f_temp=u_temp*0.0625;
s_temp=f_temp*10;
display_ftemp(s_temp);
}
}
void display() //静态文字显示
{
uchar i;
write_com(0x80+0x03); //0x80+3(0x80+0x03)表示从液晶显示屏第一行的第四位开始显示
for(i=0;i<10;i++)
{
write_data(disp2[i]);
}
write_com(0x80+0x40+10); //从液晶显示屏第二行的第11位开始显示
write_data(0x00);
write_data('C');
}
void main() //主函数
{
uchar i;
lcd_init();
write_com(0x40);
for(i=0;i<8;i++)
{
delay(1);
write_data(user[i]);
}
display();
while(1)
{
convert_tempt();
get_tempt();
}
}
八:参考文献及资料
【1】肖洪兵. 跟我学用单片机. 北京:北京航空航天大学出版社,2002.8
【2】 何立民. 单片机高级教程. 第1版.北京:北京航空航天大学出版社,2001
【3】赵晓安. MCS-51单片机原理及应用. 天津:天津大学出版社,2001.3
【4】李广第. 单片机基础. 第1版.北京:北京航空航天大学出版社,1999
【5】徐惠民、安德宁. 单片微型计算机原理接口与应用. 第1版. 北京:北京邮电大学出版社,1996
6】何立民.从Cygnal 80C51F看8位单片机发展之路. 单片机与嵌入式系统应用,2002年,第5期:P5~8
7】 夏继强. 单片机实验与实践教程. 北京:北京航空航天大学出版社, 2001
【8】 智能温度传感器.ppt
【9】ds18b20 中文全套资料
【10】lcd1602 液晶显示中文资料
九:心得体会
本设计使用的温度控制器结构简单、测温准确,具有一定的实际应用价值。该智能温度控制器只是DS18B20在温度控制领域的一个简单实例,还有许多需要完善的地方,例如可以将测得的温度通过单片机与通讯模块相连接,以手机短消息的方式发送给用户,使用户能够随时对温度进行监控。此外,还能广泛地应用于其他一些工业生产领域,如建筑,仓储等行业。本温度控制系统可以应用于多种场合,像花房的多点温度、育婴房的温度、水温的检测与控制。用户可灵活选择本设计的用途,有很强的实用价值。
由衷感谢我们的老师,教予了我诸多传感器的理论知识。指导了我顺利的独立地完成了这一次的课程设计。期间,让我学到了许多在实践中需注意的问题。怎样思考问题,然后如何去收集整理资料。
源程序:
展开阅读全文