verilog 实现单个ds18b20的ID号,uart输出

特点基础介绍

懒得写,可以看这位大哥的基础介绍:https://blog.csdn.net/as480133937/article/details/112604303

注意事项

  1. 硬件连接一定记得输出口要用上拉电阻,要不然释放总线无法拉高。
  2. 供电方式:两种供电方式(官方文档,或者看上面老哥的文档)都可以,无所谓。
  3. ds18b20的输入输出是一根线所以需要用到三态门来控制输入输出。如下
    wire                        dq_in;
    reg                         dq_out;
    reg                         dq_en;
    assign dq_in = (!dq_en)&dq;                              //高阻态,总线输入给到dq_in
    assign dq = (dq_en) ? dq_out : 1'bz;            //使能总线则输出,释放总线则为高阻

代码书写重点

1. rom查询命令的流程
在这里插入图片描述
上图是官方文档中给出rom命令的使用流程,从图中总结出IDd读取的流程就是:
复位---->写rom[33h]命令---->读出ID,整体的步骤就这三步。
2. 复位、读写时序

  1. 复位时序
    在这里插入图片描述
    上图是官方文档中的复位时序图,
    其中前半部分是我们需要输出的复位信号,首先是使能总线dq_en=1,同时拉低总线dq_out=0,在文档中要求主机复位低电平必须大于480us,最大值没有说,但是适当的大于480us就可以。此时需要释放总线dq_en=0,在释放总线后上拉电阻会将总线拉高,ds18b20在检测到这个高电平时会等待15-60us后,将总线拉低60-240us,所以在释放总线15-60us后我们只需要检测输入信号dq_in是否为低电平(因为刚才已经释放总线了所以输出变输入了),只要是低电平就说明复位成功。复位代码如下
INIT_1  :   begin
                            if (t_cnt_us == T_INIT) begin
                                t_cnt_us <= 0;
                                flag_ack <= 0;
                            end 
                            else begin
                                t_cnt_us <= t_cnt_us + 1'b1;
                                if (t_cnt_us <= 20'd499) begin
                                    dq_en <= 1;
                                    dq_out <= 0;
                                end  
                                else begin
                                    dq_en <= 0;
                                    if (t_cnt_us == 20'd570 && !dq_in)
                                        flag_ack <= 1;
                                end  
                            end 
                        end

这个是我状态机的一部分,时序逻辑可以看出,我这边复位总共用了T_INIT=1000us,(拉低总线等待了500us,然后等待响应500us,两边只要都大于480us就可)。
2. 写时序
在这里插入图片描述

写0和写1都要求持续时间必须大于60us小于120us,写0很简单,就是控制总线dq_en=1,拉低输出dq_out=0,然后维持时间控制在时序要求的那个范围就可以。写1,首先控制总线dq_en=1,拉低输出dq_out=0维持时间大于1us小于15us,然后释放总线dq_en=0。图中还显示在一次写完后必须释放总线dq_en=0,而且时间要大于1us。到此写0和写1的时序就可,代码如下

WR_CMD :   begin
                            if (t_cnt_us == 20'd69) begin
                                t_cnt_us <= 0;
                                dq_en <= 0;
                                if (bit_cnt == 7'd7)
                                    bit_cnt <= 0;
                                else 
                                    bit_cnt <= bit_cnt + 1;
                            end 
                            else begin
                                t_cnt_us <= t_cnt_us + 1;
                                if (t_cnt_us <= 1) begin                        //两次写的间隙释放总线,这里维持了2us
                                    dq_en <= 0;
                                    dq_out <= 0;
                                end 
								else if (t_cnt_us <= 3 && t_cnt_us >= 2) begin		//写1需要先拉低总线1-15us,写0都是拉低,所以先拉低个2us									
									dq_en <= 1;
									dq_out <= 0;
									end 
                                else begin
                                    if (READ_ROM[bit_cnt] == 0) begin		//写0,拉低总线
                                        dq_en <= 1;
                                        dq_out <= 0;
                                    end 
                                    else begin												//写1,已经拉低过总线所以这直接释放总线
                                        dq_en <= 0;
                                        dq_out <= 0;
                                    end 
                                end  
                            end 
                        end 
  1. 读时序
    在这里插入图片描述
    读0和读1的维持时间是一样的都是60-120us之间就可以,无论读1还是读0两个读取操作之间都得先控制总线dq_en=1,拉低输出dq_out=0,维持至少1us然后释放总线dq_en=0,然后就可以读0或者读1,当然读取操作必须在15us以内读取。代码如下</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值