编写Verilog HDL语言完成DS18B20的初始化工作、首先会读取DS18B20温度传感器的48位ID号、启动DS18B20温度的转换以及读取温度转化的结果。在完成读取48位ID号以及读取温度转换结果的过程后FPGA还要实现对于CRC校验码的计算用以保证在此过程当中通信数据的可靠性。以上操作反复进行可以用状态机来实现。状态机的各种状态如下:RESET1:对DS18B20温度传感器完成第一次的
以下是Verilog HDL语言代码,实现DS18B20的初始化工作、读取48位ID号、启动温度转换、读取温度转换结果以及CRC校验码计算:
module ds18b20(
input clk,
input reset,
input [7:0] cmd,
output reg [47:0] id,
output reg [11:0] temp_data
);
// 状态定义
parameter RESET1 = 2'b00;
parameter CMD33 = 2'b01;
parameter GET_ID = 2'b10;
parameter RESET2 = 2'b11;
parameter CMDCC = 2'b00;
parameter CMD44 = 2'b01;
parameter RESET3 = 2'b10;
parameter CMDCC2 = 2'b11;
parameter GET_TEMP = 2'b00;
parameter DELAY = 2'b01;
parameter WRITE_BIT = 2'b10;
parameter READ_BIT = 2'b11;
// 内部信号定义
reg [7:0] data;
reg [7:0] crc;
reg [2:0] state;
reg [3:0] bit_count;
reg [47:0] shift_reg;
// 初始化
initial begin
state = RESET1;
bit_count = 0;
end
// 状态机逻辑
always @(posedge clk) begin
if (reset) begin
state <= RESET1;
bit_count <= 0;
shift_reg <= 48'b0;
id <= 48'b0;
temp_data <= 12'b0;
end else begin
case (state)
// 复位1,等待800μs
RESET1: begin
state <= CMD33;
#800;
end
// 发送0x33命令读取ID号
CMD33: begin
data <= 8'h33;
state <= WRITE_BIT;
end
// 读取ID号
GET_ID: begin
id <= shift_reg;
state <= RESET2;
end
// 复位2,等待800μs
RESET2: begin
state <= CMDCC;
#800;
end
// 发送忽略ROM命令
CMDCC: begin
data <= 8'hCC;
state <= WRITE_BIT;
end
// 发送0x44命令启动温度转换,等待900ms
CMD44: begin
data <= 8'h44;
state <= WRITE_BIT;
#900000;
end
// 复位3
RESET3: begin
state <= CMDCC2;
end
// 发送忽略ROM命令
CMDCC2: begin
data <= 8'hCC;
state <= WRITE_BIT;
end
// 读取温度转换结果
GET_TEMP: begin
temp_data <= shift_reg[11:0];
state <= DELAY;
end
// 等待800μs
DELAY: begin
state <= READ_BIT;
#800;
end
// 写入数据位
WRITE_BIT: begin
shift_reg[bit_count] <= data[0];
crc <= crc ^ shift_reg[bit_count];
data <= {1'b1, data[7:1]};
bit_count <= bit_count + 1;
if (bit_count == 47) begin
state <= GET_ID;
end else begin
state <= READ_BIT;
end
end
// 读取数据位并进行CRC校验计算
READ_BIT: begin
data <= {data[6:0], 1'b0};
shift_reg[bit_count] <= data[0];
crc <= crc ^ shift_reg[bit_count];
bit_count <= bit_count + 1;
if (bit_count == 47) begin
state <= GET_TEMP;
end else begin
state <= WRITE_BIT;
end
end
endcase
end
end
// CRC校验模块
always @(posedge clk) begin
if (reset) begin
crc <= 8'h0;
end else begin
case (state)
// 写入数据位时清空CRC校验码
WRITE_BIT: begin
crc <= 8'h0;
end
// 读取数据位时进行CRC校验计算
READ_BIT: begin
if (crc[7]) begin
crc <= (crc << 1) ^ 8'h18;
end else begin
crc <= crc << 1;
end
end
endcase
end
end
endmodule
``
原文地址: https://www.cveoy.top/t/topic/eMdO 著作权归作者所有。请勿转载和采集!