FPGA project : DS18B20

本想着一天发一个实验的,这个ds18b20,耗时两天。代码写了两次,呜呜~

由于第二次写代码没画时序图,所以代码和时序图一些参数有些不一致,但问题不大。

这里有几件事情值得一提:

1:关于状态机的编写,我觉得还是三段式比较好。

2:关于生成其他时钟信号,用来做触发边沿。我不喜欢用这种方法(提一个概念“全局时钟网络”)。所以用产生一个1us base基础计时器,产生一个1us的标志信号。之后的计数器与该计数器级联,记得把<end_cnt_base>这个标志信号加上。

我犯下的错误:

1:在画时序图是,没有画<end_cnt_base>标志信号,直接默认时钟为周期为1us,造成了混乱。所以以后要注意。

2:&& 逻辑写成了 || 逻辑

3:三态门输出 Z 写成了 1

4:数据位宽定义错误,因为少思考了一个数据对应的位宽。

4:读取温度时,少记一位。注意data_bit跳转条件,和发指令时不一样的。

 

 

module ds18b20(
    input   wire            sys_clk     ,
    input   wire            sys_rst_n   ,

    inout   wire            dq          ,

    output  reg     [19:0]  data        ,
    output  reg             sign  
);

    // localparam   指令,先发低位。
    localparam      WR_CMD_WORD = 16'h44CC    ,
                    RD_CMD_WORD = 16'hBECC    ;
    localparam      INIT        =  6'b000_001 ,
                    WR_CMD      =  6'b000_010 ,
                    WAIT        =  6'b000_100 ,
                    INIT_AGIN   =  6'b001_000 ,
                    RD_CMD      =  6'b010_000 ,
                    RD_TEMP     =  6'b100_000 ;
    // wire signal define
    wire            end_cnt_base      ;
    wire            INITtoWR_CMD      ;
    wire            WR_CMDtoWAIT      ;
    wire            WAITtoINIT_AGIN   ;
    wire            INIT_AGINtoRD_CMD ;
    wire            RD_CMDtoRD_TEMP   ;
    wire            RD_TEMPtoINIT     ;
    // reg  signal define
    reg     [5:0]   cnt_base     ;
    reg             dq_en        ;
    reg             dq_out       ;
    reg     [5:0]   state_c  /*synthesis preserve*/;
    reg     [5:0]   state_n  /*synthesis preserve*/;
    reg     [19:0]  cnt          ;
    reg     [4:0]   data_bit     ;
    reg             flag_respond ;
    reg             data_done    ;
    reg     [15:0]  data_temp    ; // 读取高速缓存器的byte0和byte1,一共16位。
    
    /****************************************************************************************/
    // reg     [5:0]       cnt_base ;
    // wire                end_cnt_base ;
    always @(posedge sys_clk or negedge sys_rst_n) 
        if(~sys_rst_n)
            cnt_base <= 6'd0 ;
        else if(end_cnt_base)
            cnt_base <= 6'd0 ;
        else 
            cnt_base <= cnt_base + 1'b1 ;
    assign  end_cnt_base = cnt_base == 49;
    // reg     [5:0]       state_c ;
    always @(posedge sys_clk or negedge sys_rst_n)
        if(~sys_rst_n
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值