当初开始做这个系统的时候苦于没有一个成熟的代码和时序图帮助理解,网上的代码往往被魔改过,在技术群里边问问题基本上不回应,有一哥们甚至想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)
|