1、DS18B20数字温度传感器

本文将使用三段式状态机(Moore型)的写法来对DS18B20进行测温操作,以便了解DS18B20和熟悉三段式状态机的写法。

1.1、概述

温度传感器(temperature transducer)是指能感受温度并转换成可用输出信号的传感器, 是各种传感器中最常用的一种。随着现代仪器的发展,微型化、集成化、数字化正成为传感器发展的一个重要方向。

美国DALLAS半导体公司推出的数字化温度传 感器DS18B20采用单总线协议,即与FPGA接口仅需占用一个I/O端口,无须任何外部元件,直接 将环境温度转化成数字信号,以数字码方式串行输出,从而大大简化了传感器与FPGA的接口设计。

引脚如下图:

1.2、结构组成

DS18B20测量温度范围为-55~+125℃,精度为±0.5℃。现场(实时)温度直接以“单总线” 的数字方式传输,大大提高了系统的抗干扰性。它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~l2位的数字值读数方式。它工作在3~5.5V的电压范围,采用多种封装形式,从而使系统设计灵活、方便,设定分辨率及用户设定的报警温度存储在EEPROM中,掉电后 依然保存。其内部结构如图:

高速缓存器的结构框图如下:

由上图可知DS18B20的高速缓存器共有9个8位寄存器,其中温度数据低位(LSB)对应字节 地址0,温度数据高位(MSB)对应字节地址1,以此类推,配置寄存器的字节地址为4。温度数据存放的格式如下图:

DS18B20在出厂时默认配置温度数据为12位,其中最高位为符号位,即温度值共11位,最低四位为小数位。FPGA在读取温度数据时,一次会读2字节共16位,读完后将低11位的二进制 数转化为十进制数后再乘以0.0625得到所测的实际温度值。

另外还需要判断温度的正负,前5 个数字为符号位,这5位同时变化,我们只需要判断其中任何一位就可以了。前5位为1时,读 取的温度为负值,则测到的数值需要取反加1再乘以0.0625才可得到实际温度值。前5位为0时, 读取的温度为正值,只要将测得的数值乘以0.0625即可得到实际温度值。

高速缓存器中第四个字节即为配置寄存器,用户通过改变 R1 和 R0 的值来配置 DS18B20 的分辨率,上电默认为 R1=1 以及 R0=1(12 位分辨率)。需要注意的是转换时间与分辨率时间是有关系的。另外寄存器中最高位和低 5 位作 为内部使用而保留使用,不可被写入。转换时间与位数关系如下表所示:

1.3、通讯步骤

如何操作 DS18B20 去进行对温度的转换以及读取呢?步骤如下:

1. 初始化

1-Wire 总线上的所有事件都必须以初始化为开始。初始化序列由总线上的主设备发出的复位脉冲以及紧跟着从设备回应的存在脉冲构成。该存在脉冲是让总线主设备知道 DS18B20 在总线上并准备好运行。所有具体时序都在1.4章节介绍。

2. ROM命令

当初始化完成之后,就可以执行 ROM 命令。这些命令是对每个设备的 64 位 ROM 编 码进行操作的,当总线上连接有多个设备时,可以通过这些命令识别各个设备。总共包含 有 5 种 ROM 命令,每个命令的长度都是 8bit。

搜索 ROM[F0h]:当系统上电初始化后,主设备可识别该总线上所有的从设备的 ROM 编码,这样就可以使得主设备确定总线上的从设备的类型以及数量。

读 ROM[33h] :该命令允许主设备读取 DS18B20 的 64 位 ROM 编码,只有在总线上只有一个 DS18B20 时才能使用这个命令。如果总线上存在多个从设备,发送此命令,则当所有从设 备都会回应时,将会引起数据冲突。

匹配 ROM[55h] :该匹配 ROM 命令之后接着发出 64 位 ROM 编码,使主设备在多点总线上定位一只特定的 DS18B20。只有和 64 位 ROM 序列完全匹配的 DS18B20 才会做出响应。总线上的其 他从设备都将等待下一个复位脉冲。此命令在总线上有单个或多个器件时都可以使用。

跳过 ROM[CCh] :这条命令可以不用提供 64 位 ROM 编码就进行下一步操作,在单点总线(一个 DS18B20 传感器)情况下可以节省时间。如果总线上不止一个从设备,在跳过 ROM 命令 之后跟着发一条读命令,则所有从设备将会同时执行温度转换,总线上就会发生数据冲突。

警报搜索[ECh] :该命令的操作与跳过 ROM 命令基本相同,但是不同的是只有温度高于 TH 或低于 TL (达到报警条件)的从设备才会响应。只要不掉电,警报状态将一直保持,直到温度不在警报范围内为止。

3. 功能命令

当总线上的主设备通过 ROM 命令确定了哪个 DS18B20 可以进行通信时,主设备就可 以向其中一个从设备发送功能命令。这些命令可以使得主设备操控从设备进行一系列的操作。

温度转换[44h]: 此命令为初始化单次温度转换,温度转换完后,转换的温度数据会寄存在高速缓存器 的 byte0(温度数据低八位)和 byte1(温度数据高八位)中,之后 DS18B20 恢复到低功耗 的闲置状态。如果总线在该命令后发出读时隙,若 DS18B20 正在进行温度转换则会响应 “0”,若完成了温度转换则响应“1”。如果是用的“寄生电源”供电模式,则在命令发 出后应立即强制拉高总线,拉高时间应大于时序要求。

写入暂存器[4Eh] :该命令使得主设备向高速缓存器写入 3 个字节的数据。第一个字节写入高速缓存器的 byte2 中(TH 寄存器),第二个字节的数据写入 byte3 中(TL 寄存器),第三个字节的数据写入 byte4 中(配置寄存器)。所有的数据都是由低位到高位的顺序写入。复位可随时中断写入。

读取高速缓存器[BEh] :读取高速缓存器里的值,从 byte0(温度低八位)开始一直读到 byte8(CRC 校验),每个字节的数据从低位开始传送。若是不想读取这么多数据则在读取数据时随时可以通过复位来终止。

复制高速缓存器[48h] :该命令是将高速缓存器中的 TH(byte2)、TL(byte3)以及配置寄存器(byte4)里的 值拷贝到非易失性的存储器 EEPROM 里。如果总线控制器在这条命令之后跟着发出读时 隙,而 DS18B20 又正在忙于把暂存器拷贝到 EEPROM 存储器,DS18B20 就会输出一个 “0”,如果拷贝结束的话,DS18B20 则输出“1”。如果设备采用“寄生电源”供电模 式,则在该命令发送后,必须立即强制拉高总线至少 10ms。

召回 EEPROM[B8h] :该命令将温度报警触发值(TH 和 TL)及配置寄存器的数据从 EEPROM 中召回至高速 缓存器中。这个操作会在上电后自动执行一次,所以在上电期间暂存器中一直会存在有效 的数据。若在召回命令之后启动读时隙,若 DS18B20 正在进行召回 EEPROM 则会响应 “0”,若召回完成则响应“1”。

读取供电模式[B4h] :该命令可以读取总线上的 DS18B20 是否是由“寄生电源”供电。在读取数据时序中 “0”表示“寄生电源供”模式供电,“1”表示外部电源供电。

1.4、总线时序

初始化—复位和存在脉冲

与 DS18B20 所有的通信都是由初始化开始的,初始化由主设备发出的复位脉冲及 DS18B20 响应的存在脉冲组成。如下图 所示。当 DS18B20 响应复位信号的存在脉冲 后,则其向主设备表明其在该总线上,并且已经做好了执行命令的准备。 在初始化状态,总线上的主设备通过拉低 1-Wire 总线最少 480us 来表示发送复位脉 冲。发送完之后,主设备要释放总线进入接收模式。当总线释放后,上拉电阻将 1- Wire 总线拉至高电平。当 DS18B20 检测到该上升沿信号后,其等待 15us 至 60us 后将总线 拉低 60us 至 240us 来实现发送一个存在脉冲。

写时隙

主设备通过写时隙将命令写入 DS18B20 中,写时隙有两种情况:写“1”和写“0”时 隙。主设备通过写 1 时隙来向 DS18B20 中写入逻辑 1,通过写 0 时隙来向 DS18B20 中写入 逻辑 0。当主设备将总线从高电平拉至低电平时,启动写时隙,所有的写时隙持续时间最 少为 60us,每个写时隙间的恢复时间最少为 1us。 当总线(DQ)拉低后,DS18B20 在 15us 至 60us 之间对总线进行采样,如果采的 DQ 为高电平则发生写 1,如果为低电平则发生写 0,如下图所示(图中的总线控制器即为主设备)。 如果要产生写 1 时隙,必须先将总线拉至逻辑低电平然后释放总线,允许总线在写 隙开始后 15us 内上拉至高电平。若要产生写 0 时隙,必须将总线拉至逻辑低电平并保持不 变最少 60us。

读时隙

当我们发送完读取供电模式[B4h]或读高速缓存器[BEh]命令时,必须及时地生成读时隙,只有在读时隙 DS18B20 才能向主设备传送数据。每个读时隙最小必须有 60us 的持续 时间以及每个读时隙间至少要有 1us 的恢复时间。当主设备将总线从高电平拉至低电平超 过 1us,启动读时隙,如下图所示。当启动读时隙后,DS18B20 将会向主设备发送“0”或者“1”。DS18B20 通过将总线 拉高来发送 1,将总线拉低来发送 0 。当读时隙完成后,DQ 引脚将通过上拉电阻将总线拉高至高电平的闲置状态。从 DS18B20 中输出的数据在启动读时隙后的 15us 内有效,所以,主设备在读时隙开始后的 15us 内必须释放总线,并且对总线进行采样。

2、采用三段式状态机测试

接下来将采用三段式状态机对DS18B20进行测温操作。

2.1、整体设计

因为本文只写DS18B20的驱动,不涉及到其他模块(如数码管),所以模块框图如下:

信号说明如下:

  • sys_clk:系统时钟,50M
  • rst_n:低电平有效的复位信号
  • dq:单总线(双向信号)
  • temp_data:输出的有效数据,位宽20
  • sign:输出给数码管的正负信号,1表示数据为负数;0表示数据为正数

根据上面对DS18B20的介绍,可以概括出整个的测温流程如下:

2.2、状态机设计

三段式状态机的概念可以参考:状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)

当知道了 DS18B20 的控制流程之后,我们可以借助状态机来进一步了解它是如何跳转的:

下面对各状态说明:

INIT1:每次操作前都需要进行初始化操作。在这个状态主机会使用一个计数器从0计数到1000us。一开始就先拉低总线500us,然后释放总线;在570us处采集总线电平,若为0,则说明总线进行了响应,初始化完成。

WR_CMD:在这个状态一起发送跳过ROM和温度转换指令。使用一个计数器计时,使用另一个计数器则对发送的数据个数计数,当成功发送16个数据后,发送命令完成

WAIT:这个状态为延时状态,满足发送温度转换指令后的等待时间750ms。使用一个计数器计时,时间满足750ms则说明计时完成。

        INIT2:第二次操作前的初始化操作。所有操作同INIT1,不赘述。

        RD_CMD:在这个状态一起发送跳过ROM和读取温度指令。使用一个计数器计时,使用另一个计数器则对发送的数据个数计数,当成功发送16个数据后,发送命令完成

        RD_DATA:在这个状态读取从机返回的16位温度数据。使用一个计数器计时,使用另一个计数器则对读取的数据个数计数,使用一个寄存器寄存读取到的温度数据,当成功读取16个数据后,接收命令完成

需要注意:信号线dq是一个双向信号,所以使用时要用使用三态门的方法来操作,具体方法参考:如何规范地使用双向(inout)信号?

2.3、Verilog代码

根据上面的状态分析图,编写Verilog代码如下:(这里就不写分析了,注释已经写得很详细了,如果你看到了这边文章且这段代码又不懂的地方,可以评论给我)

//==================================================================
//--3段式状态机(Moore)实现的DS18B20驱动
//==================================================================//------------<模块及端口声明>----------------------------------------
module ds18b20_dri(input                clk         ,       //系统时钟,50Minput              rst_n       ,       //低电平有效的复位信号    inout               dq          ,       //单总线(双向信号)output reg [19:0]   temp_data      ,       // 转换后得到的温度值output reg          sign                // 符号位
);//------------<参数定义>----------------------------------------------
//状态机状态定义
localparam  INIT1       = 6'b000001 ,WR_CMD      = 6'b000010 ,WAIT          = 6'b000100 ,INIT2        = 6'b001000 ,RD_CMD   = 6'b010000 ,RD_DATA      = 6'b100000 ;//时间参数定义
localparam  T_INIT = 1000      ,           //初始化最大时间,单位usT_WAIT = 780_000  ;           //转换等待延时,单位us//命令定义
localparam  WR_CMD_DATA = 16'h44cc,       //跳过 ROM 及温度转换命令,低位在前RD_CMD_DATA = 16'hbecc;       //跳过 ROM 及读取温度命令,低位在前//------------<reg定义>----------------------------------------------
reg [5:0]   cur_state   ;                   //现态
reg [5:0]   next_state  ;                   //次态
reg [4:0]   cnt         ;                   //50分频计数器,1Mhz(1us)
reg         dq_out      ;                   //双向总线输出
reg         dq_en       ;                   //双向总线输出使能,1则输出,0则高阻态
reg         flag_ack    ;                   //从机响应标志信号
reg         clk_us      ;                   //us时钟
reg [19:0]  cnt_us      ;                   //us计数器,最大可表示1048ms
reg [3:0]   bit_cnt     ;                   //接收数据计数器
reg [15:0]  data_temp   ;                   //读取的温度数据寄存
reg [15:0]  data        ;                   //未处理的原始温度数据//------------<wire定义>----------------------------------------------
wire        dq_in       ;                   //双向总线输入//==================================================================
//===========================<main  code>===========================
//==================================================================//-----------------------------------------------------------------------
//--双向端口使用方式
//-----------------------------------------------------------------------
assign  dq_in = dq;                            //高阻态的话,则把总线上的数据赋给dq_in
assign  dq =  dq_en ? dq_out : 1'bz;      //使能1则输出,0则高阻态//-----------------------------------------------------------------------
//--us时钟生成,因为时序都是以us为单位,所以生成一个1us的时钟会比较方便
//-----------------------------------------------------------------------
//50分频计数
always @(posedge clk or negedge rst_n)beginif(!rst_n)cnt <= 5'd0;else if(cnt == 5'd24)                 //每25个时钟500ns清零cnt <= 5'd0;elsecnt <= cnt + 1'd1;
end
//生成1us时钟
always @(posedge clk or negedge rst_n)beginif(!rst_n)clk_us <= 1'b0;else  if(cnt == 5'd24)                 //每500nsclk_us <= ~clk_us;                  //时钟反转elseclk_us <= clk_us;
end//-----------------------------------------------------------------------
//--三段式状态机
//-----------------------------------------------------------------------//状态机第一段:同步时序描述状态转移
always @(posedge clk_us or negedge rst_n)beginif(!rst_n)       cur_state <= INIT1; elsecur_state <= next_state;
end//状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
always @(*)beginnext_state = INIT1;   case(cur_state)INIT1        :beginif(cnt_us == T_INIT && flag_ack)                //满足初始化时间且接收到了从机的响应信号   next_state = WR_CMD;                       //跳转到写状态else    next_state = INIT1;                            //不满足则保持原有状态end WR_CMD       :begin if(bit_cnt == 4'd15 && cnt_us == 20'd62)      //写完了16个数据,写跳过ROM和写温度转换命令    next_state = WAIT;                         //跳转到等待状态,等待温度转换完成 else  next_state = WR_CMD;                       //不满足则保持原有状态end WAIT  :begin    if(cnt_us == T_WAIT)                          //等待时间结束next_state = INIT2;    else    next_state = WAIT; end INIT2  :begin   if(cnt_us == T_INIT && flag_ack)              //再进行初始化,时序同INIT1next_state = RD_CMD;elsenext_state = INIT2;endRD_CMD  :beginif(bit_cnt == 4'd15 && cnt_us == 20'd62)        //写完了16个数据,写跳过ROM和写读取温度转换命令  next_state = RD_DATA;                      //跳转到读取温度数据状态else   next_state = RD_CMD;   end RD_DATA  :begin if(bit_cnt == 4'd15 && cnt_us == 20'd62)      //读取完了16个数据next_state = INIT1;                         //跳转到初始化状态,开始新一轮温度采集else next_state = RD_DATA;  end         default:next_state = INIT1;                            //默认初始化状态endcase
end //状态机第三段:时序逻辑描述输出
always @(posedge clk_us or negedge rst_n)beginif(!rst_n)begin                                          //默认输出dq_en <= 1'b0;dq_out <= 1'b0;flag_ack <= 1'b0;cnt_us <= 20'd0;bit_cnt <= 4'd0;endelse begin  case(cur_state)INIT1    :beginif(cnt_us == T_INIT)begin                   //时间计数到最大值(初始化时间)cnt_us <= 20'd0;                        //计数器清零flag_ack <= 1'b0;                       //从机响应标志信号拉低endelse begin                                   //没有计数到最大值cnt_us <= cnt_us + 1'd1;                //计数器计数if(cnt_us <= 20'd499)begin              //小于500us时dq_en <= 1'b1;                       //控制总线dq_out <= 1'b0;                      //输出0,即拉低总线endelse begin                             //在500us处dq_en <= 1'b0;                        //释放总线,等待从机响应                        if (cnt_us == 20'd570 && !dq_in) //在570us处采集总线电平,如果为0则说明从机响应了flag_ack <= 1'b1;               //拉高从机响应标志信号end endendWR_CMD    :beginif(cnt_us == 20'd62)begin                      //一个写时隙周期63us,满足计时条件则cnt_us <= 20'd0;                           //清空计数器dq_en <= 1'b0;                              //释放总线if(bit_cnt == 4'd15)                       //如果数据已经写了15个bit_cnt <= 4'd0;                      //则清空else                                       //没写15个bit_cnt <= bit_cnt + 1'd1;             //则数据计数器+1,代表写入了一个数据end else begin                                      //一个写时隙周期63us未完成cnt_us <= cnt_us + 1'd1;                  //计数器一直计数if(cnt_us <= 20'd1)begin                  //0~1us(每两个写数据之间需要间隔2us)dq_en <= 1'b1;                           //拉低总线dq_out <= 1'b0;endelse begin                 if (WR_CMD_DATA[bit_cnt] == 1'b0)begin   //需要写入的数据为0dq_en <= 1'b1;                      //拉低总线dq_out <= 1'b0;                      //                              endelse if(WR_CMD_DATA[bit_cnt] == 1'b1)begindq_en <= 1'b0;                     //需要写入的数据为1dq_out <= 1'b0;                     //释放总线                      endend  end     end     WAIT    :begin                                      //等待温度转换完成dq_en <= 1'b1;                                   //拉低总线兼容寄生电源模式dq_out <= 1'b1;                                  if(cnt_us == T_WAIT)                          //计数完成cnt_us <= 20'd0;elsecnt_us <= cnt_us + 1'd1;end    INIT2   :begin                                      //第二次初始化,时序同INIT1if(cnt_us == T_INIT)begin                     cnt_us <= 20'd0;flag_ack <= 1'b0;endelse begincnt_us <= cnt_us + 1'd1;if(cnt_us <= 20'd499)begindq_en <= 1'b1;                        dq_out <= 1'b0;endelse begindq_en <= 1'b0;                                                if (cnt_us == 20'd570 && !dq_in)flag_ack <= 1'b1;end    endend  RD_CMD  :begin                                      //写16个数据,时序同WR_CMDif(cnt_us == 20'd62)begincnt_us <= 20'd0;dq_en <= 1'b0;if(bit_cnt == 4'd15)bit_cnt <= 4'd0;elsebit_cnt <= bit_cnt + 1'd1;endelse begincnt_us <= cnt_us + 1'd1;if(cnt_us <= 20'd1)begindq_en <= 1'b1;                            dq_out <= 1'b0;endelse begin                   if (RD_CMD_DATA[bit_cnt] == 1'b0)begindq_en <= 1'b1;                        dq_out <= 1'b0;                                                        endelse if(RD_CMD_DATA[bit_cnt] == 1'b1)begindq_en <= 1'b0;                     dq_out <= 1'b0;                                                endend  endend  RD_DATA :begin                                      //读16位温度数据if(cnt_us == 20'd62)begin                      //一个读时隙周期63us,满足计时条件则cnt_us <= 20'd0;                           //清空计数器dq_en <= 1'b0;                              //释放总线if(bit_cnt == 4'd15)begin                  //如果数据已经读取了15个bit_cnt <= 4'd0;                     //则清空data <= data_temp;                     //临时的数据赋值给dataendelse begin                                 //如果数据没有读取15个bit_cnt <= bit_cnt + 1'd1;               //则数据计数器+1,意味着读取了一个数据data <= data;endendelse begin                                      //一个读时隙周期还没结束cnt_us <= cnt_us + 1'd1;                 //计数器累加if(cnt_us <= 20'd1)begin                    //0~1us(每两个读数据之间需要间隔2us)dq_en <= 1'b1;                           //拉低总线dq_out <= 1'b0;endelse begin                                 //2us后dq_en <= 1'b0;                           //释放总掉线                 if (cnt_us == 20'd10)                    //在10us处读取总线电平data_temp <= {dq,data_temp[15:1]};    //读取总线电平end endenddefault:;     endcaseend
end//-----------------------------------------------------------------------
//--12位温度数据处理
//-----------------------------------------------------------------------
always @(posedge clk_us or negedge rst_n)beginif(!rst_n)begin                                                  //初始状态temp_data <= 20'd0;  sign  <= 1'b0; end else begin  if(!data[15])begin                                          //最高位为0则温度为正sign  <= 1'b0;                                         //标志位为正temp_data <= data[10:0] * 11'd625 /7'd100;             //12位温度数据处理end  else if(data[15])begin                                      //最高位为1则温度为负sign  <= 1'b1;                                         //标志位为负temp_data <= (~data[10:0] + 1'b1)* 11'd625 /7'd100;      //12位温度数据处理         endend
endendmodule

2.4、调试

因为通讯过程涉及到从机的响应,我又找不到相应的器件模型,仿真就不搞了。

直接使用signaltap抓下波形:

上图中:

  • 状态机开始运行,进入INTI1的初始化状态
  • dht11_en拉高同时dht11_out为0,说明主机拉低了总线
  • 主机拉低总线后在500us处释放了总线,总线被上拉电阻拉高
  • 在528us处总线被从机拉低,直至637us从机才释放了总线,说明从机发送了响应
  • 在570us处因为总线被从机拉低,所以拉高了响应信号flag_ack,直到进入下个状态才将flag_ack拉低

上图中:

  • 状态机从INTI1的初始化状态跳转到写入ROM和温度转换命令的状态WR_CMD
  • bit_cnt从0计数到F,说明写入了16个数据;与此同时,总线上也在分别写入“0”和“1”

上图中:

  • 状态机从WAIT状态跳转到初始化状态INIT2
  • cnt_us计数器从780000清零,说明此时延时了780ms的时间以便完成温度转换

上图中:

  • 状态机从状态RD_CMD跳转到数据读取状态RD_DATA
  • bit_cnt从0计数到F,说明读取了16个数据;与此同时,总线上也在分别输出“0”和“1”

上图中:

  • data是直接从DS18B20温度寄存器中读取的数据0000000111111001
  • temp_data是处理后发送给数码管显示的数据3156,对应摄氏度31.56

3、上板调试

添加数码管显示模块,编译工程,板卡显示如下:

和用调试软件抓取的结果一致。

4、参考

DS18B20--Dalas Semiconductor

FPGA Verilog 开发实战指南--基于 Intel Cyclone IV--野火电子

基于FPGA的DS18B20数字温度传感器测温实例相关推荐

  1. 基于FPGA的分布式拉曼光纤测温控制系统

    摘要:本文首先对分布式拉曼光纤测温技术的原理进行了简要的介绍,分析了系统的主要结构.在集成的拉曼测温模块的基础上,使用Cyclone IV系列的FPGA作为后端数据采集控制模块的主要控制模块,进行设计 ...

  2. 基于DS18B20数字温度传感器的温度计设计

    基于DS18B20数字温度传感器的温度计设计 本报告为哈尔滨工业大学电子与信息工程学院大二学期微机原理课程的课设报告.请注意,本文所述代码均在Quartus II 13.0程序内使用汇编语言运行. 一 ...

  3. 【正点原子FPGA连载】第二十七章DS18B20数字温度传感器实验 -摘自【正点原子】新起点之FPGA开发指南_V2.1

    1)实验平台:正点原子新起点V2开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=609758951113 2)全套实验源码+手册+视频下载地址:ht ...

  4. Arduino基础篇(七)-- 如何使用DS18B20数字温度传感器(基于OneWire和DallasTemperature库)

    温度传感器是指能感受温度并转换成可用输出信号的传感器.按测量方式分为接触式和非接触式,按照传感器材料及电子元件分为热电阻和热电偶两类,按照工作原理分为模拟式和数字式.本篇主要介绍数字温度传感器 DS1 ...

  5. DS18B20数字温度传感器

    目录 一.基础知识 1.基础介绍: 2.DS18B20特点: 3.单总线时序 4.相关操作时序 5.部分ROM指令 二.相关代码 1. 使用步骤(单点总线情况) 2. 代码展示 数字温度传感器你会用了 ...

  6. 【正点原子STM32连载】第三十九章 DS18B20数字温度传感器实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  7. 【正点原子MP157连载】第二十六章 DS18B20数字温度传感器实验-摘自【正点原子】STM32MP1 M4裸机CubeIDE开发指南

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  8. 基于51单片机的密码锁多路测温+测距+语音播报

    本项目为单片机课程设计成果,实物制作+proteus仿真,相关资料见结尾. 文章目录 前言 一.系统组成 1.1 WT588D语音模块 1.2 JQ8900-TF语音模块 1.3 HC-SR04-P超 ...

  9. 温度传感器的c语言程序,DS18B20数字温度传感器C语言程序实例

    51单片机DS18B20数字温度传感器设计 与C程序 #include #define uchar unsigned char #define uint unsigned int #define DQ ...

  10. DS18B20数字温度传感器及单总线协议规定

    1,DS18B20数字温度传感器的主要特点 通信采用1-Wire接口 每个DS18B20都有唯一的64位序列码储存在板载ROM中 无需外部元件 可从数据线供电,电源范围为3.0V ~ 5.5V. 可测 ...

最新文章

  1. 跟着JAMA论文学习重复测量资料分析方法
  2. IIS 7 及以上 IIS错误页“编辑功能设置...”提示“锁定冲突”
  3. 学习Promise之前你必须理解的知识点:异步处理的通用模型
  4. CoreText使用介绍
  5. DeepMind发布《神经网络中持续学习》Cell综述论文
  6. 电力拖动自动控制系统_系主任带你看专业 | 电气工程及其自动化、电子科学与技术、信息工程、自动化,优质就业、超高考研、竞赛获奖都在这里……...
  7. Flutter 入门安装——C#程序喵的Flutter之旅
  8. SHEditor v0.3 SkinSharp皮肤设计工具
  9. matlab格拉布斯准则程序,基于格拉布斯准则及离群点检测光伏阵列故障检测方法与流程...
  10. 腾讯视频怎么获得html代码,如何获取腾讯视频等九大视频网站的视频分享代码...
  11. c语言dp算法,通过leetcode学算法——动态规划(dp)
  12. 深度学习--Inception-ResNet-v1网络结构
  13. 旺旺打标工具,淘宝搜索打标软件(含旺旺打标API接口)
  14. Simulink学习——弹球仿真三维动画模型(Simulink3D演示动画学习01)
  15. UltraEdit32常用快捷键
  16. 精选20个高品质的免费素材,可以下载PSD格式
  17. 华为AC外置Portal认证方案配置步骤指南
  18. 【CXY】JAVA基础 之 JDBC
  19. 如何破解华为家长防护
  20. Python之建模规划篇--整数规划

热门文章

  1. 【转】灵格斯词霸怎样在 PDF 文档中取词?
  2. 《CSS世界》--张鑫旭 : 前端样式高手进阶CSS
  3. openssl SM2签名密钥生成
  4. 【Unity3D插件】AnyPortrait插件分享《(一)制作史莱姆动画》
  5. 微信小程序 全套 视频 9ph7 教程 全部免费 百度网盘
  6. 华为手机照片 计算机,教你华为手机怎么传照片到电脑上去
  7. oracle数据库脱敏代码
  8. postman并发测试_PostMan接口压力测试
  9. usb转rs485测试软件,usb转rs485
  10. LeaRun低代码开发平台 助推物联网应用快速落地