找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9447|回复: 1
打印 上一主题 下一主题
收起左侧

51单片机DS18B20温度测量

[复制链接]
跳转到指定楼层
楼主
ID:73526 发表于 2015-2-11 01:13 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
      大家好,通过以前的学习,我们已经对51单片机综合学习系统的使用方法及学习方式有所了解与熟悉,学会了步进电机控制的基本知识,体会到了综合学习系统的易用性与易学性,这一期我们将一起学习数字温度传感器DS18B20的基本原理与使用方法。
      先看一下我们将要使用的51单片机综合学习系统能完成哪些实验与产品开发工作:分别有流水灯,数码管显示,液晶显示,按键开关,蜂鸣器奏乐,继电器控制,IIC总线,SPI总线,PS/2实验,AD模数转换,光耦实验,串口通信,红外线遥控,无线遥控,温度传感,步进电机控制等等。
     单总线温度传感器DS18B20简介
     DS18B20是DALLAS公司生产的单总线式数字温度传感器,它具有微型化、低功耗、高性能、搞干扰能力强、易配处理器等优点,特别适用于构成多点温度测控系统,可直接将温度转化成串行数字信号(提供9位二进制数字)给单片机处理,且在同一总线上可以挂接多个传感器芯片。它具有3引脚TO-92小体积封装形式,温度测量范围为-55℃~+125℃,可编程为9位~12位A/D转换精度,测温分辨率可达0.0625℃,被测温度用符号扩展的16位数字量方式串行输出,其工作电源既可在远端引入,也可采用寄生电源方式产生,多个DS18B20可以并联到3根或2根线上,CPU只需一根端口线就能与多个DS18B20通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。以上特点使DS18B20非常适用于远距离多点温度检测系统。
    DS18B20外形及引脚说明
    在TO-92和SO-8的封装中引脚有所不同,具体差别请查阅PDF手册,在TO-92封装中引脚分配如下:
    1(GND):地
    2(DQ):单线运用的数据输入输出引脚
    3(VDD):可选的电源引脚
    DS18B20工作过程及时序
    DS18B20内部的低温度系数振荡器是一个振荡频率随温度变化很小的振荡器,为计数器1提供一频率稳定的计数脉冲。
    高温度系数振荡器是一个振荡频率对温度很敏感的振荡器,为计数器2提供一个频率随温度变化的计数脉冲。
    初始时,温度寄存器被预置成-55℃,每当计数器1从预置数开始减计数到0时,温度寄存器中寄存的温度值就增加1℃,这个过程重复进行,直到计数器2计数到0时便停止。
    初始时,计数器1预置的是与-55℃相对应的一个预置值。以后计数器1每一个循环的预置数都由斜率累加器提供。为了补偿振荡器温度特性的非线性性,斜率累加器提供的预置数也随温度相应变化。计数器1的预置数也就是在给定温度处使温度寄存器寄存值增加1℃计数器所需要的计数个数。
    DS18B20内部的比较器以四舍五入的量化方式确定温度寄存器的最低有效位。在计数器2停止计数后,比较器将计数器1中的计数剩余值转换为温度值后与0.25℃进行比较,若低于0.25℃,温度寄存器的最低位就置0;若高于0.25℃,最低位就置1;若高于0.75℃时,温度寄存器的最低位就进位然后置0。这样,经过比较后所得的温度寄存器的值就是最终读取的温度值了,其最后位代表0.5℃,四舍五入最大量化误差为±1/2LSB,即0.25℃。
    温度寄存器中的温度值以9位数据格式表示,最高位为符号位,其余8位以二进制补码形式表示温度值。测温结束时,这9位数据转存到暂存存储器的前两个字节中,符号位占用第一字节,8位温度数据占据第二字节。
    DS18B20测量温度时使用特有的温度测量技术。DS18B20内部的低温度系数振荡器能产生稳定的频率信号;同样的,高温度系数振荡器则将被测温度转换成频率信号。当计数门打开时,DS18B20进行计数,计数门开通时间由高温度系数振荡器决定。芯片内部还有斜率累加器,可对频率的非线性度加以补偿。测量结果存入温度寄存器中。一般情况下的温度值应该为9位,但因符号位扩展成高8位,所以最后以16位补码形式读出。
    DS18B20工作过程一般遵循以下协议:初始化——ROM操作命令——存储器操作命令——处理数据
    ① 初始化
    单总线上的所有处理均从初始化序列开始。初始化序列包括总线主机发出一复位脉冲,接着由从属器件送出存在脉冲。存在脉冲让总线控制器知道DS1820 在总线上且已准备好操作。
   ② ROM操作命令
    一旦总线主机检测到从属器件的存在,它便可以发出器件ROM操作命令之一。所有ROM操作命令均为8位长。这些命令列表如下:
Read ROM(读ROM)[33h]
    此命令允许总线主机读DS18B20的8位产品系列编码,唯一的48位序列号,以及8位的CRC。此命令只能在总线上仅有一个DS18B20的情况下可以使用。如果总线上存在多于一个的从属器件,那么当所有从片企图同时发送时将发生数据冲突的现象(漏极开路会产生线与的结果)。
    Match ROM( 符合ROM)[55h]
    此命令后继以64位的ROM数据序列,允许总线主机对多点总线上特定的DS18B20寻址。只有与64位ROM序列严格相符的DS18B20才能对后继的存贮器操作命令作出响应。所有与64位ROM序列不符的从片将等待复位脉冲。此命令在总线上有单个或多个器件的情况下均可使用。
    Skip ROM( 跳过ROM )[CCh]
    在单点总线系统中,此命令通过允许总线主机不提供64位ROM编码而访问存储器操作来节省时间。如果在总线上存在多于一个的从属器件而且在Skip ROM命令之后发出读命令,那么由于多个从片同时发送数据,会在总线上发生数据冲突(漏极开路下拉会产生线与的效果)。
    Search ROM( 搜索ROM)[F0h]
    当系统开始工作时,总线主机可能不知道单线总线上的器件个数或者不知道其64位ROM编码。搜索ROM命令允许总线控制器用排除法识别总线上的所有从机的64位编码。
    Alarm Search(告警搜索)[ECh]
    此命令的流程与搜索ROM命令相同。但是,仅在最近一次温度测量出现告警的情况下,DS18B20才对此命令作出响应。告警的条件定义为温度高于TH 或低于TL。只要DS18B20一上电,告警条件就保持在设置状态,直到另一次温度测量显示出非告警值或者改变TH或TL的设置,使得测量值再一次位于允许的范围之内。贮存在EEPROM内的触发器值用于告警。
    ③ 存储器操作命令
    Write Scratchpad(写暂存存储器)[4Eh]
    这个命令向DS18B20的暂存器中写入数据,开始位置在地址2。接下来写入的两个字节将被存到暂存器中的地址位置2和3。可以在任何时刻发出复位命令来中止写入。
    Read Scratchpad(读暂存存储器)[BEh]
    这个命令读取暂存器的内容。读取将从字节0开始,一直进行下去,直到第9(字节8,CRC)字节读完。如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。
    Copy Scratchpad(复制暂存存储器)[48h]
    这条命令把暂存器的内容拷贝到DS18B20的E2存储器里,即把温度报警触发字节存入非易失性存储器里。如果总线控制器在这条命令之后跟着发出读时间隙,而DS18B20又正在忙于把暂存器拷贝到E2存储器,DS18B20就会输出一个“0”,如果拷贝结束的话,DS18B20 则输出“1”。如果使用寄生电源,总线控制器必须在这条命令发出后立即起动强上拉并最少保持10ms。
    Convert T(温度变换)[44h]
    这条命令启动一次温度转换而无需其他数据。温度转换命令被执行,而后DS18B20保持等待状态。如果总线控制器在这条命令之后跟着发出读时间隙,而DS18B20又忙于做时间转换的话,DS18B20将在总线上输出“0”,若温度转换完成,则输出“1”。如果使用寄生电源,总线控制器必须在发出这条命令后立即起动强上拉,并保持500ms。
    Recall E2(重新调整E2)[B8h]
    这条命令把贮存在E2中温度触发器的值重新调至暂存存储器。这种重新调出的操作在对DS18B20上电时也自动发生,因此只要器件一上电,暂存存储器内就有了有效的数据。在这条命令发出之后,对于所发出的第一个读数据时间片,器件会输出温度转换忙的标识:“0”=忙,“1”=准备就绪。
    Read Power Supply(读电源)[B4h]
    对于在此命令发送至DS18B20之后所发出的第一读数据的时间片,器件都会给出其电源方式的信号:“0”=寄生电源供电,“1”=外部电源供电。
    ④ 处理数据
    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。
    DS18B20软、硬件设计
    本实例介绍DS18B20与单片机之间的软、硬件接口,通过单片机来读取DS18B20的温度值,并将温度值通过数码管显示出来。在实验中先要将功能选择开关调到DS18B20位置上。
/***************************************************************************/
/*DS18B20演示程序 */
/*目标器件:AT89S51 */
/*晶振:11.0592MHZ */
/*编译环境:Keil 7.50A */
/***************************************************************************/
/*********************************包含头文件********************************/
#include <reg51.h>
/*******************************共阳LED段码表*******************************/
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
/*********************************端口定义**********************************/
sbit DQ=P3^3; //数据传输线接单片机的相应的引脚
/*********************************定义全局变量******************************/
unsigned char tempL=0; //临时变量低位
unsigned char tempH=0; //临时变量高位
float temperature; //温度值
/****************************************************************************
函数功能:延时子程序
入口参数:k
出口参数:
/****************************************************************************/
void delay(unsigned int k)
{
unsigned int n;
n=0;
while(n < k)
{n++;}
return;
}
/****************************************************************************
函数功能:数码管扫描延时子程序
入口参数:
出口参数:
***************************************************************************/
void delay1(void)
{
int k;
for(k=0;k<400;k++);
}
/****************************************************************************
函数功能:数码管显示子程序
入口参数:k
出口参数:
/****************************************************************************/
void display(int k)
{
P2=0xfe;
P0=tab[k/1000];
delay1();
P2=0xfd;
P0=tab[k%1000/100];
delay1();
P2=0xfb;
P0=tab[k%100/10];
delay1();
P2=0xf7;
P0=tab[k%10];
delay1();
P2=0xff;
}
/****************************************************************************
函数功能:DS18B20初始化子程序
入口参数:
出口参数:
/****************************************************************************/
Init_DS18B20(void)
{
unsigned char x=0;
DQ=1; //DQ先置高
delay(8); //延时
DQ=0; //发送复位脉冲
delay(85); //延时(>480ms)
DQ=1; //拉高数据线
delay(14); //等待(15~60ms)
}
/****************************************************************************
函数功能:向DS18B20读一字节数据
入口参数:
出口参数:dat
/****************************************************************************/
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat=0;
for (i=8;i>0;i--)
{
DQ=1;
delay(1);
DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
/****************************************************************************
函数功能:向DS18B20写一字节数据
入口参数:dat
出口参数:
****************************************************************************/
WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
}
/****************************************************************************
函数功能:向DS18B20读温度值
入口参数:
出口参数:temperature
****************************************************************************/
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)*0.0625;
delay(200);
return(temperature);
}
/****************************************************************************
函数功能:主程序
入口参数:
出口参数:
****************************************************************************/
void main()
{
float i;
while(1)
{
i=ReadTemperature();
display(i);
}
}
相信看到这里,你应该可以理解DS18B20数字温度传感器的原理是怎么样的了,你也可以根据自己的需要来写一下温度探测及相关控制的程序。由于篇幅有限,读者朋友可以通过网站或电子邮件一起交流与学习。


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:73711 发表于 2015-2-17 17:29 | 只看该作者
感谢  分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表