当前位置:首页 > Betone

基于FPGA的DS18B20数字温度传感器测温实例

來源:Betone    發佈時間:2024-04-04 02:29:13

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


產品詳情

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

  温度传感器(temperature transducer)是指能感受温度并转换成可用输出信号的传感器, 是各种传感器中最常用的一种。随着现代仪器的发展,微型化、集成化、数字化正成为传感器发展的一个重要方向。美国DALLAS半导体公司推出的数字化温度传 感器DS18B20采用单总线协议,即与FPGA接口仅需占用一个I/O端口,无须任何外部元件,直接 将环境温度转化成数字信号,以数字码方式串行输出,从而大大简化了传感器与FPGA的接口设计。引脚如下图:

  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 位作 为内部使用而保留使用,不可被写入。转换时间与位数关系如下表所示:

  如何操作 DS18B20 去进行对温度的转换以及读取呢?步骤如下:1. 初始化1-Wire 总线上的所有事件都必须以初始化为开始。初始化序列由总线上的主设备发出的复位脉冲以及紧跟着从设备回应的存在脉冲构成。该存在脉冲是让总线 在总线上并准备好运行。所有具体时序都在1.4章节介绍。

  当初始化完成之后,就可以执行 ROM 命令。这些命令是对每个设备的 64 位 ROM 编 码进行操作的,当总线上连接有多个设备时,可以通过这些命令识别各个设备。总共包含 有 5 种 ROM 命令,每个命令的长度都是 8bit。搜索 ROM[F0h]:当系统上电初始化后,主设备可识别该总线上所有的从设备的 ROM 编码,这样就可以使得主设备确定总线上的从设备的类型以及数量。读 ROM[33h] :该命令允许主设备读取 DS18B20 的 64 位 ROM 编码,只有在总线 时才能使用这个命令。如果总线上存在多个从设备,发送此命令,则当所有从设 备都会回应时,将会引起数据冲突。匹配 ROM[55h] :该匹配 ROM 命令之后接着发出 64 位 ROM 编码,使主设备在多点总线上定位一只特定的 DS18B20。只有和 64 位 ROM 序列完全匹配的 DS18B20 才会做出响应。总线上的其 他从设备都将等待下一个复位脉冲。此命令在总线上有单个或多个器件时都可以使用。跳过 ROM[CCh] :这条命令可以不用提供 64 位 ROM 编码就进行下一步操作,在单点总线 传感器)情况下可以节省时间。如果总线上不止一个从设备,在跳过 ROM 命令 之后跟着发一条读命令,则所有从设备将会同时执行温度转换,总线上就会发生数据冲突。警报搜索[ECh] :该命令的操作与跳过 ROM 命令基本相同,但是不同的是只有温度高于 TH 或低于 TL (达到报警条件)的从设备才会响应。只要不掉电,警报状态将一直保持,直到温度不在警报范围内为止。

  当总线上的主设备通过 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”,如果拷贝结束的线”。如果设备采用“寄生电源”供电模 式,则在该命令发送后,必须立即强制拉高总线ms。召回 EEPROM[B8h] :该命令将温度报警触发值(TH 和 TL)及配置寄存器的数据从 EEPROM 中召回至高速 缓存器中。这个操作会在上电后自动执行一次,所以在上电期间暂存器中一直会存在有效 的数据。若在召回命令之后启动读时隙,若 DS18B20 正在进行召回 EEPROM 则会响应 “0”,若召回完成则响应“1”。读取供电模式[B4h] :该命令可以读取总线 是否是由“寄生电源”供电。在读取数据时序中 “0”表示“寄生电源供”模式供电,“1”表示外部电源供电。

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

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

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

  WR_CMD:在这个状态一起发送跳过ROM和温度转换指令。使用一个计数器计时,使用另一个计数器则对发送的数据个数计数,当成功发送16个数据后,发送命令完成WAIT:这个状态为延时状态,满足发送温度转换指令后的等待时间750ms。使用一个计数器计时,时间满足750ms则说明计时完成。

  RD_CMD:在这个状态一起发送跳过ROM和读取温度指令。使用一个计数器计时,使用另一个计数器则对发送的数据个数计数,当成功发送16个数据后,发送命令完成RD_DATA:在这个状态读取从机返回的16位温度数据。使用一个计数器计时,使用另一个计数器则对读取的数据个数计数,使用一个寄存器寄存读取到的温度数据,当成功读取16个数据后,接收命令完成需要注意:信号线dq是一个双向信号,所以使用时要用使用三态门的方法来操作,具体方法参考:如何规范地使用双向(inout)信号?2.3、Verilog代码

  2.4、调试 因为通讯过程涉及到从机的响应,我又找不到相应的器件模型,仿真就不搞了。 直接使用signaltap抓下波形: 上图中: 状态机开始运行,进入INTI1的初始化状态 dht11_en拉高同时dht11_out为0,说明主机拉低了总线us处释放了总线,总线us处总线us从机才释放了总线,说明从机发送了响应 在570us处因为总线被从机拉低,所以拉高了响应信号flag_ack,直到进入下个状态才将flag_ack拉低 上图中: 状态机从INTI1的初始化状态跳转到写入ROM和温度转换命令的状态WR_CMD bit_cnt从0计数到F,说明写入了16个数据;与此同时,总线” 上图中: 状态机从WAIT状态跳转到初始化状态INIT2 cnt_us计数器从780000清零,说明此时延时了780ms的时间以便完成温度转换 上图中: 状态机从状态RD_CMD跳转到数据读取状态RD_DATA bit_cnt从0计数到F,说明读取了16个数据;与此同时,总线” 上图中: data是直接从DS18B20温度寄存器中读取的数据1 temp_data是处理后发送给数码管显示的数据3156,对应摄氏度31.56 3、上板调试 添加数码管显示模块,编译工程,板卡显示如下: 和用调试软件抓取的结果一致。 4、参考 DS18B20—DalasSemiconductor FPGAVerilog开发实战指南—基于IntelCycloneIV—野火电子