文章目录
一.传感器介绍
ds18b20是常用的数字温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。
1.特点
ds18b20单线数字温度传感器具有独特的优点:
( 1 )采用单总线的接口方式,与微处理器连接时仅需要一条线即可实现微处理器与DS18B20的双向通讯。单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。
( 2 )测量温度范围宽。测量精度高 DS18B20的测量范围为 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C范围内,精度为 ± 0.5°C 。
( 3 )在使用中不需要任何外围元件。
( 4 )支持多点组网功能。多个 DS18B20 可以并联在唯一的单线上,实现多点测温。
( 5 )供电方式灵活。DS18B20 可以通过内部寄生电路从数据线上获取电源。因此,当数据线上的时序满足一定的要求时,可以不接外部电源,从而使系统结构更趋简单,可靠性更高。
( 6 )测量参数可配置。DS18B20的测量分辨率可通过程序设定 9~12 位。
( 7 ) 负压特性电源极性接反时,温度计不会因发热而烧毁,但不能正常工作。
( 8 )掉电保护功能。DS18B20 内部含有 EEPROM ,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。
2.内部结构
ds18b20内部主要由四部分组成:64位ROM,温度传感器,非挥发的温度报警触发器TH和TL,配置寄存器。
64位ROM
ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。
64位ROM的循环冗余校验码:
ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
3.ds18b20管脚
- GND为电源地;
- DQ为数字信号输入/输出端;
- VDD为外接供电电源输入端(在寄生电源接线方式时接地)
4.ds18b20内部高速暂存存储器
高速暂存存储器由9个字节组成,当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变为原码,再计算十进制值。
说明:
字节0表示温度的低八位数据。
字节1表示温度的高八位数据。
字节2表示高温阀值。
字节3表示低温阀值。
字节4表示配置寄存器。
字节5、字节6、字节7是保留字节。
DS18B20中的温度传感器完成对温度的测量,用16位二进制形式提供,形式表达,其
中S为符号位。
例如:
+125℃的数字输出07D0H。(正温度直接把16进制数转成10进制即得到温度值 )
-55℃的数字输出为 FC90H。(负温度把得到的16进制数取反后加1 再转成10进制数)
5.ds18b20工作时序
初始化时序:
①主机首先发出一个480-960微秒的低电平脉冲,然后释放总线变为高电平,并在随后的480微秒时间内对总线进行检测,如果有低电平出现说明总线上有器件已做出应答。若无低电平出现,一直都是高电平说明总线上无器件应答。
②做为从器件的DS18B20在一上电后就一直在检测总线上是否有480-960微秒的低电平出现,如果有,在总线转为高电平后等待15-60微秒后将总线电平拉低60-240微秒做出响应存在脉冲,告诉主机本器件已做好准备。若没有检测到就一直在检测等待。
写操作:
写周期最少为60微秒,最长不超过120微秒。写周期一开始做为主机先把总线拉低1微秒表示写周期开始。随后若主机想写0,则继续拉低电平最少60微秒直至写周期结束,然后释放总线为高电平。若主机想写1,在一开始拉低总线电平1微秒后就释放总线为高电平,一直到写周期结束。而做为从机的DS18B20则在检测到总线被拉底后等待15微秒然后从15us到45us开始对总线采样,在采样期内总线为高电平则为1,若采样期内总线为低电平则为0。
读操作:
对于读数据操作时序也分为读0时序和读1时序两个过程。读时隙是从主机把单总线拉低之后,在1微秒之后就得释放单总线为高电平,以让DS18B20把数据传输到单总线上。DS18B20在检测到总线被拉低1微秒后,便开始送出数据,若是要送出0就把总线拉为低电平直到读周期结束。若要送出1则释放总线为高电平。主机在一开始拉低总线1微秒后释放总线,然后在包括前面的拉低总线电平1微秒在内的15微秒时间内完成对总线进行采样检测,采样期内总线为低电平则确认为0。采样期内总线为高电平则确认为1。完成一个读时序过程,至少需要60us才能完成。
6.ds18b20单线通信
DS18B20 单线通信功能是分时完成的,他有严格的时隙概念,如果出现序列混乱,1-WIRE 器件将不响应主机,因此读写时序很重要。系统对 DS18B20 的各种操作必须按协议进行。根据 DS18B20 的协议规定,微控制器控制 DS18B20 完成温度的转换必须经过以下 3个步骤 :
(1)每次读写前对 DS18B20 进行复位初始化。复位要求主 CPU 将数据线下拉500us ,然后释放, DS18B20 收到信号后等待 16us-60us 左右,然后发出60us-240us 的存在低脉冲,主 CPU 收到此信号后表示复位成功。
(2)发送一条 ROM 指令
指令名称 | 指令代码 | 指令功能 |
---|---|---|
读ROM | 33H | 读DS18B20ROM中的编码(即读64位地址) |
ROM匹配(符合ROM) | 55H | 发出此命令之后,接着发出64位 ROM编码,访问单总线上与编码相对应DS18820使之作出响应,为下一步对该 DS18B20的读写作准备 |
搜索ROM | 0F0H | 用于确定挂接在同一总线上 DS18B20的个数和识别64位ROM地址,为操作各器件作好准备 |
跳过ROM | 0CCH | 忽略64位ROM地址,直接向DS18B20发温度变换命令,适用于单片机工作 |
警报搜索 | 0ECH | 该指令执行后,只有温度超过设定值上限或下限的片子才做出响应 |
(3)发送存储器指令
指令名称 | 指令代码 | 指令功能 |
---|---|---|
温度变换 | 44H | 启动 DS18B20进行温度转换,转换时间最长为500ms(典型为200ms ),结果存入内部9字节 RAM中 |
读暂存器 | 0BEH | 读内部 RAM中9宇节的内容 |
写暂存器 | 4EH | 发出向内部RAM的第3, 4字节写上,下限温度数据命令,紧跟该命令之后,是传送两字节的数据 |
复制暂存器 | 48H | 将RAM中第3,4字节的内容复制到EEPROM中 |
重调EEPROM | 0B8H | EEPROM中的内容恢复到 RAM中的第3, 4字节 |
读供电方式 | 0B4H | 读DS18B20的供电模式,寄生供电时 DS18B20发送“0”,外接电源供电DS18B20发送“1” |
二.FPGA代码实现
1.状态图
FPGA作为主机,DS18B20作为从机。
①主状态机实现发复位脉冲-接收存在脉冲-发ROM指令-发温度转换指令-延时-温度读取指令-读取温度;
②从状态机负责发送数据或读取数据时序:拉低总线-发送数据/采样数据-释放总线;
主从机状态图:
状态说明:
M_IDLE:空闲状态,等待开始通信;
M_RST:发送复位脉冲;
M_RELE:释放总线;
M_RACK:接收存在脉冲;
M_RSKP:发送跳过ROM指令;
M_SCON:发送温度转换命令;
M_WAIT:等待750ms;
M_SRTM:发送温度读取指令;
M_RTMP:读取温度值;
S_IDLE:空闲状态,等待传输请求;
S_LOW:发数据前先拉低1us;
S_SEND:发送1bit数据;
S_SAMP:接收1bit数据;
S_RELE:释放总线;
S_DONE:发送/接收一次数据完成;
2.代码实现
2.1DS18B20驱动模块
在该模块,主从状态机都是属于FPGA主机部分,主状态机控制整个流程,而从状态机在主状态机的控制下实现相关主机状态下的操作。
module ds18b20_driver(
input clk ,//时钟信号
input rst_n ,//复位信号
input dq_in ,
output reg dq_out ,//dq总线FPGA输出
output reg dq_out_en ,//输出数据有效信号
output reg temp_sign ,//温度值符号位 0:正 1:负
output reg [23:0] temp_out ,//温度输出
output reg temp_out_vld //温度输出有效信号
);
//状态机参数
localparam
//主机状态参数
M_IDLE = 9'b0_0000_0001 ,//空闲状态
M_REST = 9'b0_0000_0010 ,//复位
M_RELE = 9'b0_0000_0100 ,//释放总线 -- ds18b20等待
M_RACK = 9'b0_0000_1000 ,//接收应答 -- 主机接收存在脉冲
M_ROMS = 9'b0_0001_0000 ,//ROM命令 -- 跳过ROM命令
M_CONT = 9'b0_0010_0000 ,//转化
M_WAIT = 9'b0_0100_0000 ,//等待 -- 12bit分辨率下的温度转化时间
M_RCMD = 9'b0_1000_0000 ,//读命令 -- 读暂存器命令
M_RTMP = 9'b1_0000_0000 ,//读温度 -- 产生读时隙 -- 接收2字节带符号位的补码温度
//从机状态参数
S_IDLE = 6'b00_0001 ,//空闲状态
S_LOW = 6'b00_0010 ,//拉低总线 -- 时隙的开始
S_SEND = 6'b00_0100 ,//发送 -- 15us内
S_SAMP = 6'b00_1000 ,//采样 -- 在15us内
S_RELE = 6'b01_0000 ,//释放 -- 时隙的恢复时间
S_DONE = 6'b10_0000 ;//
parameter
TIME_1US = 50 ,//1us
TIME_RST = 500 ,//复位脉冲 500us
TIME_REL = 20 ,//主机释放总线 20us
TIME_PRE = 200 ,//主机接收存在脉冲 200us
TIME_WAIT= 750000 ,//主机发完温度转换命令 等待750ms
TIME_LOW = 2 ,//主机拉低总线 2us
TIME_RW = 60 ,//主机读、写1bit 60us
TIME_REC = 3 ;//主机读、写完1bit释放总线 3us
localparam
CMD_ROMS = 8'hCC ,//跳过ROM指令
CMD_CONT = 8'h44 ,//温度转化指令
CDM_RTMP = 8'hBE ;//读暂存器指令
//信号定义
reg [8:0] m_state_c ;//主机现态
reg [8:0] m_state_n ;//主机次态
reg [5:0] s_state_c ;//从机现态
reg [5:0] s_state_n ;//从机次态
reg [5:0] cnt_1us ;//1us计数器
wire add_cnt_1us ;
wire end_cnt_1us ;
reg [19:0] cnt0 ;//复位脉冲、释放、存在脉冲、等待750ms
wire add_cnt0 ;
wire end_cnt0 ;
reg [19:0] X ;
reg [5:0] cnt1 ;//计数从机状态机每个状态持续时间
wire add_cnt1 ;
wire end_cnt1 ;
reg [5:0] Y ;
reg [4:0] cnt_bit ;
wire add_cnt_bit ;
wire end_cnt_bit ;
reg slave_ack ;//接收存在脉冲
reg flag ;//0:发送温度转换命令 1:发送温度读取命令
reg [7:0] wr_data ;
reg [15:0] orign_data ;//采样温度值寄存器
reg [10:0] temp_data ;
wire [23:0] temp_data_w ;//组合逻辑计算实际温度值 十进制
wire m_idle2m_rest ;
wire m_rest2m_rele ;
wire m_rele2m_rack ;
wire m_rack2m_roms ;
wire m_roms2m_cont ;
wire m_roms2m_rcmd ;
wire m_cont2m_wait ;
wire m_wait2m_rest ;
wire m_rcmd2m_rtmp ;
wire m_rtmp2m_idle ;
wire s_idle2s_low ;
wire s_low2s_send ;
wire s_low2s_samp ;
wire s_send2s_rele ;
wire s_samp2s_rele ;
wire s_rele2s_low ;
wire s_rele2s_done ;
//主机状态机设计 描述状态转移
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
m_state_c <= M_IDLE;
end
else begin
m_state_c <= m_state_n;
end
end
//主机状态转移条件
always @(*) begin
case(m_state_c)
M_IDLE:begin
if(m_idle2m_rest)
m_state_n = M_REST;
else
m_state_n = m_state_c;
end
M_REST:begin
if(m_rest2m_rele)
m_state_n = M_RELE;
else
m_state_n = m_state_c;
end
M_RELE:begin
if(m_rele2m_rack)