这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » zhengchao20105进程贴:ds18b20

共6条 1/1 1 跳转至

zhengchao20105进程贴:ds18b20

菜鸟
2013-03-16 17:26:45     打赏

我这个也是参照别人的程序写的,本来自己是用case(时间点)写了一个,发现不能运行。

18b20的初始化时序很重要,这个对了就成功了一半了,另外良好的编程习惯也很重要,我就是因为下面的少了一组begin,end导致程序死在这里,调了几个晚上也没有发现,因为是业余时间写,也没有示波器,只有好的书写风格才能保证少出错。

        state_3://70us的高电平
            begin
            dq<=1;
            if(wbit_count>11'd60)
                begin
                wbit_state<=state_6;
                wbit_count<=0;
                end
            else
                begin
                wbit_count<=wbit_count+1'b1;
                wbit_state<=state_3;
                end
            end


//---------------------------------------------------------------------------------------------------------------//

module ds18b20_zc(
sys_clk,
dq,
sel,
seg);
input sys_clk;
inout dq;
reg dq;
output [7:0] sel;
output [7:0] seg;
reg [9:0] sub_clk;
reg tra_clk=0;
reg [3:0] temp_bai=0;
reg [3:0] temp_shi=0;
reg [3:0] temp_ge=0;
reg [31:0] temp=0;
reg [7:0] data_count;
reg [31:0] result;
reg [7:0] j;
reg [7:0] k;
reg [7:0] rbit_buffer;
parameter state_0=0;
parameter state_1=1;
parameter state_2=2;
parameter state_3=3;
parameter state_4=4;
parameter state_5=5;
parameter state_6=6;
parameter state_7=7;
parameter state_8=8;
parameter state_9=9;
parameter state_10=10;
parameter state_11=11;
parameter state_12=12;
parameter state_13=13;
parameter state_14=14;
parameter state_15=15;

//数码管设定//
reg [7:0] sel=8'b11111111;//turn off
reg [7:0] seg=0;
reg [27:0] delay_ms=0;
reg [3:0] state_ms=0;
reg sel_0_flag=0;
reg sel_1_flag=0;
reg sel_2_flag=0;
//1Mhz 分频//
always@(posedge sys_clk)
begin
    if(sub_clk>=10'd25)
        begin
            sub_clk<=0;
            tra_clk<=~tra_clk;
        end
    else sub_clk<=sub_clk+1'b1;
end

always@(posedge tra_clk)
    process_18b20;

    
//初始化命令//
reg rst_flag;
reg [4:0] rst_state;
reg [10:0] rst_count;
task rst_initial;
begin
    case(rst_state)
    state_0:
                begin
                dq<=1'b1;
                rst_state<=state_1;
                rst_flag<=0;
                rst_count<=0;
                end
    state_1:
                begin//600us的低电平
                dq<=0;
                if(rst_count>11'd600)
                    begin
                    rst_count<=0;
                    rst_state<=state_2;
                    end
                else
                    begin
                    rst_count<=rst_count+1'b1;
                    rst_state<=state_1;
                    end
                end
    state_2:
                begin//15us的release
                dq<=1'bz;//zzzzzzzzzzzzzzzzzzzzzzzzz
                if(rst_count>11'd15)
                    begin
                    rst_count<=0;
                    rst_state<=state_3;
                    end
                else
                    begin
                    rst_count<=rst_count+1'b1;
                    rst_state<=state_2;
                    end
                end
    state_3:
            begin
            dq<=1'bz;//zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
            rst_state<=state_4;
            end
    state_4:
                begin//等待接收复位信号,50us内检测    
                    if(dq==0)
                        begin
                        rst_count<=0;
                        rst_state<=state_5;
                        end
                    else if(rst_count>11'd45)
                        begin
                        rst_flag<=0;
                        rst_count<=0;
                        rst_state<=state_0;
                        end
                    else
                        begin
                        rst_count<=rst_count+1'b1;
                        rst_state<=state_4;
                        end
                    end
    state_5:
                begin//发送80us的低电平
                if(rst_count>11'd80)
                    begin
                        if(dq==0)
                            begin
                        rst_count<=0;
                        rst_state<=state_6;
                            end
                        else
                        begin
                        rst_count<=0;
                        rst_state<=state_0;
                        end
                    end
                 else
                        begin
                        rst_count<=rst_count+1'b1;
                        rst_state<=state_5;
                        end
                end
    state_6:
                begin//发送400us的高电平
                if(rst_count>11'd420)
                    begin
                    rst_count<=0;
                    rst_flag<=1;
                    rst_state<=state_0;//返回
                    end
                else
                    begin
                    rst_count=rst_count+1'b1;
                    rst_state<=state_6;
                    end
                end    
    default:
                begin
                rst_count<=0;
                rst_flag<=0;
                rst_state<=0;
                end
    endcase
end
endtask

//写位操作命令//
reg write_bit_flag;
reg [4:0] wbit_state;
reg [10:0] wbit_count;
task write_bit;
input wbit;
begin
    case(wbit_state)
        state_0:
            begin
            dq<=1'b1;
            wbit_state<=state_1;
            write_bit_flag<=0;
            wbit_count<=0;
            end
        state_1:
            begin
            dq<=0;
            if(wbit==1'b1)
            wbit_state<=state_2;//写1
            else if(wbit==0)
            wbit_state<=state_4;//写0
            end
//以下为写1的操作------------------------------------//
        state_2://2us 低电平
            begin
            dq<=0;
            if(wbit_count>11'd2)
                begin
                wbit_count<=0;
                wbit_state<=state_3;
                end
            else
                begin
                wbit_count<=wbit_count+1'b1;
                wbit_state<=state_2;
                end
            end
        state_3://70us的高电平
            begin
            dq<=1;
            if(wbit_count>11'd60)
                begin
                wbit_state<=state_6;
                wbit_count<=0;
                end
            else
                begin
                wbit_count<=wbit_count+1'b1;
                wbit_state<=state_3;
                end
            end
//以下为写0的操作-------------------------------//
        state_4://70us的低电平
            begin
            dq<=0;
            if(wbit_count>11'd60)
                begin
                wbit_count<=0;
                wbit_state<=state_5;
                end
            else
                begin
                wbit_count<=wbit_count+1'b1;
                wbit_state<=state_4;
                end
            end
            state_5://3us的高电平
                begin
                dq<=1;
                if(wbit_count>11'd3)
                    begin
                    wbit_state<=state_6;
                    wbit_count<=0;
                    end
                else
                    begin
                    wbit_count<=wbit_count+1'b1;
                    wbit_state<=state_5;
                    end
                end    
            state_6:
                    begin
                    write_bit_flag<=1'b1;//写完标志为1
                    wbit_count<=0;
                    wbit_state<=state_0;
                    end
            default:
                    begin
                    write_bit_flag<=0;
                    wbit_state<=0;
                    wbit_count<=0;
                    end
        endcase
end
endtask

//写字节操作命令//

reg write_byte_flag;
reg [4:0] wbyte_state;
reg [10:0] wbyte_count;
task write_byte;
input [7:0] write_data;
reg [7:0] in_data;
begin
    case(wbyte_state)
    state_0:
        begin
        write_byte_flag<=0;
        wbyte_state<=state_1;
        k<=0;
        in_data<=write_data;
        end
    state_1:
        begin
        if(k<8'd8)
            begin
            write_bit(write_data[k]);
                if(write_bit_flag==1'b1)
                begin
                k<=k+1'b1;//位数加一
                in_data<=in_data>>1;
                end
            wbyte_state<=state_1;//重复写位命令
            end
        else if(k>=8'd8)
            begin
            k=0;
            write_byte_flag<=1;
            wbyte_state<=state_0;
            in_data<=0;
            end
        end
    default:
            begin
            write_byte_flag<=0;
            wbyte_state<=0;
            end
    endcase
end
endtask


//读位操作命令//
reg read_bit_flag;
reg [4:0] rbit_state;
reg [10:0] rbit_count;
reg [15:0] sum_bit;
task read_bit;

begin
    case(rbit_state)
        state_0:
            begin
            rbit_count<=0;
            read_bit_flag<=0;//flag为0
            dq<=1'b1;
            rbit_state<=state_1;
            end
        state_1:
            begin
            //持续3us的低电平
            dq<=1'b0;
            if(rbit_count>11'd3)
                begin
                rbit_count<=0;
                rbit_state<=state_2;
                end
            else
                begin
                rbit_count<=rbit_count+1'b1;
                rbit_state<=state_1;
                end
            end
        state_2:
            begin
            dq<=1'bz;//释放dqzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
            rbit_state<=state_3;
            end
        state_3:
            begin
            if(rbit_count>11'd10)//经过10us
                begin
                rbit_buffer[j]<=dq;
                rbit_state<=state_4;
                end
            else
                begin
                rbit_count<=rbit_count+1'b1;
                rbit_state<=state_3;
                end
            end
        state_4:
                begin
                dq<=1'b1;
                if(rbit_count>11'd60)//60us动作时间
                    begin
                    rbit_count<=0;
                    rbit_state<=state_0;
                    read_bit_flag<=1'b1;
                    end
                else
                    begin
                    rbit_count<=rbit_count+1'b1;
                    rbit_state<=state_4;
                    end
                end
        default:
                begin
                rbit_count<=0;
                rbit_state<=0;
                read_bit_flag<=0;
                end
            endcase
end
endtask

//读字节命令//
reg read_byte_flag;
reg [4:0]rbyte_state;
reg [7:0] rbyte_buffer;
task read_byte;
begin
    case(rbyte_state)
    state_0:
            begin
            j<=0;
            read_byte_flag<=0;
            rbyte_state<=state_1;
            end
    state_1:
            begin
            if(j<8'd8)
                begin
                read_bit;
                if(read_bit_flag==1'b1)
                j<=j+1'b1;
                rbyte_state<=state_1;
                end
            else
                begin
                j<=0;
                rbyte_state<=state_2;
                end
            end
    state_2:
            begin
                if(j<8'd8)
                begin
                rbyte_buffer[j]=rbit_buffer[j];
                j<=j+1'b1;
                rbyte_state<=state_2;
                end
            else
                begin
                rbyte_state<=state_0;
                read_byte_flag<=1'b1;
                end
            end
    default:
            begin
            rbyte_state<=0;
            read_byte_flag<=0;
            end
    endcase
end
endtask

reg [7:0] result_h;
reg [7:0] result_l;
reg finish_flag;
reg [7:0] pro_state;
reg [30:0] pro_count;
task process_18b20;
begin        
    case(pro_state)
    state_0://初始化
            begin
            finish_flag<=0;
            rst_initial;
            if(rst_flag==0)
            pro_state<=state_0;
            else
            pro_state<=state_1;
            end
    state_1://写入cch
            begin
            write_byte(8'hcc);
            if(write_byte_flag==0)
                pro_state<=state_1;
            else
            pro_state<=state_2;
            end
    state_2://写入44h
            begin
            write_byte(8'h44);
            if(write_byte_flag==0)
            pro_state<=state_2;
            else
            pro_state<=state_3;
            end
    state_3://延时700ms
            begin
            if(pro_count>31'd700000)
                begin
                pro_count<=0;
                pro_state<=state_4;
                end
            else
                begin
                pro_count<=pro_count+1'b1;
                pro_state<=state_3;
                end
            end
    state_4://初始化
            begin
            rst_initial;
            if(rst_flag==0)
            pro_state<=state_4;
            else
            pro_state<=state_5;
            end
    state_5://写入cch
            begin
            write_byte(8'hcc);
            if(write_byte_flag==0)
                pro_state<=state_5;
            else
            pro_state<=state_6;
            end
    state_6://写入beh
            begin
            write_byte(8'hbe);
            if(write_byte_flag==0)
            pro_state<=state_6;
            else
            pro_state<=state_7;
            end
    state_7://读出数值
            begin
            read_byte;
            if(read_byte_flag==0)
            pro_state<=state_7;
            else
            pro_state<=state_8;
            end
    state_8:
            begin//低位
            result_l[7:0]<=rbyte_buffer[7:0];
            pro_state<=state_9;
            end
    state_9:
            begin//读出数值
            read_byte;
            if(read_byte_flag==0)
            pro_state<=state_9;
            else
            pro_state<=state_10;
            end
    state_10:
            begin//高位
            result_h[7:0]<=rbyte_buffer[7:0];
            pro_state<=state_11;
            end
    state_11://计算数值
                begin
                result[15:8]<=result_h[7:0];
                result[7:0]<=result_l[7:0];
                pro_state<=state_12;
                end
    state_12:
                begin
                temp[31:0]=result[15:0]*625;
                temp_bai=temp[31:0]/1000/100;
                temp_shi=temp[31:0]/1000/10%10;
                temp_ge=temp[31:0]/1000%10%10;
            /*    temp_bai<=result/100;
                temp_shi<=result/10%10;
                temp_ge<=result%10%10;*/
                pro_state<=state_13;
                end
    state_13://完成
            begin
            finish_flag<=1'b1;
            pro_state<=state_0;
            end    
    default:
            begin
            finish_flag<=0;
            pro_state<=state_0;
            end
        endcase
    end
endtask
            


//------------display delay  ms//
always@(posedge sys_clk)
begin
if(delay_ms>28'd9999)
delay_ms<=0;
else delay_ms<=delay_ms+1'b1;
end

always@(posedge sys_clk)
if(delay_ms==28'd9999)
begin
if(state_ms>=4'b0010)
state_ms<=1'b0;
else state_ms<=state_ms+1'b1;
end

always@(posedge sys_clk)
begin
    begin
    case (state_ms)
    4'b0000:
            begin
            sel<=8'b11011111;//select 0 tube
            sel_0_flag<=1;
            end
    
    4'b0001:
            begin
            sel<=8'b10111111;//select 1 tube
            sel_1_flag<=1;
            end
    4'b0010:
            begin
            sel<=8'b01111111;//select 2 tube
            sel_2_flag<=1;
            end
    endcase
    end

    if(sel_2_flag==1)//第三个数码管被选择
    begin
    case(temp_bai)
    4'b0000:seg<=8'hc0;//display 0
    4'b0001:seg<=8'hf9;//display 1
    4'b0010:seg<=8'ha4;//display 2
    4'b0011:seg<=8'hb0;//display 3
    4'b0100:seg<=8'h99;//display 4
    4'b0101:seg<=8'h92;//display 5
    4'b0110:seg<=8'h82;//display 6
    4'b0111:seg<=8'hF8;//display 7
    4'b1000:seg<=8'h80;//display 8
    4'b1001:seg<=8'h90;//display 9
    endcase
    sel_2_flag<=0;
    end

    else if(sel_1_flag==1)//第二个数码管被选择
    begin
    case(temp_shi)
    4'b0000:seg<=8'h40;//display 0.
    4'b0001:seg<=8'h79;//display 1.
    4'b0010:seg<=8'h24;//display 2.
    4'b0011:seg<=8'h30;//display 3.
    4'b0100:seg<=8'h19;//display 4.
    4'b0101:seg<=8'h12;//display 5.
    4'b0110:seg<=8'h02;//display 6.
    4'b0111:seg<=8'h78;//display 7.
    4'b1000:seg<=8'h00;//display 8.
    4'b1001:seg<=8'h10;//display 9.
    endcase
    sel_1_flag<=0;
    end
    
    else if(sel_0_flag==1)//第一个数码管被选择
    begin
    case(temp_ge)
    4'b0000:seg<=8'hc0;//display 0
    4'b0001:seg<=8'hf9;//display 1
    4'b0010:seg<=8'ha4;//display 2
    4'b0011:seg<=8'hb0;//display 3
    4'b0100:seg<=8'h99;//display 4
    4'b0101:seg<=8'h92;//display 5
    4'b0110:seg<=8'h82;//display 6
    4'b0111:seg<=8'hF8;//display 7
    4'b1000:seg<=8'h80;//display 8
    4'b1001:seg<=8'h90;//display 9
    endcase
    sel_0_flag<=0;
    end
end
endmodule        
    
                
                

                
                
                
                            
                
                
                





关键词: 18b20    

工程师
2013-03-21 10:10:39     打赏
2楼
还没试过在FPGA中测ds18b20,有时间也试一下

专家
2013-03-21 14:28:04     打赏
3楼
代码够长的啊

助工
2013-03-24 11:15:45     打赏
4楼
kkkkk

工程师
2013-03-27 17:02:54     打赏
5楼
用单片机写过ds18b20,感觉要比这个简单多勒

菜鸟
2013-10-19 07:19:45     打赏
6楼
你的程序写的好复杂。实际上没有这么复杂,你的平台是什么

共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]