當初開始做這個系統的時候苦于沒有一個成熟的代碼和時序圖幫助理解,網上的代碼往往被魔改過,在技術群里邊問問題基本上不回應,有一哥們甚至想1000塊賣我代碼……后來灑家爆肝一周把寫出代碼又調試完畢。本人比較認同黑客精神,認為網上的學習資源應該是免費使用的。因此在這里將灑家的代碼和仿真文件、仿真圖一并奉上,以供參考。如有不足,希望大家多多包涵指正。
Verilog源程序如下:
- module ds18b20_top
- (
- clkin,//時鐘
- resetin,//復位信號輸入
- ds18b20_bus,//ds18b20控制信號
- wrong,//錯誤信號
- temperature,//溫度輸出
- read//讀溫度命令
- );
- input clkin,resetin,read;
- inout ds18b20_bus;
- output[15:0] temperature;
- output wrong;
- parameter reset1 = 1, //初始化
- data1_1 = reset1 + 1000,//1000 寫0xcc
- data1_2 = data1_1 + 600,//1600 寫0x44
- reset2 = data1_2 + 600,//2200 初始化
- data2_1 = reset2 + 1000,//3200 寫0xcc
- data2_2 = data2_1 + 600,//3800 寫0xbe
- read1 = data2_2 + 600,//4400 讀低字節
- read2 = read1 + 600,//5000 讀高字節
- read_end = read2 + 600;//5600
-
- assign temperature = {tempH, tempL};
- reg[7:0] tempH, tempL;//溫度高字節 溫度低字節
- wire[7:0] temp;//
- wire[1:0] command;
- reg[1:0] state;
- reg divider_reset, ds18b20_reset, wrong;
- wire ds18b20_ok;
- //分頻時鐘
- wire clk_1MHz;
- reg start, stop;
- reg[8:0] ds18b20_byte_write;
- reg[15:0] clk_count;
- Divider Divide_1MHz(.reset(divider_reset), .clkin(clkin), .clkout(clk_1MHz));
- ds18b20_byte ds18b20(.clkin(clkin),
- .resetin(start),
- .ds18b20_command(ds18b20_byte_write),
- .ds18b20_bus(ds18b20_bus),
- .ds18b20_read(temp),
- .ds18b20_reset(ds18b20_reset),
- .ds18b20_ok(ds18b20_ok),
- );
-
- always @ (negedge resetin or posedge clk_1MHz)
- if (!resetin)
- begin
- divider_reset<=1'b1;
- start<=0;
- clk_count<=0;
- ds18b20_reset<=0;
- wrong<=0;
- tempL<=0;
- tempH<=0;
- stop<=0;
- end
- else
- begin
- //send 0xcc 0x44
- case(clk_count)
- reset1 - 1: ds18b20_reset<=1;
- reset1:start<=1;
- data1_1 - 1://數據準備
- begin
- if(ds18b20_ok!=1'b1)
- begin
- wrong<=1;
- stop<=1;
- end
- else
- begin
- start<=0;
- ds18b20_reset<=0;
- ds18b20_byte_write<={8'hcc, 1'b1};
- end
- end
- data1_1:start<=1;//數據發送
- data1_2 - 2://數據準備
- begin
- ds18b20_byte_write<={8'h44, 1'b1};
- start<=0;
- end
- data1_2:start<=1;//數據發送
- //send 0xcc 0xbe
- reset2 - 2:
- begin
- ds18b20_reset<=1;
- start<=0;
- if(!read)
- stop<=1;
- end
- reset2 - 1:
- begin
- if(read)
- stop<=0;
- end
- reset2:start<=1;
- data2_1 - 2://等待讀命令輸入
- begin
- if(ds18b20_ok!=1'b1)
- begin
- wrong<=1;
- stop<=1;
- end
- else
- begin
- start<=0;
- ds18b20_reset<=0;
- ds18b20_byte_write<={8'hcc, 1'b1};
- end
- end
- data2_1:start<=1;//開始讀溫度
- data2_2 - 2:
- begin
- ds18b20_byte_write<={8'hbe, 1'b1};
- start<=0;
- end
- data2_2:start<=1;
- read1 - 2://低字節
- begin
- ds18b20_byte_write<={8'h00, 1'b0};
- start<=0;
- end
- read1:start<=1;
- read2 - 2:
- begin
- tempL<=temp;
- start<=0;
- end
- read2:start<=1;//prepare for read, get tempH
- read_end://高字節
- begin
- start<=0;
- tempH<=temp;
- stop<=1;
- end
- endcase
- if(!stop)
- clk_count<=(clk_count+1)%8000;
- end
- endmodule
復制代碼
所有資料51hei提供下載:
ds18b20.zip
(8.75 KB, 下載次數: 61)
2019-9-7 15:25 上傳
點擊文件名下載附件
ds18b20的verilog編程文件以及quartus2仿真文件
|