DS18B20的原理及实例代码(51单片机、STM32单片机) 您所在的位置:网站首页 ds18b20的电路 DS18B20的原理及实例代码(51单片机、STM32单片机)

DS18B20的原理及实例代码(51单片机、STM32单片机)

2024-06-24 20:18| 来源: 网络整理| 查看: 265

一、DS18B20介绍

DS18B20数字温度传感器是DALLAS公司生产的单总线器件,用它来组成一个测温系统具有线路简单,体积小,在一根通信线上可以挂很多这样的数字温度传感器,十分方便。

        温度传感器种类众多,应用在高精度、高可靠性的场合时DALLAS公司生产的DS18B20温度传感器当仁不让。超小的体积,超低的硬件开销,抗干扰能力强,精度高,附加功能强,使得DS18B20更受欢迎。DS18B20的优势更是我们学习单片机技术和开发温度相关小产品的不二选择。了解工作原理和应用可以拓宽您对单片机开发的思路。

二、DS18B20特点 1、通信采用1-Wire接口 2、每个DS18B20都有唯一的64位序列码储存在板载ROM中 3、无需外部元件 4、可从数据线供电,电源范围为3.0V ~ 5.5V。 5、可测量的温度范围在-55℃ ~ +125℃ 6、在-10~+85℃范围内精确度为±0.5℃ 7、温度计分辨率可设置为9~12位,12位时分辨率对应为0.0625℃  三、DS18B20在实际应用中的典型接法

1、工作在寄生电源下的典型接法

2、 外部供电下的典型接法

 

 四、单总线时序

       DS18B20采用1-wire Bus所有数据都在一条线上传输,因此单总线协议对时序要求非常严格以确保数据的完整性。

       单总线信号类型:复位脉冲、存在脉冲、写0、写1、读0、读1。所有这些信号除存在脉冲由DS18B20发出的以外其他信号都由总线控制器发出。

       数据传输总是从最低有效位开始。

1、初始化时序

初始化时序里面包含了复位DS18B20和接收DS18B20返回的存在信号。

主机和DS18B20做任何通讯前都需要对其初始化。初始化期间,总线控制器拉低总线并保持480us以上挂在总线上的器件将被复位,然后释放总线,等到15-60us,此时18B20将返回一个60-240us之间的低电平存在信号。

复位脉冲和存在脉冲时序图:

2、写时序

写时序分为写0时序和写1时序。

总线控制器通过控制单总线高低电平持续时间从而把逻辑1或0写DS18B20中。

总线控制器要产生一个写时序,必须将总线拉低最少1us,产生写0时序时总线必须保持低电平60~120us之间,然后释放总线,产生写1时序时在总线产生写时序后的15us内允许把总线拉高。注意:2次写周期之间至少间隔1us

 3、读时序

读时序分为读0时序和读1时序。

总线控制器通过读取由DS18B20控制的总线高低电平接收DS18B20数据,总线控制器要产生一个读时序,必须将总线拉低至少1us,然后释放总线,在读信号开始后15us内总线控制器采样总线数据,读一位数据至少保持在60us以上。注意:2次读周期之间至少间隔1us

读时序图:

 读1详细时序图:

 五、DS18B20暂存器

 温度寄存器图表:

 

 配置寄存器图表:

 

 部分ROM指令及功能指令:

执行序列

通过单线总线端口访问DS18B20的协议如下:

步骤1. 初始化

步骤2. ROM操作指令

步骤3. DS18B20功能指令

忽略ROM指令(CCh):

这条指令允许总线控制器不用提供64 位ROM 编码就使用功能指令。例如,总线控制器可以先发出一条忽略ROM 指令,然后发出温度转换指令[44h],从而完成温度转换操作。在单点总线情况下使用该命令,器件无需发回64 位ROM 编码,从而节省了时间。如果总线上有不止一只从机,若发出忽略ROM指令,由于多只从机同时传送信号,总线上就会发生数据冲突。

六、DS18B20功能指令

1、温度转换指令(44h)

这条命令用以启动一次温度转换。温度转换指令被执行,产生的温度转换结果数据以2个字节的形式被存储在高速暂存器中,而后DS18B20保持等待状态。

2、读暂存器指令(BEh)

这条命令读取暂存器的内容。读取将从字节0 开始,一直进行下去,直到读完暂存器所有字节,如果不想读完所有字节,控制器可以在任何时间发出复位命令来中止读取。

3、写暂存器指令(4Eh)

这条命令向DS18B20 的暂存器写入数据,开始位置在TH 寄存器(暂存器的第2个字节),接下来写入TL 寄存器(暂存器的第3 个字节),最后写入配置寄存器(暂存器的第4 个字节)

4、拷贝暂存器指令(48h)

这条命令把TH,TL 和配置寄存器(第2、3、4 字节)的内容拷贝到EEPROM 中。

 七、执行序列

通过单线总线端口访问DS18B20的协议如下:

步骤1. 初始化

步骤2. ROM操作指令

步骤3. DS18B20功能指令

            温度转换命令

            读取暂存器命令

八、DS18B20驱动代码

1、51单片机(数码管显示)

#include #include #define MAIN_Fosc 11059200UL //宏定义主时钟HZ /*==================================== 自定义类型名 ====================================*/ typedef unsigned char INT8U; typedef unsigned char uchar; typedef unsigned int INT16U; typedef unsigned int uint; /*==================================== 硬件接口位声明 ====================================*/ sbit DS = P2^2; //DS18B20单总线 sbit DU = P2^6; //数码管段选 sbit WE = P2^7; //数码管位选 /*==================================== 共阴极数码管段选码 ====================================*/ uchar code table[]={ //0 1 2 3 4 5 6 7 8 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, //9 A B C D E F - . 关显示 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00 }; /*==================================== 数码管位选码 ====================================*/ //第1位 2位 3位 4位 5位 6位 7位 8位 uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码 /*==================================== 函数:void Delay_Ms(INT16U ms) 参数:ms,毫秒延时形参 描述:12T 51单片机自适应主时钟毫秒级延时函数 ====================================*/ void Delay_Ms(INT16U ms) { INT16U i; do{ i = MAIN_Fosc / 96000; while(--i); //96T per loop }while(--ms); } /*us延时函数,执行一次US--所需6.5us进入一次函数需要11.95us*/ void Delay_us(uchar us) { while(us--); } /*==================================== 函数:void Display(INT16U Value) 参数:Value,显示值 取值0-65535 描述:共阴极数码管显示函数可显示一个字节的数 ====================================*/ void Display(INT16U Value) //注意由于需要显示的数大于一个字节所有形参需为int型 { //------------------------------ DU = 0; //关闭段选 P0 = table[Value/100]; //数码管显示百位 DU = 1; //打开段选 DU = 0; //关闭段选 WE = 0; //关闭位选 P0 = T_COM[0]; //第一位数码管 WE = 1; //打开位选 WE = 0; //关闭位选 Delay_Ms(3); //------------------------------- DU = 0; P0 = table[Value%100/10]|0x80; //显示十位 DU = 1; DU = 0; WE = 0; P0 = T_COM[1]; //第二位数码管 WE = 1; WE = 0; Delay_Ms(3); //------------------------------- DU = 0; P0 = table[Value%10]; //显示个位 DU = 1; DU = 0; WE = 0; P0 = T_COM[2]; //第三位数码管 WE = 1; WE = 0; Delay_Ms(3); } /*单总线初始化时序*/ bit ds_init() { bit i; DS = 1; _nop_(); DS = 0; Delay_us(75); //拉低总线499.45us 挂接在总线上的18B20将会全部被复位 DS = 1; //释放总线 Delay_us(4); //延时37.95us 等待18B20发回存在信号 i = DS; Delay_us(20); //141.95us DS = 1; _nop_(); return (i); } /*写一个字节*/ void write_byte(uchar dat) { uchar i; for(i=0;i>= 1; } } uchar read_byte() { uchar i, j, dat; for(i=0;i0) i--; ds = 1; i = 4; while(i>0) i--; } void dsWait() { unsigned int i; while(ds); while(~ds); i = 4; while(i > 0) i--; } bit readBit() { unsigned int i; bit b; ds = 0; i++; ds = 1; i++; i++; b = ds; i = 8; while(i>0) i--; return b; } unsigned char readByte() { unsigned int i; unsigned char j, dat; dat = 0; for(i=0; i 1); } return dat; } void writeByte(unsigned char dat) { unsigned int i; unsigned char j; bit b; for(j = 0; j < 8; j++) { b = dat & 0x01; dat >>= 1; if(b) { ds = 0; i++; i++; ds = 1; i = 8; while(i>0) i--; } else { ds = 0; i = 8; while(i>0) i--; ds = 1; i++; i++; } } } void sendChangeCmd() { dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0x44); } void sendReadCmd() { dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0xbe); } int getTmpValue() { unsigned int tmpvalue; int value; float t; unsigned char low, high; sendReadCmd(); low = readByte(); high = readByte(); tmpvalue = high; tmpvalue


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有