1.DS18B20温度传感器
DS18B20是由DALLAS半导体公司推出的一款基于单总线接口的数字温度传感器。与传统的热敏电阻等模拟温度传感器相比,DS18B20具有体积小、适用电压范围宽、接口简单等缺点,广泛应用于工业控制、温度监测等领域。
1 主要特点
- 宽电压范围:工作电压为 3.0V~5.5V,支持寄生电源模式,可通过数据线供电。
- 单总线接口:仅需一条数据线即可实现与微处理器的双向通信,简化了硬件设计。
- 多点组网功能:多个 DS18B20 可以并联在同一总线上,实现多点测温。
- 高集成度:传感器内部集成了全部传感元件和转换电路,无需外部元件。
- 宽温度范围:测温范围为 -55℃~+125℃,在 -10℃~+85℃ 时精度为 ±0.5℃。
- 可编程分辨率:支持 9~12 位分辨率,对应温度分辨率为 0.5℃、0.25℃、0.125℃ 和 0.0625℃。
- 快速转换:在 9 位分辨率时,温度转换时间最快为 93.75ms;12 位分辨率时为 750ms。
- 数字输出:温度测量结果直接以数字信号输出,抗干扰能力强。
- 负压保护:电源极性接反时,芯片不会烧毁,但无法正常工作。
2.引脚说明
DS18B20 有三个引脚:
- GND:接地。
- DQ(I/O):数据线,用于与微处理器通信。
- VDD:电源引脚,电压范围为 3.0V~5.5V。
注意:插入传感器时需注意方向,插反会导致电源短路,损坏传感器。
3. 内部结构
DS18B20 内部包含以下主要部分:
- 64 位 ROM:存储唯一的序列号,用于区分多个传感器。
- 高速暂存器 RAM:存储温度转换结果。
- EEPROM:存储温度触发器和配置寄存器。

ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列号。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20是该DS18B20自身的序列号,最后8位是前面56位循环冗余校验码。光刻ROM的作用是使每一个DS18B20各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
DS18B20温度传感器的内部存储器包括一个高速的暂存器RAM和一个非易失性的可电擦除的EEPROM,后者存放高温度和低温度触发器TH、TL和配置寄存器。
配置寄存器是配置不同位数来确定温度和数字的转化,配置寄存器温度如下:

低5位一直是"1",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用户不需要改动。R1和R0用来设置DS18B20的精度(分辨率),可设置为9,10,11或12位,对应的分辨率温度是0.5℃,0.25℃,0.0625℃。
R0和R1配置如下图:

在初始状态下默认的精度是12位,即R0=1、R1=1。
高速暂存存储器由9个字节组成,其分配如下:

当温度转换命令(44H)发布后,经转换所得的温度值以二进制补码形式存放在高速暂存器的第0和第1个字节。存储的两个字节,高字节的前5位是符号位S,单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式如下:

如果测得的温度大于0,这5位为"0",只要将测到的数值乘以0.0625(默认精度是12位)即可得到实际温度;如果温度小于0,这5位为"1",测到的数值需要取反加1再乘以0.0625即可得到实际温度。温度与数据对应光系如下:

1.初始化时序
单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480us(该时间的范围可以从480到960us),以产生复位脉冲。接着主机释放总线,外部的上拉电阻将单总线拉高,延时15-60us,并进入接收模式。接着DS18B20拉低总线60-240us,以产生低电平应答脉冲,若为低电平,还要做延时,其延时的时间从外部上拉电阻将单总线拉高算起最少要480us,初始化时序图如下:
sbit OneWire_DQ=P3^7;
unsigned char OneWire_Init(void)
{
unsigned char i;
unsigned char ActBit;
OneWire_DQ=1;
OneWire_DQ=0;
i = 227;while (--i); //Delay 500us
OneWire_DQ=1;
i = 29;while (--i); //Delay 70us
ActBit=OneWire_DQ;
i = 227;while (--i); //Delay 500us
return ActBit;
}
2.写时序
写时序包括写0时序和1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。写1时序,主机输出低电平,延时2us,然后释放总线延时60us。写0时序,主机输出低电平,延时60us,然后释放总线,延时20us,写时序如下:

void OneWire_SendBit(unsigned char Bit)
{
unsigned char i;
OneWire_DQ=0;
i = 3;while (--i); //Delay 10us
OneWire_DQ=Bit;
i = 22;while (--i); //Delay 50us
OneWire_DQ=1;
}
void OneWire_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
OneWire_SendBit(Byte&(0x01<<i));
}
}
3.读时序
单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要60us,且在2次独立的时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us内采样总线状态。

unsigned char OneWire_ReceiveBit(void)
{
unsigned char i;
unsigned char Bit;
OneWire_DQ=0;
i = 1;while (--i); //Delay 9us
OneWire_DQ=1;
i = 1;while (--i); //Delay 9us
Bit=OneWire_DQ;
i = 22;while (--i); //Delay 50us
return Bit;
}
unsigned char OneWire_ReceiveByte(void)
{
unsigned char i;
unsigned char Byte=0x00;
for(i=0;i<8;i++)
{
if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
}
return Byte;
}
4.DS18B20
#include <REGX52.H>
#include "OneWire.h"
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
1.温度转换
void DS18B20_ConverT(void)
{
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM); //跳过ROM操作
OneWire_SendByte(DS18B20_CONVERT_T); //启动温度转换
}
2.温度读取
float DS18B20_ReadT(void)
{
unsigned char TLSB,TMSB;
int Temp;
float T;
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM); //跳过ROM操作
OneWire_SendByte(DS18B20_READ_SCRATCHPAD); //发送读取暂存器命令
TLSB=OneWire_ReceiveByte();
TMSB=OneWire_ReceiveByte();
Temp=(TMSB<<8)|TLSB;
T=Temp/16.0;
return T;
}
2.实践
接下来我们来实现测量温度,并将温度显示在LCD1602上:
#include <REG51.H>
#include "lcd1602.h"
#include "DS18B20.h"
#include "OneWire.h"
float T;
void main()
{
LCD1602_Init();
LCD1602_ShowString(1,1,"Temperature:");
while(1)
{
DS18B20_ConverT();
T=DS18B20_ReadT();
if(T<0)
{
LCD1602_ShowChar(2,1,'-');
T=-T;
}
else
{
LCD1602_ShowChar(2,1,'+');
}
LCD1602_ShowNum(2,2,T,3);
LCD1602_ShowChar(2,5,'.');
LCD1602_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
}
}