標(biāo)題:
Spartan-6 FPGA驅(qū)動ds18B20的源程序
[打印本頁]
作者:
hu_junbo
時間:
2018-12-11 15:13
標(biāo)題:
Spartan-6 FPGA驅(qū)動ds18B20的源程序
spartan-6芯片外掛一顆ds18B20來讀取溫度,根據(jù)此溫度來進(jìn)行加熱控制
1544512037.png
(36.33 KB, 下載次數(shù): 82)
下載附件
ds18B20電路圖
2018-12-11 15:08 上傳
module DS18B20_drive
(
input clk,rst_n,
inout temp_dq,
output reg [15:0] temp
);
reg ds,flag;
//延時參數(shù)
parameter TIME_1us = 32'd50,
TIME_2us = 32'd100,
TIME_4us = 32'd200,
TIME_8us = 32'd400,
TIME_550us = 32'd27500,
TIME_500us = 32'd25000,
TIME_66us = 32'd3300,
TIME_20us = 32'd1000,
TIME_1s = 32'd50_000_000;
parameter RESET1 = 3'd0,
DELAY1 = 3'd1,
WRITE1 = 3'd2,
DELAY2 = 3'd3,
RESET2 = 3'd4,
DELAY3 = 3'd5,
WRITE2 = 3'd6,
READ = 3'd7;
`define delay_1us cnt_clk_r == TIME_1us
`define delay_2us cnt_clk_r == TIME_2us
`define delay_4us cnt_clk_r == TIME_4us
`define delay_8us cnt_clk_r == TIME_8us
`define delay_20us cnt_clk_r == TIME_20us
`define delay_550us cnt_clk_r == TIME_550us
`define delay_500us cnt_clk_r == TIME_500us
`define delay_66us cnt_clk_r == TIME_66us
`define delay_1s cnt_clk_r == TIME_1s
//狀態(tài)變重
reg [2:0] work_state,
state_rest1,
state_write1,
state_rest2,
state_write2,
state_read;
reg [4:0] i;
reg [4:0] j;
reg [15:0] value;
//reg flag;
/*
parameter val1 = 16'h44CC,
val2 = 16'hBECC;
*/
reg [15:0] vala;
reg [15:0] val2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)begin
ds <= 1'b1;
work_state <= 3'd0;
state_rest1 <= 3'd0;
state_write1<= 3'd0;
state_rest2 <= 3'd0;
state_write2<= 3'd0;
state_read <= 3'd0;
vala <= 16'h44CC;
val2 <= 16'hBECC;
i <= 5'd0;
j <= 5'd0;
flag <= 1'b1;
end
else begin
case(work_state)
//復(fù)位1
RESET1:
case(state_rest1)
3'd0: //ds=1 延時1us
begin
state_rest1 <= (`delay_1us) ? 3'd1:3'd0;
ds <= 1'b1;
end
3'd1: //ds=0 延時550us 要求480~960us
begin
state_rest1 <= (`delay_550us) ? 3'd2:3'd1;
ds <= 1'b0;
end
3'd2: //ds=z 延時66us 釋放總線等待15-60us使ds18B20發(fā)出低脈再
begin
state_rest1 <= (`delay_66us) ? 3'd3:3'd2;
ds <= 1'bz;
end
3'd3://獲取低脈再
begin
state_rest1 <= 3'd4;
flag <= ds;
end
3'd4:
begin
if(flag==1'b0)
begin
ds <= 1'bz;
work_state <= DELAY1;
end
else
begin
state_rest1 <= 3'd0;
ds <= 1'b1;
work_state <= work_state;
end
end
default:state_rest1 <= 3'd0;
endcase
DELAY1://等待18B20發(fā)出的低脈沖信號完全結(jié)束60~240us
begin
work_state <= (`delay_500us) ? WRITE1 : DELAY1;
//flag <= 1'b1;
end
//寫數(shù)捠寫入數(shù)據(jù)16'hcc 16'h44
WRITE1:
case(state_write1)
3'd0: // ds=1 延時1us 連續(xù)寫兩位間隔大仵s
begin
state_write1 <= (`delay_2us) ? 3'd1:3'd0;
ds <= 1'b1;
end
3'd1: //ds=0 延時4us 將FPGA引腳從高拉至低電平時,就產(chǎn)生寫時間隙
begin
state_write1 <= (`delay_4us) ? 3'd2:3'd1;
ds <= 1'b0;
end
3'd2: //寫一僥۶時66us
begin
state_write1 <= (`delay_66us) ? 3'd3:3'd2;
ds <= vala[0];
end
3'd3:
begin
if(i <= 14)
begin
vala <= {1'b0,vala[15:1]};
i <= i+1'b1;
state_write1 <= 3'd0;
end
else if(i==15)
begin
state_write1 <= 3'd4;
vala <= {1'b0,vala[15:1]};
end
end
3'd4: //ds=1 延時1us
begin
ds <= 1'bz;
i <= 5'd0;
state_write1 <= (`delay_1us) ? 3'd5:3'd4;
end
3'd5:
begin
work_state <= DELAY2;
end
default:state_write1 <= 3'd0;
endcase
//延時1s,使得芯片完成溫度轉(zhuǎn)化(datasheet要求最尿00ms_
DELAY2:
begin
work_state <= (`delay_1s) ? RESET2:DELAY2;
ds <= 1'bz;
end
//復(fù)位2
RESET2:
case(state_rest2)
3'd0: //ds=1 延時1us
begin
state_rest2 <= (`delay_1us) ? 3'd1:3'd0;
ds <= 1'b1;
end
3'd1: //ds=0 延時550us 要求480~960us
begin
state_rest2 <= (`delay_550us) ? 3'd2:3'd1;
ds <= 1'b0;
end
3'd2: //ds=z 延時66us 釋放總線等待15-60us使ds18B20發(fā)出低脈再
begin
state_rest2 <= (`delay_66us) ? 3'd3:3'd2;
ds <= 1'bz;
end
3'd3://獲取低脈再
begin
state_rest2 <= 3'd4;
flag <= ds;
end
3'd4:
begin
if(flag==1'b0)
begin
ds <= 1'bz;
work_state <= DELAY3;
end
else
begin
state_rest2 <= 3'd0;
ds <= 1'b1;
work_state <= work_state;
end
end
default:state_rest2 <= 3'd0;
endcase
DELAY3:
begin
work_state <= (`delay_500us) ? WRITE2:DELAY3;
end
//寫操你寫入16'hcc 16'hBE
WRITE2:
case(state_write2)
3'd0: // ds=1 延時1us 連續(xù)寫兩位間隔大仵s
begin
state_write2 <= (`delay_2us) ? 3'd1:3'd0;
ds <= 1'b1;
end
3'd1: //ds=0 延時4us
begin
state_write2 <= (`delay_4us) ? 3'd2:3'd1;
ds <= 1'b0;
end
3'd2: //寫一僥۶時66us
begin
state_write2 <= (`delay_66us) ? 3'd3:3'd2;
ds <= val2[0];
end
3'd3:
begin
if(i <= 14)
begin
val2 <= {1'b0,val2[15:1]};
i <= i+1'b1;
state_write2 <= 3'd0;
end
else if(i==15)
begin
state_write2 <= 3'd4;
val2 <= {1'b0,val2[15:1]};
end
end
3'd4: //ds=z 延時1us
begin
ds <= 1'bz;
i <= 5'd0;
state_write2 <= (`delay_1us) ? 3'd5:3'd4;
end
3'd5:
begin
work_state <= READ;
end
default:state_write2 <= 3'd0;
endcase
//讀操位
READ:
case(state_read)
3'd0: // ds=1 延時2us 讀兩個位之間應(yīng)大仵s
begin
ds <= 1'b1;
state_read <= (`delay_2us) ? 3'd1:3'd0;
end
3'd1: //ds=0 延時4us 從高拉至低電平時,總線只須保持低電庵s
begin
state_read <= (`delay_4us) ? 3'd2:3'd1;
ds <= 1'b0;
end
3'd2: //ds=1 延時4us 將總線拉高,產(chǎn)生讀時間隍
begin
state_read <= (`delay_4us) ? 3'd3:3'd2;
ds <= 1'b1;
end
3'd3:
begin
value[0] <= ds;
state_read <= 3'd4;
end
3'd4:
begin
if(j<=15)
begin
value <= {value[0], value[15:1]};
j <= j+1'b1;
state_read <= 3'd5;
end
else
begin
state_read <= 3'd6;
temp <= value;
j <= 5'd0;
end
end
3'd5://60us~120us內(nèi)釋放總線
begin
state_read <= (`delay_66us) ? 3'd0:3'd5;
end
3'd6:
begin
ds <= 1'b1;
work_state <= RESET1;
state_rest1 <= 3'd0;
state_write1<= 3'd0;
state_rest2 <= 3'd0;
state_write2<= 3'd0;
state_read <= 3'd0;
vala <= 16'h44CC;
val2 <= 16'hBECC;
flag <= 1'b1;
end
default:state_read <= 3'd0;
endcase
default:work_state <= RESET1;
endcase
end
end
//------------------------------------------------------------------------------
//產(chǎn)生18b20時序操作的延旍
//------------------------------------------------------------------------------
reg[31:0] cnt_clk_r; //時鐘計數(shù)
reg cnt_rst_n; //時鐘計數(shù)復(fù)位信號
always @ (posedge clk or negedge rst_n)
if(!rst_n) cnt_clk_r <= 32'd0; //計數(shù)寄存器復(fù)位
else if(!cnt_rst_n) cnt_clk_r <= 32'd0; //計數(shù)寄存器清雍
else cnt_clk_r <= cnt_clk_r+1'b1; //啟動計數(shù)延時
always @(*)begin
case(work_state)
RESET1:
begin
case(state_rest1)
3'd0:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
3'd1:cnt_rst_n <= (`delay_550us) ? 1'b0:1'b1;
3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
default:cnt_rst_n <= 1'b0;
endcase
end
DELAY1:
begin
cnt_rst_n <= (`delay_500us) ? 1'b0:1'b1;
end
WRITE1:
begin
case(state_write1)
3'd0:cnt_rst_n <= (`delay_2us) ? 1'b0:1'b1;
3'd1:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
3'd4:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
default:cnt_rst_n <= 1'b0;
endcase
end
DELAY2:
begin
cnt_rst_n <= (`delay_1s) ? 1'b0:1'b1;
end
RESET2:
begin
case(state_rest2)
3'd0:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
3'd1:cnt_rst_n <= (`delay_550us) ? 1'b0:1'b1;
3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
default:cnt_rst_n <= 1'b0;
endcase
end
WRITE2:
begin
case(state_write2)
3'd0:cnt_rst_n <= (`delay_2us) ? 1'b0:1'b1;
3'd1:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
3'd2:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
3'd4:cnt_rst_n <= (`delay_1us) ? 1'b0:1'b1;
default:cnt_rst_n <= 1'b0;
endcase
end
DELAY3:
begin
cnt_rst_n <= (`delay_500us) ? 1'b0:1'b1;
end
READ:
begin
case(state_read)
3'd0:cnt_rst_n <= (`delay_2us) ? 1'b0:1'b1;
3'd1:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
3'd2:cnt_rst_n <= (`delay_4us) ? 1'b0:1'b1;
3'd5:cnt_rst_n <= (`delay_66us) ? 1'b0:1'b1;
default:cnt_rst_n <= 1'b0;
endcase
end
default:cnt_rst_n <= 1'b0;
endcase
end
assign temp_dq = ds;
/*
//chipscope觀察輸出和輸入的數(shù)據(jù),檢查數(shù)據(jù)是否正硿
wire [35:0] CONTROL0;
wire [255:0] TRIG0;
chipscope_icon icon_debug (
.CONTROL0(CONTROL0) // INOUT BUS [35:0]
);
chipscope_ila ila_filter_debug (
.CONTROL(CONTROL0), // INOUT BUS [35:0]
// .CLK(dma_clk), // IN
.CLK(clk), // IN
.TRIG0(TRIG0) // IN BUS [255:0]
//.TRIG_OUT(TRIG_OUT0)
);
assign TRIG0[15:0] = temp;
assign TRIG0[31:16] = ~temp;
*/
endmodule
復(fù)制代碼
全部資料51hei下載地址:
DS18B20_drive.zip
(2.36 KB, 下載次數(shù): 31)
2018-12-11 15:13 上傳
點擊文件名下載附件
源碼
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1