DS18B20介绍
DS18B20数字温度计提供9位到12位摄氏度的温度测量,并具有非易失性,用户可编程的上下触发点的报警功能。DS18B20通过1线总线进行通信,根据定义,该总线只需要一条数据线,即可与中央微处理器进行通信。它的工作温度范围为-55°C到+125°C,在-10°C到+85°C的范围内精确到±0.5°C。此外,DS18B20可以直接从数据线获得电力,消除了对外部电源的需要。
每个DS18B20都有一个唯一的64位串行码,它允许多个DS18B20在同一个1线总线上工作。因此,使用一个微处理器来控制分布在大面积区域内的许多ds18b20是很简单的。可以受益于此特性的应用程序包括暖通空调环境控制、建筑物内部的温度监测系统、设备或机械内部的温度监测系统,以及过程监控和控制系统。
引脚说明
8引脚SOIC封装 | T0-9封装 | 符号 | 说明 |
5 | 1 | GND | 接地 |
4 | 2 | DQ | 数据输入/输出引脚。对于单线操作:漏极开漏。当工作在寄生电源模式时用来提供电源(建“寄生电源”节) |
3 | 3 | VDD | 可选的VDD引脚。工作与寄生电源模式时VDD必须接地。 |
Tips:上表没说的引脚不需要连接。
DS18B20的另一个功能是可以在没有外部电源供电的情况下工作。当总线处于高电平状态,DQ与上拉电阻连接通过单总线对器件供电。同时处于高电平状态的总线信号对内部电容(Cpp)充电,在总线处于低电平状态时,该电容提供能量给器件。这种提供能量的形式被称为“寄生电源”。作为替代选择,DS18B20同样可以通过VDD引脚连接外部电源供电。
配置寄存器
bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 |
0 | R1 | R0 | 1 | 1 | 1 | 1 | 1 |
可通过按R1和R0来设置DS18B20的精度。上电默认设置:R0=1,R1=1(12位精度)。
Tips:精度和转换时间之间一般成反比。
温度计精确度配置表
R1 | R0 | 精度 | 最大转换时间 | |
0 | 0 | 9-bit | 93.75ms | (Tconv/8) |
0 | 1 | 10-bit | 187.5ms | (Tconv/4) |
1 | 0 | 11-bit | 375ms | (Tconv/2) |
1 | 1 | 12-bit | 750ms | (Tconv) |
温度转换期间(tconv)
执行序列
通过单线总线端口访问DS18B20的协议如下:
- 初始化
- ROM操作指令
- DS18B20功能指令
每次执行DS18B20都需要满足以上步骤,若是步骤缺少或混乱,DS18B20都将不会返回值。
初始化
通过单总线的所有执行操作都从一个初始化序列开始。初始化序列包括一个由总线控制器发出的复位脉冲和其后由从机发出的存在脉冲。从机的存在脉冲告知总线控制器DS18B20已就绪。
初始化序列
在初始化序列期间,总线控制器拉低总线并保持480us发出(TX)一个复位脉冲,然后释放总线,进入接受状态(RX)。单总线由5K上拉电阻拉到高电平。当DS18B20探测到I/O引脚上的上升沿后,等待15-60us,然后发出一个由60-240us低电平信号构成的存在脉冲。
简而言之,Vpu单总线刚开始为输出模式,输出480us低电平,然后输出高电平(15-60us)后,转换为上拉输入模式,总线接收到DS18B20的60-240us的低电平存在脉冲。
ROM操作指令
一旦总线控制器探测到一个存在脉冲,他就发出一条ROM指令。如果总线上挂有多个DS18B20,这些指令将通过器件独有的64位ROM片序列码使得总线控制器选出特定的需要控制的器件进行操作。
33h(读取ROM指令)
在总线只有单只DS18B20的时候才能使用这条命令。该命令允许总线控制器在不适用搜索ROM指令的情况下读取从机的64位片序列码;
CCh(忽略ROM指令)
这条指令允许总线控制器不用提供64位ROM编码使用功能指令。
其他ROM指令可以去看DS18B20的手册。
DS18B20控制指令
在总线控制器发给准备连接的DS18B20一条ROM命令后,随之发送一条DS18B20功能指令。这些命令可以让总线控制器读写DS18B20的暂存器,发起一些功能。
44h(温度转换指令)
使用这条指令可以启动一次温度转换。温度转换执行后,产生的温度转换结果数据以2个字节的形式被存储在高速暂存器中,而后DS18B20保持等待状态。如果在寄生电源模式下发出该指令后,在温度转换期间(tconv),在10us之内,给单总线一个强上拉。
B4h(读电源模式指令)
发出指令后,若是寄生电源模式,DS1820将拉低总线,若是外部电源模式,DS18B20将把总线拉高。
供电
DS18B20可以通过从VDD引脚接入一个外部电源供电,或者可以工作与寄生电源模式(通过数据线贡献),该模式允许DS18B20工作于无外部电源供电的状态。寄生电源在远距离测温时非常有用。
Tips:寄生电源模式时,VDD必须接地。
测温操作
DS18B20能够直接读取数字。DS18B20启动后保持低消耗状态;当需要执行温度测量和AD转换时,总线控制必须发出0x44的命令。之后,产生的温度数据以两个字节的形式被存储到高速暂存的温度寄存器中,然后DS18B20继续保持等待状态。
当DS18B20由外部电源供电时,总线控制器在温度转换指令之后发起“读时序”。
读时序
总线控制器发起读时序时,DS18B20 仅被用来传输数据给控制器。因此,总线控制器在发出读暂存器指令[BEh]或读电源模式指令[B4H]后必须立刻开始读时序,DS18B20可以提供请求信息。除此之外,总线控制器在发出发送温度转换指令[44h]或召回 EEPROM 指令[B8h]之后读时序。所有读时序必须最少 60us,包括两个读周期间至少 1us 的恢复时间。当总线控制器把数据线从高电平拉到低电平时,读时序开始,数据线必须至少保持 1us,然后总线被释放。在总线控制器发出读时序后,DS18B20 通过拉高或拉低总线上来传输 1 或 0。当传输逻辑 0 结束后,总线将被释放,通过上拉电阻回到上升沿状态。从 DS18B20 输出的数据在读时序的下降沿出现后 15us 内有效。因此,总线控制器在读时序开始后必须停止把 I/O 脚驱动为低电平 15us,以读取I/O 脚状态。
代码
bsp_ds18b20.c
#include "bsp_ds18b20.h"
void DS18B20_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DS18B20_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DS18B20_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void DS18B20_Init(void)
{
DS18B20_Mode_Out_PP();
DS18B20_DATA_OUT(0);
Delay_us(750);
DS18B20_DATA_OUT(1);
Delay_us(15);
DS18B20_Mode_IPU();
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) != 0);
while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6) == 0);
}
bsp_ds18b20.h
#ifndef __BSP_DS18B20_H__
#define __BSP_DS18B20_H__
#include <stm32f10x.h>
#include "bsp_SysTick.h"
#define DS18B20_DATA_OUT(a) GPIO_WriteBit(GPIOB, GPIO_Pin_6, (BitAction)(a))
void DS18B20_GPIO_Configuration(void);
void DS18B20_Init(void);
#endif
bsp_SysTick.c
#include "bsp_SysTick.h"
unsigned int TimingDelay;
void SysTick_Configuration(void)
{
while(SysTick_Config(72));
SysTick->CTRL &= ~(1<<0); //暂时初始化后先关闭定时器,使用前开启
}
void Delay_us(unsigned int n)
{
TimingDelay = n;
SysTick->CTRL |= (1<<0); //开启Sys_Tick
while(TimingDelay);
SysTick->CTRL &= ~(1<<0);
}
bsp_Systick.h
#ifndef __BSP_SYSTICK_H__
#define __BSP_SYSTICK_H__
#include <stm32f10x.h>
extern unsigned int TimingDelay;
void SysTick_Configuration(void);
void Delay_us(unsigned int n);
#endif