FPGA(9) DS18b20驱动(状态机综合应用)

 

 

 

代码:

module  ds18b20_ctrl(sys_clk,sys_rst,data1_inout,data_out,sign);

    input   wire    sys_clk,sys_rst;
    
    inout   wire     data1_inout;
    
    output  wire    [15:0]      data_out;
    output  reg      sign;

//时钟定义
reg              clk_1us;
reg     [4:0]    cnt_clk1us;

//状态机系列
reg     [5:0]           state;
parameter   init             =6'b000001;
parameter   write_cmd        =6'b000010;
parameter   waite_cmd        =6'b000100;
parameter   init_again       =6'b001000;
parameter   write_cmd_again  =6'b010000;
parameter   read_cmd         =6'b100000;



parameter   WR_44CC_CMD =   16'h44cc;
parameter   WR_BECC_CMD =   16'hbecc;

reg             flag_answer_init;
reg   [19:0]    cnt_time;
reg   [4:0]     cntBit15;
reg   [15:0]    data16_temp;
reg             qout_temp;
reg             qout_en;
wire   [15:0]   dataCmd_in_temp;
wire             qin_temp;
reg     [15:0]      data16_out;

//各个状态总延时
parameter   init_time   =20'd999;
parameter   write_time  =20'd65;
parameter   waite_time  =20'd750_000;
parameter   read_time   =20'd64;

//各个状态的输出方向的改变时间
parameter   init_outend_time    =20'd499;
parameter   init_answer_time    =20'd570;
parameter   write_outend0_time  =20'd62;
parameter   write_outend1_time  =20'd5;
parameter   read_answer_time    =20'd13;
parameter   read_outend         =20'd2;

//要输入数据的具体命令
parameter   write_cmd_CCh=8'hCC;//跳过rom命令
parameter   write_cmd_44h=8'h44;//温度转换命令
parameter   write_cmd_again_CCh=8'hcc;
parameter   write_cmd_again_BEh=8'hBE;


//时钟设置(50分频,1us)
always@(posedge sys_clk or negedge  sys_rst)
begin
    if(!sys_rst)
        begin
            clk_1us<=1'b0;
            cnt_clk1us<=5'd0;
        end
    else    if(cnt_clk1us==5'd24)
        begin
            clk_1us<=~clk_1us;
            cnt_clk1us<=5'd0;
        end
    else
        begin
            clk_1us<=clk_1us;
            cnt_clk1us=cnt_clk1us+1'b1;
        end
end

//全体状态机
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        state<=init;
    else    case(state)
        init:
            if((flag_answer_init==1'b1)&&(cnt_time==init_time))
                state<=write_cmd;
            else
                state<=state;
        write_cmd:
            if((cntBit15==5'd15)&&(cnt_time==write_time))
                state<=waite_cmd;
            else
                state<=state;
        waite_cmd:
            if(cnt_time==waite_time)
                state<=init_again;
            else
                state<=state;
        init_again:
            if((flag_answer_init==1'b1)&&(cnt_time==init_time))
                state<=write_cmd_again;
            else
                state<=state;
        write_cmd_again:
            if((cntBit15==5'd15)&&(cnt_time==write_time))
                state<=read_cmd;
            else
                state<=state;
        read_cmd:
            if((cntBit15==5'd15)&&(cnt_time==read_time))
                state<=init;
            else
                state<=state;
        default:
                state<=init;
        endcase
end

//Bit15计数
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        cntBit15<=5'd0;
    else    case(state)
        init:
        cntBit15<=cntBit15;
        write_cmd:
            if((cntBit15==5'd15)&&(cnt_time==write_time))
                cntBit15<=5'd0;
            else    if(cnt_time==write_time)
                cntBit15<=cntBit15+1'b1;
            else
                cntBit15<=cntBit15;
        waite_cmd:
            cntBit15<=cntBit15;
        init_again:
            cntBit15<=cntBit15;
        write_cmd_again:
            if((cntBit15==5'd15)&&(cnt_time==write_time))
                cntBit15<=5'd0;
            else    if(cnt_time==write_time)
                cntBit15<=cntBit15+1'b1;
            else
                cntBit15<=cntBit15;
        read_cmd:
            if((cntBit15==5'd15)&&(cnt_time==read_time))
                cntBit15<=5'd0;
            else    if(cnt_time==read_time)
                cntBit15<=cntBit15+1'b1;
            else
                cntBit15<=cntBit15;
        default:
                cntBit15<=cntBit15;
        endcase
end
//全体计数
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        cnt_time<=20'd0;
    else    case(state)
        init:
            if(cnt_time==init_time)
                cnt_time<=20'd0;
            else
                cnt_time<=cnt_time+1'b1;
        write_cmd:
            if((cnt_time==write_time))
                cnt_time<=20'd0;
            else
                cnt_time<=cnt_time+1;
        waite_cmd:
            if(cnt_time==waite_time)
                cnt_time<=20'd0;
            else
                cnt_time<=cnt_time+1'b1;
        init_again:
            if(cnt_time==init_time)
                cnt_time<=20'd0;
            else
                cnt_time<=cnt_time+1'b1;
        write_cmd_again:
            if((cnt_time==write_time))
                cnt_time<=20'd0;
            else
                cnt_time<=cnt_time+1;
        read_cmd:
            if(cnt_time==read_time)
                cnt_time<=20'd0;
            else
                cnt_time<=cnt_time+1'b1;
        default:
                cnt_time<=20'd0;
        endcase
end

// //cntBit15
// always@(posedge clk_1us or negedge  sys_rst)
// begin
    // if(!sys_rst)
        // cntBit15<=5'd0;
    // else    if(((state==write_cmd||state==write_cmd_again)&&(cntBit15==5'd15&&cnt_time==write_time))||((state==read_cmd)&&(cntBit15==5'd15&&cnt_time==read_time)))
        // cntBit15<=5'd0;
    // else    if(((state==write_cmd||state==write_cmd_again)&&(cnt_time==write_time))||(state==read_cmd&&cnt_time==read_time))
        // cntBit15<=cntBit15+1'b1;
    // else
        // cntBit15<=cntBit15;
// end

//flag_answer_init
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        flag_answer_init<=1'b0;
    else    if((state==init||state==init_again)&&(data1_inout==1'b0)&&(cnt_time==init_answer_time))
        flag_answer_init<=1'b1;
    else    if(cnt_time==init_time)
        flag_answer_init<=1'b0;
    else
        flag_answer_init<=flag_answer_init;
end

//读数据
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        data16_temp<=16'd0;
    else    if((state==read_cmd)&&(cnt_time==read_answer_time))
        data16_temp[cntBit15]<=data1_inout;
    else
        data16_temp<=data16_temp;
end

//数据完整输出
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        data16_out<=16'd0;
    else    if((cntBit15==5'd15)&&(cnt_time==read_time-4)&&(state==read_cmd)&&(data16_temp[14]==1'b0))
        data16_out<=data16_temp[10:0];
    else    if((cntBit15==5'd10)&&(cnt_time==read_time-4)&&(state==read_cmd)&&(data16_temp[14]==1'b1))
        data16_out<=~data16_temp[10:0]+1;
    else
        data16_out<=data16_out;
end

//符号输出
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        sign<=1'b0;
    else    if(cntBit15==5'd15&&(state==read_cmd-4)&&data16_temp[13]==1'b1&&cnt_time==read_time)
        sign<=1'b1;
    else    if(cntBit15==5'd15&&(state==read_cmd-4)&&data16_temp[13]==1'b0&&cnt_time==read_time)
        sign<=1'b0;
    else
        sign<=sign;
end



// //下面是管理单总线的输入还是输出
// always@(posedge clk_1us or negedge  sys_rst)
// begin
    // if(!sys_rst)
        // begin
            // qout_en<=1'b0;
            // qout_temp<=1'b0;
        // end
    // else    case(state)
        // init:
            // if(cnt_time<init_outend_time)
                // begin
                    // qout_en<=1'b1;
                    // qout_temp<=1'b0;
                // end
            // else
                // begin
                    // qout_en<=1'b0;
                    // qout_temp<=1'b0;
                // end
        // write_cmd:
            // // if(qin_temp==1'b1)
                // // begin
                    // // if((cnt_time<write_outend1_time)||cnt_time==write_time)
                    // // begin
                        // // qout_en<=1'b1;
                        // // qout_temp<=1'b0;
                    // // end
                    // // else
                    // // begin
                        // // qout_en<=1'b0;
                        // // qout_temp<=1'b0;
                    // // end
                // // end
            // // else
                // // begin
                    // // if((cnt_time<write_outend0_time)||cnt_time==write_time)
                    // // begin
                        // // qout_en<=1'b1;
                        // // qout_temp<=1'b0;
                    // // end
                    // // else
                    // // begin
                        // // qout_en<=1'b0;
                        // // qout_temp<=1'b0;
                    // // end
                // // end
            // if(cnt_time > 20'd62)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b0;
                // end
            // else    if(cnt_time <= 20'd2)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b1;
                // end
            // else    if(WR_44CC_CMD[cntBit15] == 1'b0)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b1;
                // end
            // else    if(WR_44CC_CMD[cntBit15] == 1'b1)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b0;
                // end
        // waite_cmd:
                // begin
                    // qout_en<=1'b1;
                    // qout_temp<=1'b1;
                // end
        // init_again:
            // if((cnt_time<init_outend_time))
                // begin
                    // qout_en<=1'b1;
                    // qout_temp<=1'b0;
                // end
            // else
                // begin
                    // qout_en<=1'b0;
                    // qout_temp<=1'b0;
                // end
        // write_cmd_again:
            // //if(qin_temp==1'b1)
                // // begin
                    // // if((cnt_time<write_outend1_time)||cnt_time==write_time)
                    // // begin
                        // // qout_en<=1'b1;
                        // // qout_temp<=1'b0;
                    // // end
                    // // else
                    // // begin
                        // // qout_en<=1'b0;
                        // // qout_temp<=1'b0;
                    // // end
                // // end
            // // else
                // // begin
                    // // if((cnt_time<write_outend0_time)||cnt_time==write_time)
                    // // begin
                        // // qout_en<=1'b1;
                        // // qout_temp<=1'b0;
                    // // end
                    // // else
                    // // begin
                        // // qout_en<=1'b0;
                        // // qout_temp<=1'b0;
                    // // end
                // // end
            // if(cnt_time > 20'd62)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b0;
                // end
            // else    if(cnt_time <= 20'd2)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b1;
                // end
            // else    if(WR_BECC_CMD[cntBit15] == 1'b0)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b1;
                // end
            // else    if(WR_BECC_CMD[cntBit15] == 1'b1)
                // begin
                    // qout_temp  <=  1'b0;
                    // qout_en   <=  1'b0;
                // end
        // read_cmd:
            // if(cnt_time<read_outend)
                // begin
                    // qout_en<=1'b1;
                    // qout_temp<=1'b0;
                // end
            // else
                // begin
                    // qout_en<=1'b0;
                    // qout_temp<=1'b0;
                // end
        // default:
                // begin
                    // qout_en<=qout_en;
                    // qout_temp<=qout_temp;
                // end
        // endcase
// end

//下面是管理单总线的输入还是输出
always@(posedge clk_1us or negedge  sys_rst)
begin
    if(!sys_rst)
        begin
            qout_en<=1'b0;
            qout_temp<=1'b0;
        end
    else    case(state)
        init:
            if(cnt_time<init_outend_time)
                begin
                    qout_en<=1'b1;
                    qout_temp<=1'b0;
                end
            else
                begin
                    qout_en<=1'b0;
                    qout_temp<=1'b0;
                end
        write_cmd:
                begin
                    if(WR_44CC_CMD[cntBit15]==1'b0)
                    begin
                        if(cnt_time<=write_outend0_time)
                        begin
                            qout_en<=1'b1;
                            qout_temp<=1'b0;
                        end
                        else
                        begin
                            qout_en<=1'b0;
                            qout_temp<=1'b0;
                        end
                    end
                    else    if(WR_44CC_CMD[cntBit15]==1'b1)
                    begin
                        if(cnt_time<=write_outend1_time)
                        begin
                            qout_en<=1'b1;
                            qout_temp<=1'b0;
                        end
                        else
                        begin
                            qout_en<=1'b0;
                            qout_temp<=1'b0;
                        end
                    end
                    else
                    begin
                        qout_en<=1'b0;
                        qout_temp<=1'b0;
                    end
            end
        waite_cmd:
                begin
                    qout_en<=1'b1;
                    qout_temp<=1'b1;
                end
        init_again:
            if((cnt_time<init_outend_time))
                begin
                    qout_en<=1'b1;
                    qout_temp<=1'b0;
                end
            else
                begin
                    qout_en<=1'b0;
                    qout_temp<=1'b0;
                end
        write_cmd_again:
                begin
                    if(WR_BECC_CMD[cntBit15]==1'b0)
                    begin
                        if(cnt_time<=write_outend0_time)
                        begin
                            qout_en<=1'b1;
                            qout_temp<=1'b0;
                        end
                        else
                        begin
                            qout_en<=1'b0;
                            qout_temp<=1'b0;
                        end
                    end
                    else    if(WR_BECC_CMD[cntBit15]==1'b1)
                    begin
                        if(cnt_time<=write_outend1_time)
                        begin
                            qout_en<=1'b1;
                            qout_temp<=1'b0;
                        end
                        else
                        begin
                            qout_en<=1'b0;
                            qout_temp<=1'b0;
                        end
                    end
                    else
                    begin
                        qout_en<=1'b0;
                        qout_temp<=1'b0;
                    end
            end
        read_cmd:
            if(cnt_time<read_outend)
                begin
                    qout_en<=1'b1;
                    qout_temp<=1'b0;
                end
            else
                begin
                    qout_en<=1'b0;
                    qout_temp<=1'b0;
                end
        default:
                begin
                    qout_en<=qout_en;
                    qout_temp<=qout_temp;
                end
        endcase
end
assign  data1_inout=(qout_en==1'b1)? qout_temp:1'bz;
assign  data_out=data16_out*625/10;


endmodule


 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦灵-影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值