📄 ds18b20读写程序.v
字号:
//------------------------------DS18B20-------------------------------------------
// DS18B20温度测量实验
// 网址:http://www.wejay.com
// 功能:在数码管上显示当前DS18B20测到的温度
// 小数部分为1位,温度为负时,最高位显示"-"
// DS18B20测量范围:-55℃ ~ +125℃,
// 本程序所测范围-55℃ ~ +55℃,
//------------------------------------------------------------------------------------
`define SKIP_ROM 8'b11001100//command 0xcc
`define CONVERT 8'b01000100//command 0x44
`define READ_SCRATCHPAD 8'b10111110//command 0xbe
module pro4(rst,clk,data,decode_value,scan_bit);
input rst; //K3 input
input clk; //50M clcok input
inout data; //ds18b20 data pin
output[7:0] decode_value; //segment output
output[7:0] scan_bit; //bit scan output
reg[11:0] counter_wr; //write time sequence counter
reg[11:0] counter_rd; //read time sequence counter
reg[15:0] counter_rst; //reset sequence counter
reg[25:0] counter_test; //convert wait time counter
reg temp_sign; //'1'negtive temperature,'0' postive temperature
reg[3:0] temp0; //low temperature BCD num
reg[7:0] temp1; //high temperature BCD num
reg[3:0] ini_value; //load the 4 bit num of the temperature
reg[7:0] decode_value; //segment output num
reg[16:0] scan_counter; //define the clock of the led scan
reg[3:0] scan_bit; //bit scan num
reg link_data; //tri-state control
reg ff; //task finish flag
reg[7:0]send_reg; //send buff
reg[12:0] recv_reg; //recv buff
reg[12:0] recv_reg_copy; //copy the data of the recv_reg
reg[9:0] wr_state; //write state
reg[13:0]rd_state; //read state
reg[8:0] main_state; //main state
//----------------------------define main state-----------------------------------
parameter IDLE =9'b000000001,
RESET1 =9'b000000010,
CMDCC =9'b000000100,
CMD44 =9'b000001000,
DELAY =9'b000010000,
RESET2 =9'b000100000,
CMDCC2 =9'b001000000,
GET_TEMP =9'b010000000,
READ_BIT =9'b100000000;
//----------------------------define write state-----------------------------------
parameter WR_IDLE =9'b000000001,
WR_BIT0 =9'b000000010,
WR_BIT1 =9'b000000100,
WR_BIT2 =9'b000001000,
WR_BIT3 =9'b000010000,
WR_BIT4 =9'b000100000,
WR_BIT5 =9'b001000000,
WR_BIT6 =9'b010000000,
WR_BIT7 =9'b100000000;
//---------------------------define read state------------------------------------
parameter RD_IDLE =14'b00000000000001,
RD_BIT0 =14'b00000000000010,
RD_BIT1 =14'b00000000000100,
RD_BIT2 =14'b00000000001000,
RD_BIT3 =14'b00000000010000,
RD_BIT4 =14'b00000000100000,
RD_BIT5 =14'b00000001000000,
RD_BIT6 =14'b00000010000000,
RD_BIT7 =14'b00000100000000,
RD_BIT8 =14'b00001000000000,
RD_BIT9 =14'b00010000000000,
RD_BIT10 =14'b00100000000000,
RD_BIT11 =14'b01000000000000,
RD_BIT12 =14'b10000000000000;
assign data=(link_data)?1'b0 : 1'bz;
//-------------------------main state machine-------------------------------------
//9 states:IDLE,RESET1,CMDCC,CMD44,DELAY,RESET2,CMDCC2,GET_TEMP,READ_BIT
//----------------------------------------------------------------------------------
always @(posedge clk)
begin
if(!rst) //rst to initialize the reg and the state
begin
link_data<=0;
main_state<=IDLE;
wr_state<=WR_IDLE;
rd_state<=RD_IDLE;
counter_test<=0;
counter_wr<=0;
counter_rd<=0;
counter_rst<=0;
ff<=0;
temp_sign<=0;
recv_reg<=0;
send_reg<=0;
end
else
begin
casex(main_state)
IDLE:
begin
main_state<=RESET1;
end
RESET1: //reset time sequence 490us low 490us tri-state
begin
if(ff==0)
reset;
else
begin
ff<=0;
send_reg<=`SKIP_ROM;
main_state<=CMDCC;//load 0xcc command
end
end
CMDCC: //write 0xcc command
begin
if(ff==0)
shift8_out;
else
begin
ff<=0;
send_reg<=`CONVERT;//load 0x44 command
main_state<=CMD44;
end
end
CMD44: //write 0x44 command
begin
if(ff==0)
shift8_out;
else
begin
ff<=0;
main_state<=DELAY;
end
end
DELAY: //wait for 750ms convert time
begin
if(ff==0)
delay;
else
begin
ff<=0;
main_state<=RESET2;
end
end
RESET2: //second time reset
begin
if(ff==0)
reset;
else
begin
ff<=0;
send_reg<=`SKIP_ROM;//load 0xcc command
main_state<=CMDCC2;
end
end
CMDCC2: //write 0xcc command
begin
if(ff==0)
shift8_out;
else
begin
ff<=0;
send_reg<=`READ_SCRATCHPAD;//load 0xbe command
main_state<=GET_TEMP;
end
end
GET_TEMP: // write 0xbe command
begin
if(ff==0)
shift8_out;
else
begin
ff<=0;
main_state<=READ_BIT;
end
end
READ_BIT: //read 13 bits temperature data
begin
if(ff==0)
shift12_in;
else
begin
ff<=0;
main_state<=RESET1;
end
end
default:
begin
link_data<=0;
main_state<=IDLE;
wr_state<=WR_IDLE;
rd_state<=RD_IDLE;
ff<=0;
end
endcase
end
end
//------------------------------write task------------------------------------------
//write 0 :pull '0' for 60 us then release the one wire bus(whole cycle:70 us)
//write 1 :pull '0' for 6 us then release the one wire bus (whole cycle :70us)
//---------------------------------------------------------------------------------
task shift8_out;
begin
casex(wr_state)
WR_IDLE:
begin
link_data<=0;
counter_wr<=0;
wr_state<=WR_BIT0;
end
WR_BIT0:
begin
if(send_reg[0])
begin
if(counter_wr==3500)
begin
counter_wr<=0;
wr_state<=WR_BIT1;
send_reg<=send_reg>>1;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT0;
if(counter_wr<300)
link_data<=1;
else
link_data<=0;
end
end
else
begin
if(counter_wr==3500)
begin
wr_state<=WR_BIT1;
link_data<=0;
send_reg<=send_reg>>1;
counter_wr<=0;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT0;
if(counter_wr<3000)
link_data<=1;
else
link_data<=0;
end
end
end
WR_BIT1:
begin
if(send_reg[0])
begin
if(counter_wr==3500)
begin
wr_state<=WR_BIT2;
send_reg<=send_reg>>1;
counter_wr<=0;
end
else
begin
wr_state<=WR_BIT1;
counter_wr<=counter_wr+1'b1;
if(counter_wr<300)
link_data<=1;
else
link_data<=0;
end
end
else
begin
if(counter_wr==3500)
begin
counter_wr<=0;
wr_state<=WR_BIT2;
link_data<=0;
send_reg<=send_reg>>1;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT1;
if(counter_wr<3000)
link_data<=1;
else
link_data<=0;
end
end
end
WR_BIT2:
begin
if(send_reg[0])
begin
if(counter_wr==3500)
begin
counter_wr<=0;
wr_state<=WR_BIT3;
send_reg<=send_reg>>1;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT2;
if(counter_wr<300)
link_data<=1;
else
link_data<=0;
end
end
else
begin
if(counter_wr==3500)
begin
counter_wr<=0;
wr_state<=WR_BIT3;
link_data<=0;
send_reg<=send_reg>>1;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT2;
if(counter_wr<3000)
link_data<=1;
else
link_data<=0;
end
end
end
WR_BIT3:
begin
if(send_reg[0])
begin
if(counter_wr==3500)
begin
counter_wr<=0;
wr_state<=WR_BIT4;
send_reg<=send_reg>>1;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT3;
if(counter_wr<300)
link_data<=1;
else
link_data<=0;
end
end
else
begin
if(counter_wr==3500)
begin
counter_wr<=0;
wr_state<=WR_BIT4;
link_data<=0;
send_reg<=send_reg>>1;
end
else
begin
counter_wr<=counter_wr+1'b1;
wr_state<=WR_BIT3;
if(counter_wr<3000)
link_data<=1;
else
link_data<=0;
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -