问题描述
- 关于FPGA的DS18B20模块的时序问题,感觉一点错都没有啊。。。。 5C
- 求大神指导一下到底哪里错了,已经调试了三四天了,不管怎么调temp的值都是0.。。
module DS18B20
(
CLK48M
//RST
DQ
temp
);
//Port declaration
input CLK48M;
//input RST;
inout DQ;
output [11:0] temp;reg [7:0] Cnt;
reg clk1MHz;always@(posedge CLK48M)
begin
if(Cnt==8'd23)
begin
Cnt<=8'd0;
clk1MHz<=~clk1MHz;
end
else
Cnt<=Cnt+8'd1;
endparameter IDLE = 11'b000_0000_0001
DO_RESET = 11'b000_0000_0010
CMD_CC = 11'b000_0000_0100
CMD_44 = 11'b000_0000_1000
CMD_BE = 11'b000_0001_0000
WRITE_BYTE = 11'b000_0010_0000
Write_High = 11'b000_0100_0000
Write_Low = 11'b000_1000_0000
WAIT_750ms = 11'b001_0000_0000
READ_BIT = 11'b010_0000_0000
GET_TMP = 11'b100_0000_0000
WAIT_4MS = 11'b100_1000_1000;
//-------------------------------------------------------------------
reg [10:0] state;
reg [31:0] counter;
reg DQ;
reg [7:0] write_byte;//中间寄存器保存主机要写的指令字节
reg [3:0] write_byte_cnt;
reg [1:0] byte_flag;
reg [3:0] read_bit;
reg[11:0] temp;//12位温度数据
reg TMP_bit;always@(posedge clk1MHz)
begin
case(state)
IDLE:
begin
DQ<=1'bz;//空闲状态释放数据总线由外接上拉电阻将DQ数据线置高
counter<=0;
write_byte_cnt<=4'b0000;
byte_flag<=2'b00;
read_bit<=4'b0;
state<=DO_RESET;
end
DO_RESET://主机拉低数据总线持续至少480us,然后释放总线
begin
if(counter<=480)
begin
DQ<=1'b0;//拉低数据线480us
counter<=counter+1'b1;
end
else if(counter>480 && counter<=780)
begin
DQ<=1'bz;//释放数据总线60us+240us=300us
counter<=counter+1'b1;
if(DQ)//检测从机是否发送Presence Pulse(持续60us~240us低电平)
begin
state<=CMD_CC;
counter<=0;
end
else
begin
state<=IDLE;
end
end
end
CMD_CC:
begin
write_byte<=8'hCC;
state<=WRITE_BYTE;
end
WRITE_BYTE://写指令字节由低位向高位依次写入从机
begin
case(write_byte_cnt)
4'b0000:
begin
state<=write_byte[0]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0001:
begin
state<=write_byte[1]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0010:
begin
state<=write_byte[2]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0011:
begin
state<=write_byte[3]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0100:
begin
state<=write_byte[4]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0101:
begin
state<=write_byte[5]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0110:
begin
state<=write_byte[6]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b0111:
begin
state<=write_byte[7]?Write_High:Write_Low;
write_byte_cnt<=write_byte_cnt+1'b1;
end
4'b1000://8bit字节写完后在此处进行状态转换
begin
write_byte_cnt<=4'b0000;
case(byte_flag)
2'b00:
begin
state<=CMD_44;
byte_flag<=2'b01;
end
2'b01:
begin
state<=DO_RESET;
byte_flag<=2'b10;
end
2'b10:
begin
state<=CMD_BE;
byte_flag<=2'b11;
end
2'b11:
begin
state<=GET_TMP;
byte_flag<=2'b00;
end
endcase
end
default:write_byte_cnt<=4'b0000;
endcase
end
Write_High://写‘1’时序:主机拉低数据线1~27us然后释放数据总线30~数千us.
begin
if(counter<=8)//拉低数据线15us(至少1us)
begin
DQ<=1'b0;
counter<=counter+1'b1;
end
else if(counter>8 && counter begin
DQ counter end
else
begin
counter state end
end
Write_Low://写‘0’时序:主机拉低数据线30~227us然后释放数据总线1us~数千us.
begin
if(counter begin
DQ counter end
else if(counter>78 && counter begin
DQ counter end
else
begin
counter state end
end
CMD_44:
begin
write_byte state end
WAIT_750ms:
begin
if(counter>750000)//实际上只等待几us甚至不等待也可以
begin
state<=DO_RESET;
counter<=0;
end
else
counter<=counter+1'b1;
end
CMD_BE:
begin
write_byte<=8'hBE;
state<=WRITE_BYTE;
end
GET_TMP:
begin
case(read_bit)
4'h0:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
end
4'h1:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[0]<=TMP_bit;
end
4'h2:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[1]<=TMP_bit;
end
4'h3:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[2]<=TMP_bit;
end
4'h4:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[3]<=TMP_bit;
end
4'h5:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[4]<=TMP_bit;
end
4'h6:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[5]<=TMP_bit;
end
4'h7:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[6]<=TMP_bit;
end
4'h8:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[7]<=TMP_bit;
end
4'h9:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[8]<=TMP_bit;
end
4'hA:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[9]<=TMP_bit;
end
4'hB:
begin
state<=READ_BIT;
read_bit<=read_bit+1'b1;
temp[10]<=TMP_bit;
end
4'hC:
begin
state<=WAIT_4MS;
read_bit<=4'h0;
temp[11]<=TMP_bit;
end
default:read_bit<=4'h0;
endcase
end
READ_BIT://读时序:主机拉低数据总线约2~4us然后释放数据总线2~4us再读取DQ数据线上的值
begin
if(counter>=0 && counter<=3)
begin
DQ<=1'b0;//主机拉低数据总线约5us
counter<=counter+1'b1;
end
else if(counter>=4 && counter<=7)//最迟必须在29us处释放数据线
begin
DQ<=1'bz;//释放数据总线5us
counter<=counter+1'b1;
end
else if(counter==8)
begincounter<=counter+1'b1;
TMP_bit<=DQ;
end
else if(counter>=9 && counter begin
counter end
else
begin
state counter end
end
WAIT_4MS:
begin
if(counter>4000)
begin
state<=IDLE;
counter<=0;
end
else
begin
counter<=counter+1'b1;
end
end
default:state<=IDLE;
endcaseend
endmodule