基于18b20多点温度检测

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

浙江海洋学院
设计题目基于18b20多点温度检测
年级专业摘要
本文介绍了基于DS18B20和STC89C52RC的多点温度测量的方法和原理,利用DSI8B20单总线温度传感器和单片机与其它外围设备结合在一起实现温度的测量和显示。

该设计主要分为以下三大部分:硬件设计、软件设计和整个系统的调试与实现。

其中硬件设计主要是由Protel99SE软件进行电路的设计和PCB 板的绘制;软件设计采用C语言编写实现。

采用该解决方案,实现了基于DS18B20进行的各项软硬件的设计、调试和处理,实现了多点温度测量和显示。

关键词:温度测量;硬件;软件;温度传感器DS18B20
目录
1. 引言 (5)
2. 方案设计 (5)
3. 硬件设计 (6)
3.1.单片机最小系统 (6)
3.2.温度传感器电路 (7)
3.3.LCD显示电路 (7)
4. 软件设计 (12)
4.1.软件流程 (12)
4.2.子程序模块 (13)
5. 实验结果与讨论 (15)
5.1.实验仿真 (15)
5.2.结果讨论 (15)
6. 心得体会 (16)
7. 附录;源程序 (17)
8. 参考文献 (25)
基于18b20多点温度检测
1.引言
随着计算机与信息技术的发展,计算机测量控制系统在越来越多的场合得到了广泛应用。

温度是许多监控系统中的一个重要参数。

对于需要实时多点温度测量的场合,计算机测控系统更为重要。

多点温度远程监测在实际生产中具有重要的应用价值。

其中测温点由数字温度传感器DSl8B20构成,DS18B20直接把温度信息转换成相应的数字信号。

数据采集、处理模块主要由AT89C2051单片机构成,完成温度数据的读取和传输。

因此,基于DS18B20的多点温度测量的方法和原理,利用DSI8B20单总线温度传感器和单片机与其它外围设备结合在一起实现温度
的测量和显示。

2.方案设计
以单片机接口原理,DS18B20芯片功能与接口设计,LCD1602液晶屏接口设计等理论知识为基础,设计出完整的系统原理图。

根据原理图,将硬件系统资源焊接成PCB板。

根据系统功能,设计编写固件程序,下载后进行调试,通过DS18B20及LCD1602正常工作实现系统的多点温度测量。

本课题涉及的理论知识主要是DS18B20多点温度测量原理及LCD1602显示原理,重点在于硬件设计,难点在于编程和整机的调试。

经过论证,在实现设计要求的前提下,控制器选取STC89C52RC;而且这款单片机支持在线编程,通过串口下载程序,这给程序的下载和使用带来方便。

电路设计采用Protel99SE,程序设计采用C语言进行编程,用Proteus软件进行仿真。

系统的组成框图如下图所示。

它主要由三部分组成:
3.硬件设计
3.1单片机驱动电路设计
单片机能正常工作,必须要有它的驱动电路,即单片机最小系统。

单片机最小系统主要包括其供电系统,时钟电路和复位电路。

本系统单片机的复位电路采用手动复位。

对本设计的单片机驱动电路说明如下:
1、单片机的供电系统采用USB接口供电电路;
2、单片机采用外接晶振的方法,晶振频率为11.0592MHz;
3、复位电路采用按键复位。

3.2温度显示模块电路设计
根据LCD1602的引脚接口说明与单片机连接,设计本系统的显示模块接口电路设计如图3.2所示,电路图的详细说明如下:
液晶显示屏LCD1602的第1脚及第16脚接地;
液晶显示屏LCD1602的第2脚接电源;
液晶显示屏LCD1602的第3脚串联一个10kΩ的可调电阻器接地;
液晶显示屏LCD1602的第4、5、6脚分别接单片机的P3.5、P3.6及P3.4口液晶显示屏LCD1602的第7~14脚分别接单片机的P1.0~P1.7口;
液晶显示屏LCD1602的第15脚串联一个10kΩ的电阻接地。

3.3温度测量模块电路设计
DS18B20引脚和实物如图3.3.1所示。

图3.3.1 DS18B20的管脚排列和实物
DALLAS半导体公司的单线数字温度传感器DS18B20是一种新型的“一线器件”,其体积小、适用于多种场合。

其温度测量范围为-55~+125 °C,可编程为9位~12 位转换精度,测温分辨率可达0.0625°C。

被测温度用符号扩展的16位数字量方式串行输出。

而且多个DS18B20可以串联到一条数据线上,单片机只需一根端口线就能与诸多DS18B20 通信,提高了I/O口的利用率,可节省大量的引线和逻辑电路。

3.2.1DS18B20特性
(1)适应电压范围宽:3.0 V~5.5V,在寄生电源方式下可由数据线供电。

(2)独特的单线接口方式,在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。

(3)DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成
在形如一只三极管的集成电路内。

(4)测温范围-55℃~+125℃,在-10℃~+85℃时精度为±0.5℃。

(5)可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温。

(6)在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字。

(7)测量结果直接输出数字温度信号,以“一线总线”串行传送给CPU,同时可传送CRC校验码,具有很强的抗干扰纠错能力。

(8)负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。

3.2.2 DS18B20内部结构
(1)DS18B20的内部结构如图3.2.2所示。

图3.2.2 DS18B20内部结构图
配置寄存器与分辨率关系表
R0 R1 温度计分辨率/bit 最大转换时间/us
0 0 9 93.75
0 1 10 187.5
1 0 11 375
1 1 1
2 750
(2)高速暂存存储器
高速暂存存储器由9个字节组成。

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

单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式如图3-8所示。

对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变为原码,再计算十进制值。

DS18B20温度数据和典型对应的温度值如下表所示:
DS18B20 温度数据表:
23 22 21 20 2-1 2-2 2-3 2-4
MSB LSB S S S S S 26 25 24
典型对应的温度值:
温度/℃二进制表示十六进制表示
+125 +25.0625 +10.125 +0.5
-0.5 -10.125 -25.0625
-55 00000111 11010000
00000001 10010001
00000000 10100010
00000000 00001000
00000000 00000000
11111111 11111000
11111111 01011110
11111110 01101111
11111100 10010000
07D0H
0191H
00A2H
0008H
0000H
FFF8H
FF5EH
FE6FH
FC90H
通过资料可知。

温度传感器DS18B20内部均有一个独立的64位序列号,单片机通过序列号可以对一条总线上的多支DS18B20进行控制,读取它们的温度。

但要完成这个操作,软件设计比较复杂,同时存在一个缺点就是速度太慢。

无法适用于一些实时性要求高的测温场合。

所以本设计采取一种利用单片机的并口,同步快速读取4支DS18B20的方法。

本系统的温度测量模块电路设计如图所示。

四支温度传感器DS18B20的第1脚接地;
四支温度传感器DS18B20的第2脚分别串联一个10kΩ的电阻;
四支温度传感器DS18B20的第2脚均接单片机的P3.4口;
四支温度传感器DS18B20的第2脚及第3脚接电源。

4.软件设计
4.1系统软件程序设计
开始
调用初始化子程序
设置跳过ROM命令CCH
调用写命令子程序
设置启动温度转换令44H
调用写命令子程序
延时
调用初始化子程序
Y
N 调温度数据处理子程序
读取温度数据
是否超出温度
设定值?
调用报警信号子程序
调LCD显示子程序
图4.1 系统主程序执行流程图
主程序执行流程如图4.1所示,主程序先对各DS18B2O及LCD1602进行初始化,然后重复调用DS18B20的写命令和读数据模块,最后将数据处理后送LCD1602显示
4.2系统软件程序调试
4.2.1 LCD1602的显示程序调试
LCD1602的介绍:LCD1602是工业字符型液晶,能够同时显示16x02即32个字符。

1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。

它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形。

1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块。

用户所编的显示程序,开始必须进行初始化,否则模块无法正常显示,LCD1602的常用初始化方法是利用内部复位电路进行初始化。

下面指令是在初始化进程中执行的。

(1)清屏(DISPLAY CLEAR);
(2)功能设置(FUNCTION SET)
DL=1:8Bin 接口数据
N=0:1 行显示;F=0:5×7dot 字形;
(3)显示开/关控制(Display ON/OFF Conrtol)
D=0:显示关;C=0:光标关;B=0:消隐关
(4)输入方式设置(ENTRY MODE SET)
I/D=1:(增量);S=0:无移位。

4.2.2 DS18B20的测量温度程序调试
DS18B20介绍:DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。

主要根据应用场合的不同而改变其外观。

封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。

耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

根据前面DS18B20的接口电路、工作原理及工作时序的介绍,编写DS18B20的温度测量程序。

DS18B20内部均有一个独立的64位序列号,单片机通过序列号可以对一条总线上的多支DS18B20进行控制,读取它们的温度,读取其序列号的程序如上。

但考虑到DS18B20初始化程序、读和写数据程序需要更改更多指令,大大降低系统测量温度的速度。

无法适用于一些实时性要求高的测温场合。

所以本设计采取一种利用单片机的并口,同步快速读取数支DS18B20的方法。

4.3多点温度测量系统总程序调试
一、根据前面的主程序流程图,本设计的主函数程序设计如下:
void main() //主函数
{
do
{
tmpchange1(); //温度传感器1的温度转换函数
tmpchange2(); //温度传感器2的温度转换函数
display(tmp1(),tmp2());//调用温度显示函数
deal(temp1,temp2); //进行温度处理
}
while(1);
}
主函数是通过调用之前编写的温度测量主程序和温度显示主程序实现的,最后加do while循环,就能让系统保持工作状态,当温度升高或降低时,就能及时把温度显示出来。

二、多点温度测量的程序调试:
为实现多点温度测量的功能,本设计采用DS18B20与单片机并口连接方式,两支DS18B20温度传感器的温度测量及显示程序参考附录A源程序。

4.4小结
本章主要讨论了系统的软件部分,包括主程序执行流程,LCD1602显示程序,DS18B20测量温度程序的调试。

最后通过硬件电路进行实际的控制,经过调试得出结果表明,单片机能独立控制元件工作,DS18B20能也实现多点温度的测量的正常运作。

5.实验结果与讨论
5.1实验仿真
图5-1 实验仿真结果
5.2结果讨论
本设计以AT89C52单片机为系统的控制核心,采用proteus仿真软件进行测试。

Proteus是一款比较常用的单片机仿真软件,用proteus和keil配合进行仿真提高系统运行效率与稳定性。

由于采用了动态扫描的方式实现对点阵式LED电子显示屏的控制,使系统能够稳定、清晰地显示文字。

该设计可以被广泛的应用于例如大棚温度控制等多方面,使得设计能运用到社会生活中来。

6.心得体会
本课题将多个DS18B20和STC89C52RC单片机相结合实现了多点温度测量。

对于单片机的独立控制外设而言,在技术上难度不大,所以,本文没有重点介绍,然而,多点温度测量技术,本文结合接口芯片DS18B20用很大的篇幅进行介绍
固件编程直接使用单片机的C语言,在速度上相对于单片机的汇编语言而
言比较慢,但是具有很好的可读性。

在多点温度测量应用范围越来越宽的今天,只有掌握了固件程序的编写,才可能开发出一个好多点温度测量系统。

在多个DS18B20与单片机的通信中,通过I/O并口传输,能快速测量多点温度,并循环显示到LCD上。

从结果来看,依据DS18B20单总线协议和单片机的应用知识,本次实验成功地实现了基于DS18B20的多点温度测量系统的功能,并开发了其温度差显示功能,如果有需要,想要显示温度平均值,只要通过更改几个语句就可以完成,需要继续测量更多的温度点,则只要按照前面讨论的DS18B20的接口电路与单片机连接好,再继续多加相应的温度测量、显示就能实现。

因此,本设计的拓展性很强。

7.附录A;源程序
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
sbit RS=P2^5; //定义LCD端口
sbit RW=P2^6;
sbit E=P2^7;
sbit DQ=P2^4; //定义单总线端口
uchar LCD_3,LCD_2,LCD_1,LCD_0;
uchar ds18b20_romA[8]={0x8e,0x00,0x00,0x00,0xb8,0xc5,0x30,0x28};
//四个DS18B20的64位ROM地址uchar ds18b20_romB[8]={0x52,0x00,0x00,0x00,0xb8,0xc5,0x34,0x28};
uchar ds18b20_romC[8]={0x65,0x00,0x00,0x00,0xb8,0xc5,0x35,0x28};
uchar ds18b20_romD[8]={0x3c,0x00,0x00,0x00,0xb8,0xc5,0x36,0x28};
uchar code LCDData[] ="0123456789";
uchar code dot_tab[] ="0112334456678899";
uchar first_line[16]="A:000.0 B:000.0"; //LCD第一行显示缓存数组uchar second_line[16]="C:000.0 D:000.0"; //LCD第二行显示缓存数组
//************************************
//延时程序
//************************************
void delay(unsigned int N)
{
unsigned int i;
for(i=0;i<N;i++);
}
//************************************
//LCD1602测忙
//************************************
void check_busy(void)
{
while(1)
{
P1=0xff;
E=0;
_nop_();
RS=0;
_nop_();
_nop_();
RW=1;
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
_nop_();
_nop_();
if((P1&0x80)==0)
{
break;
}
E=0;
}
}
//************************************ //LCD1602写命令
//************************************ void write_command(uchar tempdata) {
E=0;
_nop_();
_nop_();
RS=0;
_nop_();
_nop_();
RW=0;
P1=tempdata;
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
E=0;
_nop_();
check_busy();
}
//************************************ //LCD1602写数据
//************************************ void write_data(uchar tempdata)
{
E=0;
_nop_();
_nop_();
RS=1;
_nop_();
_nop_();
RW=0;
P1=tempdata;
_nop_();
_nop_();
E=1;
_nop_();
_nop_();
E=0;
_nop_();
check_busy();
}
//************************************
//初始化LCD1602
//************************************
void init_lcd1602()
{
write_command(0x01); //清除屏幕
write_command(0x38); //功能设定(8位,2行,5*7点阵式)
write_command(0x0c); //显示器ON,光标OFF,闪烁OFF
write_command(0x06);//地址加1
}
//************************************
//初始化ds18b20
//************************************
bit resetpulse(void)
{
DQ=0;
delay(40); //延时500us
DQ=1;
delay(4); //延时60us
return(DQ); //读取P1.0的状态
}
void ds18b20_init(void)
{
while(1)
{
if(!resetpulse()) //收到ds18b20的应答信号
{
DQ=1;
delay(40); //延时240us
break;
}
else
resetpulse(); //否则再发复位信号}
}
//************************************
//读ds18b20一位
//************************************
uchar read_bit(void)
{
DQ=0;
_nop_();
_nop_();
DQ=1;
delay(2);
return(DQ);
}
//************************************
//读ds18b20一个字节
//************************************
uchar read_byte(void)
{
uchar i,m,receive_data;
m=1;
receive_data=0;
for(i=0;i<8;i++)
{
if(read_bit())
{
receive_data=receive_data+(m<<i);
}
delay(7);
}
return(receive_data);
}
//************************************
//向ds18b20写一位
//************************************
void write_bit(uchar bitval)
{
DQ=0;
if(bitval==1)
DQ=1;
delay(5);
DQ=1;
}
//************************************
//向DS18B20写一个字节命令
//************************************
void write_byte(uchar val)
{
uchar i,temp;
for(i=0;i<8;i++)
{
temp=val>>i;
temp=temp&0x01;
write_bit(temp);
delay(5);
}
}
//************************************* //64位的ROM序列号匹配
//************************************* bit match_rom(uchar *rom)
{
uchar i;
ds18b20_init();
write_byte(0x55);
for(i=8;i>0;i--)
{
write_byte(*(rom+i-1));
}
return 1;
}
//************************************ //从ds18b20中读出64位序列号
//************************************ /*uchar * read_rom(void)
{
uchar rom[8],i;
ds18b20_init();
write_byte(0x33);
for(i=8;i>0;i--)
{
rom[i-1]=read_byte();
}
return &rom[0];
}*/
//************************************* //将64位序列号显示在LCD上显示出来
//************************************* /*void print_char(uchar a)
{
if(a>=0&&a<=9)
write_data(a+0x30);
else if(a>=0x0a &&a<= 0x0f)
write_data(a+0x37);
}*/
//*************************************
//温度转换,将从ds18b20中读出来的温度值
//转化成十进制的温度值,并存放显示缓存
//*************************************
void convert_T(uchar temp_data_h,uchar temp_data_l)
{
uchar temp;
if((temp_data_h&0xf0)==0xf0) //如果温度寄存器里的高位为1,
{ //则温度为负
temp_data_l=~temp_data_l; //负温度将补码转成二进制,
if(temp_data_l==0xff) //取反再加1
{
temp_data_l=temp_data_l+0x01;
temp_data_h=~temp_data_h;
temp_data_h=temp_data_h+0x01;
}
else
{
temp_data_l=temp_data_l+0x01;
temp_data_h=~temp_data_h;
}
LCD_0=dot_tab[temp_data_l&0x0f]; //查表得小数位的值
temp=((temp_data_l&0xf0)>>4)|((temp_data_h&0x0f)<<4);
LCD_3='-'; //显示"-"号
LCD_2=LCDData[(temp%100)/10]; //查表得负温度温度十位
LCD_1=LCDData[(temp%100)%10]; //查表得负温度个位 }
else //温度为正
{
LCD_0=dot_tab[temp_data_l&0x0f]; //查表得小数位的值
temp=((temp_data_l&0xf0)>>4)|((temp_data_h&0x0f)<<4);
LCD_3=LCDData[temp/100]; //查表得温度百位
LCD_2=LCDData[(temp%100)/10]; //查表得温度十位
LCD_1=LCDData[(temp%100)%10]; //查表得温度个位 }
}
void display(void)
{
uchar i;
write_command(0x80);
for(i=0;i<16;i++)
{
write_data(first_line[i]);
}
write_command(0xc0);
for(i=0;i<16;i++)
{
write_data(second_line[i]);
}
}
void main(void)
{
uchar temp_data_l,temp_data_h;
/*uchar *ds18b20_rom;*/
init_lcd1602();
/*while(1)
{
uchar i;
ds18b20_rom=read_rom(); //读序列号
write_command(0x80);
for(i=0;i<8;i++)
{
ds18b20_romA[i]=*ds18b20_rom;
ds18b20_rom++;
}
write_command(0x80);
for(i=0;i<8;i++) //显示序列号
{
print_char(ds18b20_romA[i]/16);
print_char(ds18b20_romA[i]%16);
}
}*/
while(1)
{
ds18b20_init();
write_byte(0xcc);
write_byte(0x44); //启动温度转换
delay(700);
match_rom(ds18b20_romA); //匹配第一路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
first_line[2]=LCD_3; //温度转换后的各位
first_line[3]=LCD_2; //分别存入显示缓存数组中
first_line[4]=LCD_1;
first_line[6]=LCD_0;
match_rom(ds18b20_romB); //匹配第二路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
first_line[10]=LCD_3; //温度转换后的各位
first_line[11]=LCD_2; //分别存入显示缓存数组中
first_line[12]=LCD_1;
first_line[14]=LCD_0;
display();
match_rom(ds18b20_romC); //匹配第三路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
second_line[2]=LCD_3; //温度转换后的各位
second_line[3]=LCD_2; //分别存入显示缓存数组中
second_line[4]=LCD_1;
second_line[6]=LCD_0;
match_rom(ds18b20_romD); //匹配第四路
write_byte(0xbe); //读温度
temp_data_l= read_byte(); //温度低8位
temp_data_h = read_byte(); //温度高8位
convert_T(temp_data_h,temp_data_l);
second_line[10]=LCD_3; //温度转换后的各位
second_line[11]=LCD_2; //分别存入显示缓存数组中
second_line[12]=LCD_1;
second_line[14]=LCD_0;
display();
}}
8.参考文献
[1] 彭伟.单片机C语言程序设计实训100例.电子工业出版社.
[2] 周景润张丽娜.Proteus入门实用教程
[3]邵启湖.基于DS1820的多点温度测量电路设计[J].湖南科技学院学报,2006(5):42-44.
[4]李红萍.基于单片机的多点温度测量显示系统设计[J].兰州石化职业技术学院学报,2006(3):17-19.
[5]罗文广,兰红莉,陆子杰.基于单总线的多点温度测量技术[J].传感器技术,2002(3):47-50.
[6]吴永.基于网络的单片机多点温度采集系统的设计[J].2010.18(4):959-960,964. [7]韦珑砷,杨荣松.基于DSI8B20的单片机多点温度测量系统[J].机械与电子.2007(11):42-44.。

相关文档
最新文档