我这个也是参照别人的程序写的,本来自己是用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