/****************************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
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驱动