控制 DS18B20 实现对实时温度的转换并读出来显示在数码管上。
`timescale 1ns/1ns
module ds18b20_ctrl
(
input wire sys_clk , //系统时钟,频率50MHz
input wire sys_rst_n , //复位信号,低电平有效
inout wire dq , //数据总线
output wire [19:0] data_out , //输出温度
output reg sign //输出温度符号位
);
//parameter define
parameter S_INIT = 3'd1, //初始状态
S_WR_CMD = 3'd2, //给跳过ROM及温度转换指令
S_WAIT = 3'd3, //等待温度转换完成
S_INIT_AGAIN = 3'd4, //再次回到初始化
S_RD_CMD = 3'd5, //给跳过ROM及读温度转换指令
S_RD_TEMP = 3'd6; //读温度状态
parameter WR_44CC_CMD = 16'h44cc; //跳过ROM及温度转换命令,低位在前
parameter WR_BECC_CMD = 16'hbecc; //跳过ROM及读取温度命令,低位在前
parameter S_WAIT_MAX = 750000 ; //750ms
//reg define
reg clk_1us ; //分频时钟,单位时钟1us
reg [4:0] cnt ; //分频计数器
reg [2:0] state ; //状态机状态
reg [19:0] cnt_1us ; //微秒计数器
reg [3:0] bit_cnt ; //字节计数器
reg [15:0] data_tmp ; //读取ds18b20的温度
reg [19:0] data ; //判断完正负后的温度
reg flag_pulse ; //初始化存在脉冲标志信号
reg dq_out ; //输出总线数据,即FPGA给的总线数据值
reg dq_en ; //输出总线数据使能信号
//温度转换,由于数码管位数有限,在这里保留小数点后三位
assign data_out = (data * 10'd625)/ 4'd10;
//当使能信号为1是总线的值为dq_out的值,为0时为高阻态
assign dq = (dq_en ==1 ) ? dq_out : 1'bz;
//cnt:分频计数器
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)