• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

CPLD驱动DS18B20的程序

蓝蓝的天 2018-05-19 浏览量:961

我写了个CPLD驱动DS18B20的程序,用LCD1602显示。

可是老是显示00.0.

哪里出错啦?高手给看看。

module ds18b20(
  input        CLOCK_50               
  input        Q_KEY                  

  inout        DS18B20
 
  
  
output lcd_p    //Backlight Source +
output lcd_n    //Backlight Source -
output  lcd_rs    //0:write order; 1:write data   
output lcd_rw        //0:write data;  1:read data
output  lcd_en    //negedge 
output  [7:0] lcd_data
);


wire [11:0] t_buf;
reg ClkEnable;
reg [3:0] address;

ds18b20_drive ds18b20_u0(
  
  .nReset(Q_KEY)
  .ClkEnable(ClkEnable)
  .address(address)
  .clk(CLOCK_50)
  .data(t_buf)
  .icdata(DS18B20)
  
);

ds18b20_lcd lcd1602(
.clk         (CLOCK_50)
.Q_KEY (Q_KEY)
  .lcd_p (lcd_p)
  .lcd_n (lcd_n)
  .lcd_rs (lcd_rs)
  .lcd_rw (lcd_rw)
  .lcd_en (lcd_en)
  .lcd_data (lcd_data)

.data    (t_buf)

);
endmodule


这是顶层文件。

/***********************************************************************
************************* name:LCD1602_Driver *************************
************************* author:made by zzuxzt **************************
************************* time:2014.5.18 ********************************
***********************************************************************/
module ds18b20_lcd(input clk      //50M
input Q_KEY
output lcd_p    //Backlight Source +
output lcd_n    //Backlight Source -
output reg lcd_rs    //0:write order; 1:write data   
output lcd_rw        //0:write data;  1:read data
output reg lcd_en    //negedge 
output reg [7:0] lcd_data
input [11:0] data);
 
//--------------------lcd1602 order----------------------------
parameter    Mode_Set    =  8'h31
Cursor_Set  =  8'h0c
Address_Set =  8'h06
Clear_Set   =  8'h01;

/****************************LCD1602 Display Data****************************/
wire [7:0] data0data1data2; //counter data
wire [7:0] addr;   //write address
//---------------------------------1s counter-----------------------------------
reg [31:0] cnt1;
reg [7:0] data_r0data_r1;
/*always@(posedge clk or negedge Q_KEY)
begin
if(!Q_KEY)
begin
cnt1 <= 1'b0;
data_r0 <= 1'b0;
data_r1 <= 1'b0;
end
else if(cnt1==32'd50000000)
begin
if(data_r0==8'd9)
begin
data_r0 <= 1'b0;
if(data_r1==8'd9)
data_r1 <= 1'b0;
else
data_r1 <= data_r1 + 1'b1;
end
else
data_r0 <= data_r0 + 1'b1;
cnt1 <= 1'b0;
end
else
cnt1 <= cnt1 + 1'b1;
end*/

//assign data0 = 8'h30 + data_r0 ;     
//assign data1 = 8'h30 + data_r1 ;
assign data0 = 8'h30 + data[7:4] ;     
assign data1 = 8'h30 + data[11:8] ;
assign data2 = 8'h30 + data[3:0];
//-------------------address------------------
assign addr = 8'h80;

/****************************LCD1602 Driver****************************/  
//-----------------------lcd1602 clk_en---------------------
reg [31:0] cnt;
reg lcd_clk_en;
always @(posedge clk or negedge Q_KEY)      
begin 
if(!Q_KEY)
begin
cnt <= 1'b0;
lcd_clk_en <= 1'b0;
end
else if(cnt == 32'h24999)   //500us
begin
lcd_clk_en <= 1'b1;
cnt <= 1'b0;
end
else
begin
cnt <= cnt + 1'b1;
lcd_clk_en <= 1'b0;
end
end 

//-----------------------lcd1602 display state-------------------------------------------
reg [4:0] state;
always@(posedge clk or negedge Q_KEY)
begin
if(!Q_KEY)
begin
state <= 1'b0;
lcd_rs <= 1'b0;
lcd_en <= 1'b0;
lcd_data <= 1'b0;   
end
else if(lcd_clk_en)     
begin
case(state)
//-------------------init_state---------------------
5'd0: begin                
lcd_rs <= 1'b0;
lcd_en <= 1'b1;
lcd_data <= Mode_Set;   
state <= state + 1'd1;
end
5'd1: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd2: begin
lcd_rs <= 1'b0;
lcd_en <= 1'b1;
lcd_data <= Cursor_Set;
state <= state + 1'd1;
end
5'd3: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd4: begin
lcd_rs <= 1'b0;
lcd_en <= 1'b1;
lcd_data <= Address_Set;
state <= state + 1'd1;
end
5'd5: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd6: begin
lcd_rs <= 1'b0;
lcd_en <= 1'b1;
lcd_data <= Clear_Set;
state <= state + 1'd1;
end
5'd7: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end

//--------------------work state--------------------
5'd8: begin              
lcd_rs <= 1'b0;
lcd_en <= 1'b1;
lcd_data <= addr;   //write addr
state <= state + 1'd1;
end
5'd9: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd10: begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= "C";   //write data
state <= state + 1'd1;
end
5'd11: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd12: begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= "n";   //write data
state <= state + 1'd1;
end
5'd13: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd14: begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= "t";   //write data
state <= state + 1'd1;
end
5'd15: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd16: begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= ":";   //write data
state <= state + 1'd1;
end
5'd17: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end    
5'd18: begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= data1;   //write data: tens digit
state <= state + 1'd1;
end
5'd19: begin
lcd_en <= 1'b0;
state <= state + 1'd1;
end
5'd20: begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= data0;   //write data: single digit
state <= state + 1'd1;
end
5'd21: begin
lcd_en <= 1'b0;
//state <= 5'd8;
state <= state + 1'd1;
  end
5'd22:begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= ".";   //write data: single digit
state <= state + 1'd1;
end
5'd23: begin
lcd_en <= 1'b0;
//state <= 5'd8;
state <= state + 1'd1;
  end
5'd24:begin
lcd_rs <= 1'b1;
lcd_en <= 1'b1;
lcd_data <= data2;   //write data: single digit
state <= state + 1'd1;
end
5'd25: begin
lcd_en <= 1'b0;
state <= 5'd8;
//state <= state + 1'd1;
  end
default: state <= 5'bxxxxx;
endcase
end
end

assign lcd_rw = 1'b0;   //only write

//------------------backlight driver----------------
assign lcd_n = 1'b0;
assign lcd_p = 1'b1;

endmodule
这是LCD驱动。

module ds18b20_drive(nResetClkEnableaddressclkdataicdata);

input [3:0] address;
input nResetClkEnableclk;//clk 1Mhz
output [7:0] data;
inout [15:0] icdata;

wire [7:0] data;
reg [15:0] icdata;
//initial data = 8'bzzzzzzzz; 
reg[4:0] ij; //一个字8个位,多出一个数量级已用于判断

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;

always@(negedge clk or negedge nReset)
begin
if(!nReset)
begin
end
else if(ClkEnable)
begin
CmdSETDS18B20;
end
end

assign data = Result[0];

reg Flag_Rst; //复位完成标志
reg [4:0] Rststate; //复位状态
reg [10:1] CountRstStep; //复位计数器 1024
task Rst_DS18B20;
begin
case(Rststate)
state_0 : //out 1 keep 1us
begin
Flag_Rst <= 0; //复位进行中
icdata <= 16'b1111_1111_1111_1111; //总线拉高16'b1111_1111_1111_1111
Rststate <= state_1;
CountRstStep <= 0;
end
state_1 : 
begin
icdata <= 0; //总线拉低
if(CountRstStep > 600) //拉低时间600us
begin
CountRstStep <= 0; //计数器清0
Rststate <= state_2;
end
else
begin
CountRstStep <= CountRstStep + 1;
Rststate <= state_1; //计时未到
end
end
state_2 :
begin
icdata <= 16'b1111_1111_1111_1111; //dbgu //总线拉高
if(CountRstStep > 50) //拉高时间50us
begin
CountRstStep <= 0; //计数器清0
Rststate <= state_3;
end
else
begin
CountRstStep <= CountRstStep + 1;
Rststate <= state_2; //计时未到
end
end
state_3 :
begin
icdata <= 16'bzzzz_zzzz_zzzz_zzzz; //释放总线
Rststate <= state_4;
end
state_4 :
begin
Rststate <= state_5;
end
state_5 :
begin
if(icdata == 16'b1111_1111_1111_1111) //初始化完成
begin
CountRstStep <= 0;
Rststate <= state_6; //结束
end
else
begin
if(CountRstStep > 20)
begin
CountRstStep <= 0;
Rststate <= state_6; //state_0
end
else
begin
CountRstStep <= CountRstStep + 1;
Rststate <= state_5;
end
end
end
state_6 :
begin
if(CountRstStep == 200)
begin
CountRstStep <= 0;
Rststate <= state_7;
end
else
begin
CountRstStep <= CountRstStep + 1;
Rststate <= state_6;
end
end
state_7 :
begin
Flag_Rst <= 1; //初始化完成
CountRstStep <= 0;
Rststate <= state_0; //回到原点
end
default : 
begin
Rststate <= state_0;  
CountRstStep <= 0;
end
endcase
end
endtask

reg Flag_Write; //写命令完成标志与写位
reg[4:0] Writestate; //写命令状态
task Write_DS18B20;
input [7:0] dcmd; //命令
reg[7:0] indcmd;
reg wBit;
begin
case(Writestate)
state_0 :
begin
Flag_Write <= 0; //写命令过程中
Writestate <= state_1;
indcmd <= dcmd;
i <= 0;
end
state_1 :
begin
if(i < 8)
begin
wBit_DS18B20(indcmd[0]);
if(Flag_wBit) //写完1位
begin
indcmd = indcmd >> 1; //右移1位
i <= i + 1; //位数加1
end
Writestate <= state_1; //重复加写位
end
else //写完8位
begin
Writestate <= state_2;
i <= 0;
end
end
state_2 :
begin
Flag_Write <= 1; //写命令完毕
indcmd <= 0;
Writestate <= state_0;
end
default :
begin
Flag_Write <= 0;
Writestate <= state_0;
end
endcase
end
endtask

reg Flag_wBit; //写位完成标志
reg[4:0] WriteBitstate; //写位命令
reg[8:1] CountWbitStep; //写位计数器
task wBit_DS18B20;
input wiBit; //位信息
begin
case(WriteBitstate)
state_0 :
begin
Flag_wBit <= 0; //写位进行中
icdata <= 16'b1111_1111_1111_1111;
WriteBitstate <= state_1;
CountWbitStep <= 0;
end
state_1 :
begin
icdata <= 0; //总线拉低
if(wiBit)WriteBitstate <= state_2; //写1的命令
else WriteBitstate <= state_4; //写0的命令
end
state_2 :
begin
if(CountWbitStep >= 3) //维持低电平3us
begin
CountWbitStep <= 0;
icdata <= 16'b1111_1111_1111_1111;
WriteBitstate <= state_3;
end
else
begin
CountWbitStep <= CountWbitStep + 1;
WriteBitstate <= state_2;
end
end
state_3 :
begin
if(CountWbitStep >= 60) //维持拉高电平60us
begin
CountWbitStep <= 0;
WriteBitstate <= state_6;
end
else
begin
CountWbitStep <= CountWbitStep + 1;
WriteBitstate <= state_3;
end
end
state_4 :
begin
if(CountWbitStep >= 60) //维持低电平60us
begin
CountWbitStep <= 0;
WriteBitstate <= state_5;
end
else
begin
icdata <= 0;
CountWbitStep <= CountWbitStep + 1;
WriteBitstate <= state_4;
end
end
state_5 :
begin
if(CountWbitStep >= 3) //拉高总线3us
begin
CountWbitStep <= 0;
WriteBitstate <= state_6;
end
else
begin
icdata <= 16'b1111_1111_1111_1111;
CountWbitStep <= CountWbitStep + 1;
WriteBitstate <= state_5;
end
end
state_6 :
begin
Flag_wBit <= 1; //写位命令完毕
CountWbitStep <= 0;
WriteBitstate <= state_0;
end
default :
begin
Flag_wBit <= 0;
CountWbitStep <= 0;
WriteBitstate <= state_0;
end
endcase
end
endtask

reg[7:0] ResultDS18B20[15:0]; //读到的结果
reg[15:0] temp[7:0];
reg Flag_Read; //读命令标志
reg [4:0] Readstate; //读命令状态
reg t;
task Read_DS18B20;
begin
case(Readstate)
state_0 : 
begin
Flag_Read <= 0; //读命令进行中
Readstate <= state_1;
j <= 0;
end
state_1 :
begin
if( j < 8 )
begin
rBit_DS18B20;
if( Flag_rBit  )
begin
j <= j + 1;
end
Readstate <= state_1;
end
else 
begin
j <= 0;
i <= 0;
t <= 1;
Readstate <= state_2;
end
end
state_2 :
begin
if( i < 16 )
begin
if( temp[j][i] )
begin
ResultDS18B20[i] = ResultDS18B20[i] | 8'b1000_0000;
end
if( j < 7 )
ResultDS18B20[i] = ResultDS18B20[i] >> 1;
i <= i + 1;
Readstate <= state_2;
end
else
begin
i <= 0;
Readstate <= state_3;
end
end
state_3 :
begin
if( j < 7 )
begin
j <= j + 1;
Readstate <= state_2;
end
else
begin
i <= 0;
j <= 0;
Readstate <= state_4;
end
end
state_4 :
begin
Flag_Read <= 1; //读命令完成
Readstate <= state_0;
end
default :
begin
Flag_Read <= 0;
Readstate <= state_0;
end
endcase
end
endtask

reg Flag_rBit; //读位命令标志
reg[4:0] ReadBitstate; //读位命令状态
reg[6:1] CountRbitStep; //读位命令计时器
task rBit_DS18B20;
begin
case(ReadBitstate)
state_0 :
begin
Flag_rBit <= 0; //读位命令进行中
icdata <= 16'b1111_1111_1111_1111;
CountRbitStep <= 0;
ReadBitstate <= state_1;
end
state_1 :
begin
if(CountRbitStep >= 3) //保持低电平3us
begin
icdata <= 16'b1111_1111_1111_1111;
icdata <= 16'bzzzz_zzzz_zzzz_zzzz; //改为输入
CountRbitStep <= 0;
ReadBitstate <= state_2;
end
else
begin
icdata <= 0; //总线拉低
CountRbitStep <= CountRbitStep + 1;
ReadBitstate <= state_1;
end
end
state_2 :
begin
if(CountRbitStep >= 10) //维持输入状态10us
begin
temp[j] <= icdata;
CountRbitStep <= 0;
ReadBitstate <= state_3;
end
else
begin
CountRbitStep <= CountRbitStep + 1;
ReadBitstate <= state_2;
end
end
state_3 :
begin
if(CountRbitStep >= 60) //维持60us输入
begin
CountRbitStep <= 0;
ReadBitstate <= state_4;
end
else
begin
CountRbitStep <= CountRbitStep + 1;
ReadBitstate <= state_3;
end
end
state_4 :
begin
Flag_rBit <= 1; //读位命令完毕
CountRbitStep <= 0;
ReadBitstate <= state_0;
end
default :
begin
Flag_rBit <= 0;
CountRbitStep <= 0;
ReadBitstate <= state_0;
end
endcase
end
endtask

reg Flag_CmdSET;
reg [4:0] CmdSETstate;
reg [16:1] Count65535;
reg [4:1] Count12;
reg [7:0] Resultl[15:0]Resulth[15:0]Result[15:0];
task CmdSETDS18B20;
begin
case(CmdSETstate)
state_0 :
begin
Flag_CmdSET <= 0;
Rst_DS18B20;
if(!Flag_Rst)CmdSETstate <= state_0;
else CmdSETstate <= state_1;
end
state_1 :
begin
// Write_DS18B20(8'hcc);//
Write_DS18B20(8'h44);
if(!Flag_Write)CmdSETstate <= state_1;
else CmdSETstate <= state_2;
end
state_2 :
begin
// Write_DS18B20(8'h44);//
Write_DS18B20(8'hcc);
if(!Flag_Write)CmdSETstate <= state_2;
else CmdSETstate <= state_3;
end
state_3 :
begin
if(Count65535 == 65535)
begin
Count65535 <= 0;
CmdSETstate <= state_4;
end
else
begin
Count65535 <= Count65535 + 1;
CmdSETstate <= state_3;
end
end
state_4 :
begin
if(Count12 == 12)
begin
Count12 <= 0;
CmdSETstate <= state_5;
end
else
begin
Count12 <= Count12 + 1;
CmdSETstate <= state_3;
end
end
state_5 :
begin
Rst_DS18B20;
if(!Flag_Rst)CmdSETstate <= state_5;
else CmdSETstate <= state_6;
end
state_6 :
begin
// Write_DS18B20(8'hcc);//
Write_DS18B20(8'hbe);
if(!Flag_Write)CmdSETstate <= state_6;
else CmdSETstate <= state_7;
end
state_7 :
begin
// Write_DS18B20(8'hbe);//
Write_DS18B20(8'hcc);
if(!Flag_Write)CmdSETstate <= state_7;
else CmdSETstate <= state_8;
end
state_8 :
begin
Read_DS18B20;
if(!Flag_Read)CmdSETstate <= state_8;
else 
begin
i <= 0;
CmdSETstate <= state_9;
end
end
state_9 :
begin
if( i < 16 )
begin
Resultl[i] = ResultDS18B20[i];
i <= i + 1;
CmdSETstate <= state_9;
end
else
begin
i <= 0;
CmdSETstate <= state_10;
end
end
state_10 :
begin
Read_DS18B20;
if(!Flag_Read)CmdSETstate <= state_10;
else 
begin
i <= 0;
CmdSETstate <= state_11;
end
end
state_11 :
begin
if( i < 16)
begin
Resulth[i] = ResultDS18B20[i];
i <= i + 1;
CmdSETstate <= state_11;
end
else
begin
i <= 0;
CmdSETstate <= state_12;
end
end
state_12 :
begin
if( i < 16 )
begin
Result[i] = (Resulth[i] << 4)|(Resultl[i] >> 4);
i <= i + 1;
CmdSETstate <= state_12;
end
else
begin
i <= 0;
CmdSETstate <= state_13;
end
end
state_13 :
begin
Flag_CmdSET <= 1;
CmdSETstate <= state_0;
end
default :
begin
Flag_CmdSET <= 0;
CmdSETstate <= state_0;
end
endcase
end
endtask
endmodule
这是DS18B20驱动​

0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • ds18b20_drive的iccdata是inout,需要描述它为三态结构,类似stin=datadata=en?stout:1’bz。
    • 发布于 2018-05-21
    • 举报
    • 评论 0
    • 0
    • 0

其他答案 数量:1
  • 这个要检查一下你的驱动时序是不是正确的
    • 发布于2018-06-17
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

CPLD驱动DS18B20的程序