【51单片机快速入门指南】6.3:DS18B20 单总线数字温度计的多路读取

目录

  • 硬知识
    • DS18B20介绍
    • 时序
      • 初始化时序
      • 写时序
      • 读时序
    • 命令
      • ROM 操作命令
        • ROM 搜索举例
      • 存贮器操作命令
  • 示例程序
    • DS18B20.c
    • DS18B20.h
    • 测试程序
      • 定时器中断服务函数
      • 单传感器时ID的获取 main.c
      • 单传感器读取温度和读取特定ID传感器的温度
      • 多路传感器读取

普中51-单核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬知识

       摘自《普中 51 单片机开发攻略》、《DS18B20 单总线数字温度计》

DS18B20介绍

       DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线(单总线)”接 口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、 适用电压宽、与微处理器接口简单的数字化温度传感器。
       DS18B20 温度传感器具有如下特点:

  1. 适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据 线供电。
  2. 独特的单线接口方式,DS18B20 在与微处理器连接时仅需要一条口线即 可实现微处理器与 DS18B20 的双向通讯。
  3. DS18B20 支持多点组网功能,多个 DS18B20 可以并联在唯一的三线上, 实现组网多点测温。
  4. DS18B20 在使用中不需要任何外围元件,全部传感元件及转换电路集成 在形如一只三极管的集成电路内。
  5. 温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃
  6. 可编程的分辨率为 9~12 位,对应的可分辨温度分别为 0.5℃、0.25℃、 0.125℃ 和 0.0625℃,可实现高精度测温。
  7. 在 9 位分辨率时最多在 93.75ms 内把温度转换为数字,12 位分辨率时 最多在 750ms 内把温度值转换为数字,速度更快。
  8. 测量结果直接输出数字温度信号,以"一根总线"串行传送给 CPU,同时 可传送 CRC 校验码,具有极强的抗干扰纠错能力。
  9. 负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。 DS18B20 外观实物如下图所示:
    在这里插入图片描述
    在这里插入图片描述
           ROM 中的 64 位序列号是出厂前被光刻好的,它可以看作是该 DS18B20 的地址序列号。64 位光刻 ROM 的排列是:
           开始 8 位(28H)是产品类型标号,
           接着的 48 位是该 DS18B20 自身的序列号,
           最后 8 位是前面 56 位的循环冗余校验码。
           光刻 ROM 的作用是使每一个 DS18B20 都各不相同,这样就可以实现一根总线上挂接多个 DS18B20 的目的。
    在这里插入图片描述
           DS18B20 温度传感器的内部存储器包括一个高速的暂存器 RAM 和一个非易失性的可电擦除的 EEPROM,后者存放高温度和低温度触发器 TH、TL 和配置寄存器。配置寄存器是配置不同的位数来确定温度和数字的转化,配置寄存器结构如下:
    在这里插入图片描述
           低五位一直都是"1",TM 是测试模式位,用于设置 DS18B20 在工作模式还 是在测试模式。在 DS18B20 出厂时该位被设置为 0,用户不需要去改动。R1 和 R0 用来设置 DS18B20 的精度(分辨率),可设置为 9,10,11 或 12 位,对 应的分辨率温度是 0.5℃,0.25℃,0.125℃和 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 即可得到实际温度。温度与数据对应关系如下:
在这里插入图片描述

时序

       比如我们要计算+85 度,数据输出十六进制是 0X0550,因为高字节的高 5 位为 0,表明检测的温度是正温度,0X0550 对应的十进制为 1360,将这个值乘 以 12 位精度 0.0625,所以可以得到+85 度。 知道了怎么计算温度,接下来我们就来看看如何读取温度数据,由于 DS18B20 是单总线器件,所有的单总线器件都要求采用严格的信号时序,以保证 数据的 完整性。DS18B20 时序包括如下几种:初始化时序、写(0 和 1)时序、 读(0 和 1)时序。 DS18B20 发送所有的命令和数据都是字节的低位在前。这里我们简单介绍这几个信号的时序:

初始化时序

       单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少 480us(该时间的时间范围可以从 480 到 960 微妙),以产生复位脉冲。接着主机释放总线,外部的上拉电阻将单总线拉高,延时 15~60 us,并进 入接收模式。接着 DS18B20 拉低总线 60~240 us,以产生低电平应答脉冲,若为低电平,还要做延时,其延时的时间从外部上拉电阻将单总线拉高算起最少要 480 微妙。初始化时序图如下:
在这里插入图片描述
       逻辑分析仪实测如下
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

写时序

       写时序包括写 0 时序和写 1 时序。所有写时序至少需要 60us,且在 2 次 独立的写时序之间至少需要 1us 的恢复时间,两种写时序均起始于主机拉低总线。写 1 时序:主机输出低电平,延时 2us,然后释放总线,延时 60us。写 0 时序:主机输出低电平,延时 60us,然后释放总线,延时 2us。写时序图如下:
在这里插入图片描述
实操如下
握手后写入0xcc
在这里插入图片描述

读时序

       单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出 读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少 需要 60us,且在 2 次独立的读时序之间至少需要 1us 的恢复时间。每个读时序都由主机发起,至少拉低总线 1us。主机在读时序期间必须释放总线,并且在 时序起始后的 15us 之内采样总线状态。读时序图如下:
在这里插入图片描述
       典型的读时序过程为:主机输出低电平延时 2us,然后主机转入输入模式延 时 12us,然后读取单总线当前的电平,然后延时 50us。
       逻辑分析仪实测如下
在这里插入图片描述
读0时宽度为29us
在这里插入图片描述

读1时:
在这里插入图片描述

命令

ROM 操作命令

       一旦总线主机检测到从属器件的存在,它便可以发出器件 ROM 操作命令之一。所有 ROM 操作命令均为 8 位长,这些命令列表如下:
Read ROM(读 ROM) [33h]
       此命令允许总线主机读DS1820的8位产品系列编码,唯一的48位序列号,以及8位的CRC此命令只能在总线上仅有一个DS1820的情况下可以使用。如果总线上存在多于一个的从属器件,那么当所有从片企图同时发送时将发生数据冲突的现象(漏极开路会产生“线与”的结果)。
Match ROM("符合"ROM)[55h]
       “符合”ROM命令。后继以64位的ROM数据序列,允许总线主机对多点总线上特定的DS1820寻址。只有与64位ROM序列严格相符的DS 1820才能对后继的存贮器操作命令作出响应。所有与64位ROM序列不符的从片将等待复位脉冲。此命令在总线上有单个或多个器件的情况下均可使用。
Skip ROM(“跳过"ROM)[CCh]
       在单点总线系统中,此命令通过允许总线主机不提供64位ROM编码而访问存储器操作来节省时间。如果在总线上存在多于一个的从属器件而且在Skip ROM命令之后发出读命令,那么由于多个从片同时发送数据,会在总线上发生数据冲突(漏极开路下拉会产生“线与”的效果)。
Search ROM(搜索ROM)[F0h]
       当系统开始工作时,总线主机可能不知道单线总线上的器件个数或者不知道其64位ROM编码。
搜索ROM命令允许总线主机使用一种“消去”(elimination)处理来识别总线上所有从片的64位ROM编码。
Alarm Search(告警搜索)[ECh]
       此命令的流程与搜索ROM命令相同。但是,仅在最近一次温度测量出现告警的情况下,DS1820才对此命令作出响应。告警的条件定义为温度高于TH或低于TL。只要DS1820一上电,告警条件就保持在设置状态,直到另一次温度测量显示出非告警值,或者改变TH或TL的设置使得测量值再一次位于允许的范围之内。贮存在EEPROM内的触发器值用于告警。

ROM 搜索举例

【51单片机快速入门指南】6.3.1:使用1-WIRE搜索算法搜索单总线上所有DS18B20的ID(基于二叉树)

       ROM搜索过程是简单三步过程的重复:读一位,读该位的补码(complement),然后写所需的那一位的值。总线主机在ROM的每一位上完成这一简单的三步过程。在全部过程完成之后,总线主机便知道一个器件中ROM的内容。器件中其余的数以及它们的ROM编码可以由另外一个过程来识别。
       以下ROM搜索过程的例子假设四个不同的器件连接到同一条单线总线上。四个器件的ROM数据如下所示:
ROM1 00110101……
ROM2 10101010……
ROM3 11110101……
ROM4 00010001……
搜索过程如下:

  1. 总线主机通过发出复位脉冲开始初始化序列,从属器件通过发出同时的存在脉冲作出响应。
  2. 然后总线主机在单线总线上发出搜索ROM命令。
  3. 总线主机从单线过程中读一位。每一器件通过把它们各自ROM数据的第一位的值放到单线总线上来作出响应。ROM1和ROM4将把一个0放在单线总线上,即,把它拉至低电平。ROM2和3通过使总线停留在高电平而把1放在单线总线上。结果是线上所有器件的逻辑“与”,因此总线主机接收到一个0。总线主机读另一位。因为搜索ROM数据命令正在执行,所以单线总线上所有器件通过把它各自ROM数据第一位的补码放到单线总线上来对这第二个读作出响应 ROMI和ROM4把1放在单总线上,使之处于高电平。ROM2和ROM3把0放在单线上,因此它将被拉至低电平。对于第一个ROM数据位的补码总线主机观察到的仍是一个0。总线主机便可决定在单线总线上有一些第一位为0的器件和一些第一位为1的器件。

       从三步过程的两次读中可获得的数据具有以下的解释:
       00:有器件连接着,在此数据位上它们的值发生冲突。
       01:有器件连接着,在此数据位上它们的值均为0。
       10:有器件连接着,在此数据位上它们的值均为1
       11:没有器件与单线总线相连。

  1. 总线主机写一个0,在这次搜索过程的其余部分,将不选择ROM2和ROM3,仅留下连接到单线总线的ROM1和ROM4。
  2. 总线主机再执行两次读,并在一个1位之后接收到一个0位,这表示所有还连接在总线上的器件的第二个ROM数据位为0。
  3. 总线主机接着写一个0,使ROM1和ROM4二者继续保持连接。
  4. 总线主机执行两次读,并接收到两次0数据位。这表示连接着的器件的ROM数据的第三位都是1数据位和0数据位
  5. 总线主机写一个0数据位。这将不选择ROMI而把ROM4作为唯一仍连接着的器件加以保留。
  6. 总线主机读ROM4的ROM数据位的剩余部分,而且访问需要的部件。这就完成了第一个过程并且唯一地识别出单线总线上的部件。
  7. 总线主机通过重复步骤1至7开始一个新的ROM搜索序列。
  8. 总线主机写一个1,这将不与ROM4发生联系,而唯一地与ROM1仍保持着联系。
  9. 总线主机对于ROM1读出ROM位的剩余部分而且,如果需要的话,与内部逻辑通信。这就完成了第二个ROM搜索过程,在其中ROM中的另一个被找到。
  10. 总线主机通过重复步骤1至3开始一次新的ROM搜索。
  11. 总线主机写一个1数据位。这使得在这一搜索过程的其余部分不选择ROM1和ROM4,仅留下ROM2和ROM3与系统相连接。
  12. 总线主机执行两个读时间片并接收到两个零,
  13. 总线主机写一个0数据位。这去掉ROM3,仅留下ROM2.
  14. 总线主机对于ROM2读出ROM数据位的剩余部分,而且若有需要便与内部逻辑通信。这完成了第三个ROM搜索过程,在此过程中找到另一个ROM.
  15. 总线主机通过重复步骤13至15开始一次新的ROM搜索。
  16. 总线主机写一个1数据位。这去掉ROM2,仅留下ROM3
  17. 总线主机读出ROM3数据位的剩余部分,而且若有需要就与内部逻辑通信。这样便完成了第4个ROM搜索过程,在这过程中找到了另一个ROM。

存贮器操作命令

在这里插入图片描述
注:

  1. 温度变换需要2秒钟。在接收到温度变换命令之后,如果器件未从VDD引脚取得电源,那么DS1820的I/O引线必须至少保持2秒的高电平以提供变换过程所需的电源。这样,在温度变换命令发出之后,至少在此期间内单线总线上不允许发生任何其他的动作。
  2. 在接收到复制暂存存储器的命令以后,如果器件没有从VDD引脚取得电源,那么DS1820的I/O引脚必须至少维持10ms的高电平,以便提供复制过程中所需的电源。这样,在复制暂存存储器命令发出之后,至少在这一期间之内单线总线上不允许发生任何其他的动作。此命令写至DS1820的暂存存储器,以地址2开始。接着写的两个字节将被保存在暂存存储器地址2和3之间中。发出一个复位便可在任何处终止写操作。

读暫存存储器(Read Scratchpad)[BEh]
       此命令读暂存存储器的内容。读开始于字节0,并继续经过暂存存储器,直至第九个字节(字节8,CRC)被读出为止。如果不是所有位置均可读,那么主机可以在任何时候发出一复位以中止读操作。
复制暫存存储器(Copy Scratchpad)[48h]
       此命令把暂存存储器复制入DS1820的E2E^2E2存储器,把温度触发器字节存贮入非易失性存储器,如果总线主机在此命令之后发出读时间片,那么只要DS1820正忙于把暂存存储器复制入E2E^2E2,它就会在总线上输出"0",当复制过程完成之后,它将反回"1",如果由寄生电源供电,总线主机在发出此命令之后必须能立即强制上拉至少10mS.
温度变换(Convert T)[44h]
       此命令开始温度变换。不需要另外的数据。温度变换将被执行,接着DS1820便保持在空闲状态。如果总线主机在此命令之后发出读时间片,那么只要DS1820正忙于进行温度变换,它将在总线上输出“0",当温度变换完成时,它便返回“1",如果由寄生电源供电,那么总线主机在发出此命令之后必须立即强制上拉至少2秒。
重新调出E2(Recall E2)[B8h]
       此命令把贮存在E2中温度触发器的值重新调至暂存存储器,这种重新调出的操作在对DS1820上电时也自动发生,因此只要器件一接电,暂存存储器内就有有效的数据可供使用。在此命令发出之后,对于所发出的第一个读数据时间片,器件都将输出其忙的标志"0"=忙,“1”=准备就绪。
读电源(Read Power Supply)[B4h]
       对于在此命令送至DS1820之后所发出的第一读出数据的时间片,器件都会给出其电源方式的信号:“0”=寄生电源供电,“1”=外部电源供电。

示例程序

DS18B20.c

#include "DS18B20.h"void delay_10us(uint8_t n);void DS18B20_Delay()
{}void DS18B20_Pin_H()
{DS18B20_Pin = 1;
}void DS18B20_Pin_L()
{DS18B20_Pin = 0;
}uint8_t DS18B20_Pin_Read()
{return DS18B20_Pin;
}/*******************************************************************************
* 函 数 名         : DS18B20_reset
* 函数功能		   : 复位DS18B20
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DS18B20_reset(void)
{DS18B20_Pin_L();	//拉低IOdelay_10us(72);		//480~960usDS18B20_Pin_H();	//释放IO
}/*******************************************************************************
* 函 数 名         : DS18B20_check
* 函数功能		   : 检测DS18B20是否存在
* 输    入         : 无
* 输    出         : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
uint8_t DS18B20_check(void)
{uint8_t time_temp = 0;while (DS18B20_Pin_Read() && time_temp < 6)	//等待DQ为低电平	实测29us{time_temp++;delay_10us(1);}if (time_temp >= 6)return 1;	//如果超时则强制返回1elsetime_temp = 0;while ((!DS18B20_Pin_Read()) && time_temp < 25)	//等待DQ为高电平	实测109us{time_temp++;delay_10us(1);}if (time_temp >= 25)return 1;	//如果超时则强制返回1return 0;
}/*******************************************************************************
* 函 数 名         : DS18B20_read_bit
* 函数功能		   : 从DS18B20读取一个位
* 输    入         : 无
* 输    出         : 1/0
*******************************************************************************/
uint8_t DS18B20_read_bit(void)
{uint8_t dat = 0;DS18B20_Pin_L();DS18B20_Delay();DS18B20_Pin_H();delay_10us(1);if (DS18B20_Pin_Read())dat = 1;	//如果总线上为1则数据dat为1,否则为0else dat = 0;delay_10us(5);return dat;
}/*******************************************************************************
* 函 数 名         : DS18B20_read_byte
* 函数功能		   : 从DS18B20读取一个字节
* 输    入         : 无
* 输    出         : 一个字节数据
*******************************************************************************/
uint8_t DS18B20_read_byte(void)
{uint8_t i = 0;uint8_t dat = 0;uint8_t temp = 0;for (i = 0; i<8; i++)//循环8次,每次读取一位,且先读低位再读高位{temp = DS18B20_read_bit();dat = (temp << 7) | (dat >> 1);}return dat;
}/*******************************************************************************
* 函 数 名         : DS18B20_write_bit
* 函数功能		   : 写一个位到DS18B20
* 输    入         : dat:要写入的位
* 输    出         : 无
*******************************************************************************/
void DS18B20_write_bit(uint8_t Bit)
{if (Bit){DS18B20_Pin_L();DS18B20_Delay();DS18B20_Pin_H();delay_10us(6);}else{DS18B20_Pin_L();delay_10us(6);DS18B20_Pin_H();DS18B20_Delay();}
}/*******************************************************************************
* 函 数 名         : DS18B20_write_byte
* 函数功能		   : 写一个字节到DS18B20
* 输    入         : dat:要写入的字节
* 输    出         : 无
*******************************************************************************/
void DS18B20_write_byte(uint8_t dat)
{uint8_t i = 0;uint8_t temp = 0;for (i = 0; i<8; i++)//循环8次,每次写一位,且先写低位再写高位{temp = dat & 0x01;//选择低位准备写入dat >>= 1;//将次高位移到低位DS18B20_write_bit(temp);}
}/*******************************************************************************
* 函 数 名         : DS18B20_init
* 函数功能		   : 初始化DS18B20的IO口 DQ 同时检测DS的存在
* 输    入         : 无
* 输    出         : 1:不存在,0:存在
*******************************************************************************/
uint8_t DS18B20_init(void)
{DS18B20_reset();return DS18B20_check();
}void DS18B20_Read_ROM(uint8_t * pROM)
{uint8_t i = 0;if(DS18B20_init())return;DS18B20_write_byte(DS18B20_READ_ROM);for(i = 0; i < 8; ++i)*pROM++ = DS18B20_read_byte();
}void DS18B20_Connect(uint8_t * pROM)
{uint8_t i = 0;if(DS18B20_init())return;DS18B20_write_byte(DS18B20_MATCH_ROM);for(i = 0; i < 8; ++i)DS18B20_write_byte(*pROM++);
}float DS18B20_Read_Temperture()
{uint8_t dath = 0;uint8_t datl = 0;uint16_t value = 0;DS18B20_write_byte(DS18B20_Read_Scratchpad);//读存储器datl = DS18B20_read_byte();//低字节dath = DS18B20_read_byte();//高字节value = (dath << 8) + datl;//合并为16位数据if ((value & 0xf800) == 0xf800)//判断符号位,负温度{value = (~value) + 1; //数据取反再加1return value*(-0.0625);//乘以精度	}else //正温度return value*0.0625;
}void DS18B20_Single(void)
{if(DS18B20_init())return;DS18B20_write_byte(DS18B20_SKIP_ROM);//SKIP ROM
}

DS18B20.h

#ifndef _DS18B20_H
#define _DS18B20_H#include <STC89C5xRC.H>
#include "stdint.h"//管脚定义
sbit DS18B20_Pin=P3^7;	//DS18B20数据口定义//ROM 操作命令
#define DS18B20_READ_ROM	0x33
#define DS18B20_MATCH_ROM	0x55
#define DS18B20_SKIP_ROM	0xcc
#define DS18B20_SEARCH_ROM	0xf0
#define DS18B20_ALARM_ROM	0xec//DS1820 命令集
#define DS18B20_Read_Scratchpad		0xbe
#define DS18B20_Write_Scratchpad	0x4e
#define DS18B20_Copy_Scratchpad		0x48
#define DS18B20_Convert_T			0x44
#define DS18B20_Recall_E2			0xB8
#define DS18B20_Read_Power_Supply	0xB4uint8_t DS18B20_init(void);//函数声明
void DS18B20_write_byte(uint8_t dat);
uint8_t DS18B20_read_bit(void);
void DS18B20_write_bit(uint8_t Bit);
void DS18B20_Read_ROM(uint8_t * pROM);
void DS18B20_Single(void);
void DS18B20_Connect(uint8_t * pROM);
float DS18B20_Read_Temperture();#endif

测试程序

       stdint.h见【51单片机快速入门指南】1:基础知识和工程创建
       串口部分见【51单片机快速入门指南】3.3:USART 串口通信
       定时器的介绍和配置源码见【51单片机快速入门指南】3.2:定时器/计数器

定时器中断服务函数

void TIM0_Callback() interrupt 1 //定时器0中断函数
{ extern uint8_t TIM0_Counter;--TIM0_Counter;
}

单传感器时ID的获取 main.c

#include <STC89C5xRC.H>
#include "intrins.h"
#include "stdint.h"
#include "TIM.h"
#include "USART.h"
#include "DS18B20.h"void Delay1ms()		//@22.1184MHz
{unsigned char i, j;_nop_();i = 4;j = 146;do{while (--j);} while (--i);
}void delay_ms(uint8_t ms)
{while(ms --)Delay1ms();
}uint8_t TIM0_Counter = 0;
void delay_10us(uint8_t n)
{TL0 = TH0;TIM0_Counter = n;while(TIM0_Counter > 1);
}uint8_t DS18B20_0[8];
code uint8_t DS18B20_1[8] = {0x28, 0x38, 0x66, 0x16, 0xa8, 0x01, 0x3c, 0xe4};void main(void)
{uint8_t i;Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400, 10, STC_TIM_Priority_Highest);	//定时器配置为10us中断一次,8位重装载USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 22118400, 115200, DOUBLE_BAUD_DISABLE, USART_TIMER_2);DS18B20_Read_ROM(&DS18B20_0);while(1){		for(i = 0; i < 7; ++i)printf("0x%x, ", (int16_t)DS18B20_0[i]);printf("0x%x\r\n", (int16_t)DS18B20_0[i]);delay_ms(100);}	
}

在这里插入图片描述

单传感器读取温度和读取特定ID传感器的温度

code uint8_t DS18B20_0[8] = {0x28, 0x38, 0x66, 0x16, 0xa8, 0x01, 0x3c, 0xe4};void main(void)
{Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400, 10, STC_TIM_Priority_Highest);	//定时器配置为10us中断一次,8位重装载USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 22118400, 115200, DOUBLE_BAUD_DISABLE, USART_TIMER_2);while(1){		DS18B20_Single();						DS18B20_write_byte(DS18B20_Convert_T);	//转换命令	DS18B20_Single();printf("%f, ", DS18B20_Read_Temperture());DS18B20_Connect(&DS18B20_0);DS18B20_write_byte(DS18B20_Convert_T);	//转换命令DS18B20_Connect(&DS18B20_0);printf("%f\r\n", DS18B20_Read_Temperture());delay_ms(100);}	
}

在这里插入图片描述

多路传感器读取

code uint8_t DS18B20_0[8] = {0x28, 0x30, 0xc5, 0xb8, 0x0, 0x0, 0x0, 0x8e};
code uint8_t DS18B20_1[8] = {0x28, 0x38, 0x66, 0x16, 0x0, 0x0, 0x0, 0xee};void main(void)
{Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400, 10, STC_TIM_Priority_Highest);	//定时器配置为10us中断一次,8位重装载USART_Init(USART_MODE_1, Rx_ENABLE, STC_USART_Priority_Lowest, 22118400, 57600, DOUBLE_BAUD_DISABLE, USART_TIMER_1);DS18B20_Read_ROM(&DS18B20_1);while(1){		DS18B20_Connect(&DS18B20_0);DS18B20_write_byte(DS18B20_Convert_T);	//转换命令DS18B20_Connect(&DS18B20_0);printf("%f, ", DS18B20_Read_Temperture());DS18B20_Connect(&DS18B20_1);DS18B20_write_byte(DS18B20_Convert_T);	//转换命令DS18B20_Connect(&DS18B20_1);printf("%f\r\n", DS18B20_Read_Temperture());delay_ms(100);}	
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL多行转多列

--★转换结果如上图 1、首先创建表&#xff1a; CREATE TABLE [成绩表]( [编号] [int]IDENTITY(1,1) NOT NULL, [姓名] [varchar](50)NULL, [语文] [numeric](5, 2)NULL, [数学] [numeric](5, 2)NULL, [英语] [numeric](5, 2)NULL ) ON [PRIMARY] 2、插入测试数据 INSERT INTO …

C#通过FFmpeg获得视频文件参数

C#通过FFmpeg获得视频参数 FFmpeg简介 FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video&#xff08;录制、转换 、音/视频&#xff0c;并可将其转换为音/视频流的完整的&#xff0c;跨平台的j解决方案&#xff09;.FFmpeg的开发…

【51单片机快速入门指南】6.3.1:使用1-WIRE搜索算法搜索单总线上所有DS18B20的ID(基于二叉树)

目录源码OWSearch.c测试程序实验现象Proteus仿真实机测试普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 移植自1-WIRE搜索算法 串口部分见【51单片机快速入门指南】3.3&#xff1a;USART 串口通信 DS18B20驱动程序见【5…

卡拉丁发布第四代车用空调滤清器

5月15日&#xff0c;卡拉丁“全澄行动”第四代车用空调滤清器产品发布会在京举行&#xff0c;据悉&#xff0c;该车用空调滤清器PM2.5过滤效率可高达99%。经国家权威检测机构广东省微生物分析检测中心检测&#xff0c;卡拉丁第四代车用空调滤清器对大肠杆菌、金***葡萄球菌抗菌…

【 Grey Hack 】大数四则运算

目录效果加减乘除乘方源码版本&#xff1a;Grey Hack v0.7.3619 - Alpha 在Gs中&#xff0c;位数大于15的整数将以科学计数法显示&#xff0c;故这里提供一种基于字符串加法的四则大数运算算法。由于位数大于10的字符串无法用to_int方法转化为整数&#xff0c;因此本示例中以长…

uniapp打包小程序上传测试后,使用有的插件显示空白页面,问题解决方【有效 / 最新】

目录 问题1图在微信开发者平台正常能使用 打包上传微信小程序测试问题2图在微信开发者平台正常能使用 打包上传微信小程序测试解决步骤一1.2.3. 解决步骤二打开微信小程序官网看图跨域网址 最后 问题1图 在微信开发者平台正常能使用 未上传小程序&#xff0c;开发过程中&…

django加载本地html

django加载本地html from django.shortcuts import renderfrom django.http import HttpResponse from django.shortcuts import render,render_to_response # Create your views here. def hello(request): return render_to_response("hello.html") 传递数据到htm…

Java知多少(68)面向字符的输出流

面向字符的输出流都是类 Writer 的子类&#xff0c;其类层次结构如图 10-5 所示。 图10-5 Writer的类层次结构图表 10-3 列出了 Writer 的主要子类及说明。 表 10-3 Writer 的主要子类类名功能说明CharArrayWriter写到字符数组的输出流BufferedWriter缓冲输出字符流PipedWriter…

Linux虚拟机的替代品:Docker与WSL2上手笔记

目录安装Docker可能出现的问题内核需更新Linux 内核更新包将 WSL 2 设置为默认版本An error occurred安装镜像使用Microsoft Store安装所选的 Linux 分发手动安装镜像及文件夹的共享Docker run 命令Windows Terminal的安装在Windows Terminal中直接运行已有的容器Windows 10 20…

flask需求文件requirements.txt的创建及使用

1.简介 Python项目中必须包含一个 requirements.txt 文件&#xff0c;用于记录所有依赖包及其精确的版本号用以新环境部署。 2.进入虚拟环境然后输入pip freeze > requirements.txt 每次安装或者升级了包之后最好也一并使用这个命令更新这个文件。 需求文件的内容示例…

【联盛德W806上手笔记】一、开发环境和烧录程序

目录简介芯片外观MCU 特性安全特性低功耗模式芯片结构管脚定义极限参数开发环境SDK的获取从官网获取从Q群获取iosetting大佬 维护的wm-sdk-w806打开工程编译固件烧录现象Windows 10 20H2 HLK-W806-V1.0-KIT WM_SDK_W806_v0.6.0 引自《W80X_MCU_快速入门V0.2》、《W806 MCU 芯片…

Mac os + Flask + PyCharm python开发环境集成

1. 打开mac自带终端安装virtualenv 执行 sudo easy_install virtualenv / sudo pip install virtualenv 2.安装完 virtualenv &#xff0c;打开一个 shell &#xff0c;创建自己的环境。 $ mkdir myapp $ cd myapp $ virtualenv venv New python executable in env/bin/py…

zookeeper注意几点

为什么80%的码农都做不了架构师&#xff1f;>>> Zookeeper 作为一个分布式的服务框架&#xff0c;主要用来解决分布式集群中应用系统的一致性问题&#xff0c;它能提供基于类似于文件系统的目录节点树方式的数据存储&#xff0c;但是 Zookeeper 并不是用来专门存储…

【51单片机快速入门指南】7:片上EEPROM

目录硬知识IAP及EEPROM新增特殊功能寄存器介绍EEPROM空间大小及地址小常识大建议常见问题示例程序EEPROM.cEEPROM.h测试程序main.c普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《STC89C52系列单片机器件手册》 ST…

wndows系统命令总结

window8系统下 打开运行窗口----------鼠标放到任务栏的windows图标下&#xff0c;右击&#xff0c;弹出菜单中如上图或者 打开运行窗口---------按“WINR”键&#xff0c; cmd-------打开命令窗口 services.msc--------打开服务命令 calc-----------启动计算器 dvdplay-------…

【RK3399Pro学习笔记】三、Debian 9 安装 ROS (Thinker Edge R)

目录配置源设置 Key安装初始化rosdep环境配置测试安装rosinstall卸载平台&#xff1a;华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本&#xff1a;Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 参考资料&#xff1a; RK3399(Debian9 - stretch) 安装 ROS Lunar —— WB893…

perl学习(二)

2019独角兽企业重金招聘Python工程师标准>>> 在perl中又两个必须搞清楚&#xff0c;就是标量值和标量变量&#xff0c;列表和数组。 直接量就是数值在perl程序代码中的表现方式&#xff0c;就是直接写在程序里的数据&#xff0c;是标量值。如12&a…

【RK3399Pro学习笔记】四、ROS 创建工作空间与功能包

目录创建工作空间编译工作空间功能包创建功能包编译功能包设置环境变量检查环境变量平台&#xff1a;华硕 Thinker Edge R 瑞芯微 RK3399Pro 固件版本&#xff1a;Tinker_Edge_R-Debian-Stretch-V1.0.4-20200615 记录自【古月居】古月ROS入门21讲 | 一学就会的ROS机器人入门教…

hip-hop初探

啥都不说了&#xff0c;上两张图片先 1、使用hiphop的 2、不使用这玩意的 都是前端部署nginx&#xff0c;转发的后面php的 hhvm的配置文件 /etc/hhvm.hdf 目前结论&#xff1a;facebook的这玩意可能适用于facebook业务&#xff0c;对于我的业务来说反而拖后腿转载于:https://ww…

表达式求值(二叉树方法/C++语言描述)(二)

表达式二叉树节点的数据可能是运算数或运算符&#xff0c;可以使用一个联合体进行存储&#xff1b;同时还需要一个变量来指示存储的是运算数还是运算符&#xff0c;可以采用和栈方法求值中一样的枚举类型TokenType&#xff1a; 1 typedef enum2 {3 BEGIN,4 NUMBER,5 …