文章目录
一.DS18B20简介
- DS18B20数字温度传感器提供9-12bit的摄氏温度测量精度和一个用户可编程的非易失性且具有过温和低温报警功能。
- 采用单总线接口方式通信
- 每个设备内部ROM上烧写了一个独一无二的序列号
- 可以由数据线供电而不需要外部电源供电
- 测量范围在-55℃~125℃
- 在温度范围超过-10摄氏度至85摄氏度之外时还具有±0.5℃的精度
二.手册解析
1.单总线协议
- 1-Wire总线系统即一个总线主设备控制一个或多个从设备。DS18B20始终是一个从设备。当总线上只有一个从设备时,此系统被称为“单节点”系统;当总线上有多个从设备连接时,此系统被称之为“多节点”系统。
1-Wire总线上所有的命令或者数据的发送送都是遵循低位先发送的原则。
接下来关于1-Wire总线系统的描述将会分成三个部分:硬件配置,事件序列和1-Wire总线信号(信号定义和时序)。
2.DS18B20内部框图
3.DS118B20供电模式
- DS18B20可以通过外部电源供电,也可以通过“寄生电源”供电。那么什么是“寄生电源”?
上图中模式就是寄生电源模式,结合内部框图来看,DQ拉高时由其向设备供电,总线拉高时为内部电容充电,总线拉低时改由电容向设备供电。
上图中模式是外接电源模式。这样不需要上拉的MOSFET,单总线在温度转换期间可以执行其他动作。
4.温度数据
-
两字节共16bit数据存储温度数据,其中bit11-bit15存储符号位S(0为正数,1为负数);bit4-bit10存储整数部分;bit0-bit3存储小数部分(这一部分要考察精度,12位转换精度时,四位小数都会有值;11位转换精度时,bit0为未定义;10位转换精度时,bit0和bit1为未定义;9位转换精度时,bit0、bit1和bit2为未定义)
-
温度/数据关系
5.温度报警
- 过温和低温数据各存在于一个字节(8bit数据)内。我们可以理解为我们设定的一个阈值,与我们传感器测量的温度数据进行比较。其寄存器值如下
需要注意的是,过温和低温报警寄存器存储的是整数,所以我们只和温度寄存器的bit4-bit11整数部分比较。
6.64位光刻ROM编码
- 64位中,低8位为保存有DS18B20的分类编码:28h。中间的48位中保存着独一无二的序列号。最高8位保存CRC校验值
7.配置寄存器
- 一字节中两个bit数据定义之前说的转换精度
bit0-bit4和bit7作为内部使用保留,不可被写入。主要考虑其中bit5和bit6,也就是R0和R1的值 [上电默认R0=1,R1=1(12位分辨率)]
8.流程
8.1初始化
- 需要复位信号和存在脉冲(计时,状态转换条件)
8.2ROM命令
- 由于我们只有一个DS18B20传感器,所以我们只考虑跳过ROM命令
8.3DS18B20功能命令
- 这里我们只考虑温度转换命令【44h】和读取暂存器命令【BEh】
DS18B20功能命令续在ROM命令完成后开始。完成一次功能命令后,需要回到初始化状态再走一次跳过ROM命令,再进行下一个功能命令。如图中,先走红线,然后再次进入到DS18B20功能命令时走绿线。
9.时隙
-
写时段有两种情况:“写1”时段和“写0”时段。主设备通过写1时段来向DS18B20中写入逻辑1以及通过写0时段来向DS18B20中写入逻辑0。每个写时段最小必须有60us的持续时间且独立的写时段间至少有1us的恢复时间。两个写时段都是由主设备通过将1-Wire总线拉低来进行初始化。
为了形成写1时段,在将1-Wire总线拉低后,主设备必须在15us之内释放总线。当总线释放后,5kΩ的上拉电阻将总线拉至高。为了形成写0时段,在将1-Wire总线拉低后,在整个时段期间主设备必须一直拉低总线(至少60us)。
在主设备初始化写时段后,DS18B20将会在15us至60us的时间窗口内对总线进行采样。如果总线在采样窗口期间是高电平,则逻辑1被写入DS18B20;若总线是低电平,则逻辑0被写入DS18B20。
10.状态及状态转移
状态转移图如下,状态解析以及状态转移条件可以参考资源https://download.csdn.net/download/weixin_67803687/88254394
三.代码
- DS18B20_driver.v
/**************************************功能介绍***********************************
Date : 2023年8月21日16:44:25
Author : Alegg xy.
Version : 1.0
Description:
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module DS18B20_driver(
input clk ,
input rst_n ,
output [23:0] temp_data,
output reg temp_data_vld,
output dout_signed,
inout dq
);
//---------<参数定义>---------------------------------------------------------
//主状态机参数定义
localparam M_IDLE = 9'b000000001,//空闲
M_RST = 9'b000000010,//复位
M_RELE = 9'b000000100,//释放总线
M_BACK = 9'b000001000,//接受存在脉冲
M_SKIP_ROM = 9'b000010000,//跳过ROM
M_CON_T = 9'b000100000,//数据转换命令
M_WAIT = 9'b001000000,//等待750ms
RD_SCRA = 9'b010000000,//读数据命令
M_READ = 9'b100000000;//读出数据
//从状态机参数定义
localparam S_IDLE = 6'b000001,//空闲状态
S_LOW = 6'b000010,//拉低
S_SEND = 6'b000100,//发送数据
S_RECV = 6'b001000,//接受数据
S_RELE = 6'b010000,//释放总线
S_DONE = 6'b100000;//完成
parameter MAX_500us = 15'd25_000;
parameter MAX_20us = 10'd1_000;
parameter MAX_200us = 14'd10_000;
parameter MAX_750ms = 26'd37_500_000;
parameter MAX_2us = 7'd100;
parameter MAX_60us = 12'd3000;
parameter MAX_3us = 8'd150;
localparam SKIP_ROM = 8'hCC,//跳过rom指令
CON_T = 8'h44,//温度转换指令
READ_T = 8'hBE;//读取温度指令
//---------<内部信号定义>-----------------------------------------------------
reg [9:0] m_cstate ;//主状态机现态
reg [9:0] m_nstate ;//主状态机次态
reg [6:0] s_cstate ;//从状态机现态
reg [6:0] s_nstate ;//从状态机次态
reg [14:0] cnt_500us ;
wire add_cnt_500us ;
wire end_cnt_500us ;
reg [9:0] cnt_20us ;
wire add_cnt_20us ;
wire end_cnt_20us ;
reg [13:0] cnt_200us ;
wire add_cnt_200us ;
wire end_cnt_200us ;
reg [25:0] cnt_750ms ;
wire add_cnt_750ms ;
wire end_cnt_750ms ;
reg [6:0] cnt_2us ;
wire add_cnt_2us ;
wire end_cnt_2us ;
reg [11:0] cnt_60us ;
wire add_cnt_60us ;
wire end_cnt_60us ;
// reg [7:0] cnt_3us ;
// wire add_cnt_3us ;
// wire end_cnt_3us ;
reg [3:0] cnt_bit ;
wire add_cnt_bit ;
wire end_cnt_bit ;
reg slave_ack ;//判断是否接收到存在脉冲 —— 0:接受到存在脉冲、1:没有接受到存在脉冲
reg flag ;//判断命令是什么 —— 0:温度转换命令、1:温度读取命令
reg flag_bit ;//0:没写完8bit或读完16bit 1:写完8bit或读完16bit
reg OE ;//三态使能信号
reg dq_out ;
wire dq_in ;
reg [7:0] cmd ;//记录命令
reg cmd_vld ;//发送命令使能
reg [15:0] rx_data ;//接收的原始数据
wire rx_data_vld ;
reg [23:0] true_data ;//转补码处理后的温度
//主状态机状态转移条件
wire M_IDLE_M_RST;
wire M_RST_M_RELE;
wire M_RELE_M_BACK;
wire M_BACK_M_SKIP_ROM;
wire M_BACK_M_IDLE;
wire M_SKIP_ROM_M_CON_T;
wire M_SKIP_ROM_RD_SCRA;
wire M_CON_T_M_WAIT;
wire M_WAIT_M_RST;
wire RD_SCRA_M_READ;
wire M_READ_M_IDLE;
//从状态机状态转移条件
wire S_IDLE_S_LOW;
wire S_LOW_S_SEND;
wire S_LOW_S_RECV;
wire S_SEND_S_RELE;
wire S_RECV_S_RELE;
wire S_RELE_S_LOW;
wire S_RELE_S_DONE;
wire S_DONE_S_IDLE;
//500us计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_500us <= 'd0;
end
else if(add_cnt_500us)begin
if(end_cnt_500us)begin
cnt_500us <= 'd0;
end
else begin
cnt_500us <= cnt_500us + 1'd1;
end
end
end
assign add_cnt_500us = m_cstate == M_RST;
assign end_cnt_500us = add_cnt_500us && cnt_500us == MAX_500us - 1'd1;
//20us计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_20us <= 'd0;
end
else if(add_cnt_20us)begin
if(end_cnt_20us)begin
cnt_20us <= 'd0;
end
else begin
cnt_20us <= cnt_20us + 1'd1;
end
end
end
assign add_cnt_20us = m_cstate == M_RELE;
assign end_cnt_20us = add_cnt_20us && cnt_20us == MAX_20us - 1'd1;
//200us计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_200us <= 'd0;
end
else if(add_cnt_200us)begin
if(end_cnt_200us)begin
cnt_200us <= 'd0;
end
else begin
cnt_200us <= cnt_200us + 1'd1;
end
end
end
assign add_cnt_200us = m_cstate == M_BACK;
assign end_cnt_200us = add_cnt_200us && cnt_200us == MAX_200us - 1'd1;
//750ms计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_750ms <= 'd0;
end
else if(add_cnt_750ms)begin
if(end_cnt_750ms)begin
cnt_750ms <= 'd0;
end
else begin
cnt_750ms <= cnt_750ms + 1'd1;
end
end
end
assign add_cnt_750ms = m_cstate == M_WAIT;
assign end_cnt_750ms = add_cnt_750ms && cnt_750ms == MAX_750ms - 1'd1;
//2us计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_2us <= 'd0;
end
else if(add_cnt_2us)begin
if(end_cnt_2us)begin
cnt_2us <= 'd0;
end
else begin
cnt_2us <= cnt_2us + 1'd1;
end
end
end
assign add_cnt_2us = s_cstate == S_LOW || s_cstate == S_RELE;
assign end_cnt_2us = add_cnt_2us && cnt_2us == MAX_2us - 1'd1;
//60us计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_60us <= 'd0;
end
else if(add_cnt_60us)begin
if(end_cnt_60us)begin
cnt_60us <= 'd0;
end
else begin
cnt_60us <= cnt_60us + 1'd1;
end
end
end
assign add_cnt_60us = s_cstate == S_SEND || s_cstate == S_RECV || m_cstate == M_BACK;
assign end_cnt_60us = add_cnt_60us && cnt_60us == MAX_60us - 1'd1;
// //3us计数器
// always @(posedge clk or negedge rst_n)begin
// if(!rst_n)begin
// cnt_3us <= 'd0;
// end
// else if(add_cnt_3us)begin
// if(end_cnt_3us)begin
// cnt_3us <= 'd0;
// end
// else begin
// cnt_3us <= cnt_3us + 1'd1;
// end
// end
// end
// assign add_cnt_3us = s_cstate == S_RELE;
// assign end_cnt_3us = add_cnt_3us && cnt_3us == MAX_3us - 1'd1;
//bit计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_bit <= 'd0;
end
else if(add_cnt_bit)begin
if(end_cnt_bit)begin
cnt_bit <= 'd0;
end
else begin
cnt_bit <= cnt_bit + 1'd1;
end
end
end
assign add_cnt_bit = S_SEND_S_RELE || S_RECV_S_RELE;
assign end_cnt_bit = add_cnt_bit && cnt_bit == (m_cstate == M_READ ? 16 - 1 : 8 - 1);
//定义flag
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
flag <= 'd0;
end
else if (M_WAIT_M_RST) begin
flag <= 'd1;
end
else if (M_READ_M_IDLE) begin
flag <= 'd0;
end
end
//定义flag_bit
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
flag_bit <= 'b0;
end
else if (end_cnt_bit) begin
flag_bit <= 'b1;
end
else if (s_cstate == S_DONE) begin
flag_bit <= 'b0;
end
end
//定义slave_ack存在脉冲
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
slave_ack <= 'd0;
end
else if (m_cstate == M_RST) begin
slave_ack <= 'd0;
end
else if (m_cstate == M_BACK && end_cnt_200us) begin
slave_ack <= dq;
end
end
//主状态机第一段
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
m_cstate <= M_IDLE;
end
else begin
m_cstate <= m_nstate;
end
end
//主状态机第二段
always @(*) begin
case(m_cstate)
M_IDLE : begin
if (M_IDLE_M_RST) begin
m_nstate = M_RST;
end
else begin
m_nstate = m_cstate;
end
end
M_RST : begin
if (M_RST_M_RELE) begin
m_nstate = M_RELE;
end
else begin
m_nstate = m_cstate;
end
end
M_RELE : begin
if (M_RELE_M_BACK) begin
m_nstate = M_BACK;
end
else begin
m_nstate = m_cstate;
end
end
M_BACK : begin
if (M_BACK_M_SKIP_ROM) begin
m_nstate = M_SKIP_ROM;
end
else if (M_BACK_M_IDLE) begin
m_nstate = M_IDLE;
end
else begin
m_nstate = m_cstate;
end
end
M_SKIP_ROM : begin
if (M_SKIP_ROM_M_CON_T) begin
m_nstate = M_CON_T;
end
else if (M_SKIP_ROM_RD_SCRA) begin
m_nstate = RD_SCRA;
end
else begin
m_nstate = m_cstate;
end
end
M_CON_T : begin
if (M_CON_T_M_WAIT) begin
m_nstate = M_WAIT;
end
else begin
m_nstate = m_cstate;
end
end
M_WAIT : begin
if (M_WAIT_M_RST) begin
m_nstate = M_RST;
end
else begin
m_nstate = m_cstate;
end
end
RD_SCRA : begin
if (RD_SCRA_M_READ) begin
m_nstate = M_READ;
end
else begin
m_nstate = m_cstate;
end
end
M_READ : begin
if (M_READ_M_IDLE) begin
m_nstate = M_IDLE;
end
else begin
m_nstate = m_cstate;
end
end
default : m_nstate = M_IDLE;
endcase
end
assign M_IDLE_M_RST = (m_cstate == M_IDLE) && 1'b1;
assign M_RST_M_RELE = (m_cstate == M_RST) && end_cnt_500us;//500us
assign M_RELE_M_BACK = (m_cstate == M_RELE) && end_cnt_20us;//20us
assign M_BACK_M_SKIP_ROM = (m_cstate == M_BACK) && end_cnt_200us && slave_ack == 1'b0;//200us并且接受到存在信号
assign M_BACK_M_IDLE = (m_cstate == M_BACK) && end_cnt_200us && slave_ack == 1'b1;//200us并且没接受到存在信号
assign M_SKIP_ROM_M_CON_T = (m_cstate == M_SKIP_ROM) && (s_cstate == S_DONE && flag == 0);//发送完跳过rom命令后,发送温度转换命令
assign M_SKIP_ROM_RD_SCRA = (m_cstate == M_SKIP_ROM) && (s_cstate == S_DONE && flag == 1);//发送完跳过rom命令后,发送温度读取命令
assign M_CON_T_M_WAIT = (m_cstate == M_CON_T) && (s_cstate == S_DONE);//主机发送完8bit的温度转换命令
assign M_WAIT_M_RST = (m_cstate == M_WAIT) && end_cnt_750ms;//750ms
assign RD_SCRA_M_READ = (m_cstate == RD_SCRA) && (s_cstate == S_DONE);//主机发送完8bit的读取温度命令
assign M_READ_M_IDLE = (m_cstate == M_READ) && (s_cstate == S_DONE);//主机收到16bit的温度数据
//从状态机第一段
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
s_cstate <= S_IDLE;
end
else begin
s_cstate <= s_nstate;
end
end
//从状态机第二段
always @(*) begin
case(s_cstate)
S_IDLE :begin
if (S_IDLE_S_LOW) begin
s_nstate = S_LOW;
end
else begin
s_nstate = s_cstate;
end
end
S_LOW :begin
if (S_LOW_S_RECV) begin
s_nstate = S_RECV;
end
else if (S_LOW_S_SEND) begin
s_nstate = S_SEND;
end
else begin
s_nstate = s_cstate;
end
end
S_SEND :begin
if (S_SEND_S_RELE) begin
s_nstate = S_RELE;
end
else begin
s_nstate = s_cstate;
end
end
S_RECV :begin
if (S_RECV_S_RELE) begin
s_nstate = S_RELE;
end
else begin
s_nstate = s_cstate;
end
end
S_RELE :begin
if (S_RELE_S_LOW) begin
s_nstate = S_LOW;
end
else if (S_RELE_S_DONE) begin
s_nstate = S_DONE;
end
else begin
s_nstate = s_cstate;
end
end
S_DONE:begin
if (S_DONE_S_IDLE) begin
s_nstate = S_IDLE;
end
else begin
s_nstate = s_cstate;
end
end
S_DONE :s_nstate = S_IDLE;
default : s_nstate = S_IDLE;
endcase
end
assign S_IDLE_S_LOW = (s_cstate == S_IDLE) && (m_cstate == M_READ || m_cstate == RD_SCRA || m_cstate == M_SKIP_ROM || m_cstate == M_CON_T);//这四个状态用到发送命令或接收数据开始运转从状态机
assign S_LOW_S_SEND = (s_cstate == S_LOW) && (m_cstate == RD_SCRA || m_cstate == M_SKIP_ROM || m_cstate == M_CON_T) && end_cnt_2us;//发送命令的三个主状态机状态,并拉低2us
assign S_LOW_S_RECV = (s_cstate == S_LOW) && (m_cstate == M_READ) && end_cnt_2us;//接收数据的主状态机状态,并拉低2us
assign S_SEND_S_RELE = (s_cstate == S_SEND) && end_cnt_60us;//发送1bit数据用60us
assign S_RECV_S_RELE = (s_cstate == S_RECV) && end_cnt_60us;//接收1bit数据用60us
assign S_RELE_S_LOW = (s_cstate == S_RELE) && end_cnt_2us && flag_bit == 1'b0;//没有写满8bit或读完16bit
assign S_RELE_S_DONE = (s_cstate == S_RELE) && end_cnt_2us && flag_bit == 1'b1;//写满8bit或读满16bit
assign S_DONE_S_IDLE = (s_cstate == S_DONE) && 1'b1;
//定义OE
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
OE <= 'b0;
end
else if(M_IDLE_M_RST || M_BACK_M_SKIP_ROM || M_SKIP_ROM_M_CON_T || M_SKIP_ROM_RD_SCRA || S_IDLE_S_LOW || S_RELE_S_LOW || M_WAIT_M_RST) begin
OE <= 'b1;
end
else if (M_RST_M_RELE || M_CON_T_M_WAIT || S_SEND_S_RELE || S_LOW_S_RECV) begin
OE <= 'b0;
end
end
assign dq = OE ? dq_out : 1'bz;
assign dq_in = dq;
//描述cmd
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cmd <= 8'h00;
end
else begin
case (m_cstate)
M_SKIP_ROM : cmd <= SKIP_ROM ;
M_CON_T : cmd <= CON_T ;
RD_SCRA : cmd <= READ_T ;
default: cmd <= 8'h00;
endcase
end
end
//描述cmd_vld
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cmd_vld <= 'b0;
end
else if (M_BACK_M_SKIP_ROM || M_SKIP_ROM_M_CON_T || M_SKIP_ROM_RD_SCRA || RD_SCRA_M_READ) begin
cmd_vld <= 'b1;
end
else begin
cmd_vld <= 'b0;
end
end
//描述dq_out
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
dq_out <= 'b0;
end
else if (M_IDLE_M_RST || M_WAIT_M_RST || S_IDLE_S_LOW || S_RELE_S_LOW) begin
dq_out <= 'b0;
end
else if (S_LOW_S_SEND) begin
dq_out <= cmd[cnt_bit];
end
end
//****************************************************************
//--接收数据&数据处理
//****************************************************************
//接收原始数据
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rx_data <= 'd0;
end
else if (s_cstate == S_RECV && cnt_60us == MAX_60us / 10) begin//计数器0-15us采样
rx_data <= {dq_in,rx_data[15:1]};
end
end
assign rx_data_vld = m_cstate == M_READ && S_DONE_S_IDLE;
//原始数据处理,考虑正负数,取补码
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
true_data <= 0;
end
else if (rx_data_vld) begin
if (rx_data[15]) begin//符号位为1,负数
true_data <= ~rx_data[10:0] + 1;//取反加一
end
else begin
true_data <= rx_data[10:0];//正数原码补码相同
end
end
end
//数据扩大10000*精度(0.0625)
assign temp_data = true_data * 'd625;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
temp_data_vld <= 'b0;
end
else begin
temp_data_vld <= rx_data_vld;
end
end
assign dout_signed = rx_data[15];
endmodule
- seg_driver.v
/**************************************功能介绍***********************************
Date :
Author : Alegg xy.
Version :
Description:
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module seg_driver(
input clk ,
input rst_n ,
input [23:0] temp_data,
input [5:0] point_n ,
output reg [5:0] sel ,
output reg [7:0] seg
);
//---------<参数定义>---------------------------------------------------------
parameter MAX_1ms = 50_000;//1ms
//---------<内部信号定义>-----------------------------------------------------
reg [3:0] data;//存数据
reg [5:0] point_n_r;//存小数点位
reg [15:0] cnt_1ms ;
wire add_cnt_1ms ;
wire end_cnt_1ms ;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_1ms <= 'd0;
end
else if(add_cnt_1ms)begin
if(end_cnt_1ms)begin
cnt_1ms <= 'd0;
end
else begin
cnt_1ms <= cnt_1ms + 1'b1;
end
end
end
assign add_cnt_1ms = 1'b1;
assign end_cnt_1ms = add_cnt_1ms && cnt_1ms == MAX_1ms - 1'd1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
sel <= 6'b111_110;
end
else if (end_cnt_1ms) begin
sel <= {sel[4:0],sel[5]};
end
end
always @(*)begin
case (sel)
6'b111_110:begin data = (temp_data / 10000) / 100 ; point_n_r = point_n[0]; end
6'b111_101:begin data = ((temp_data / 10000) % 100) / 10 ; point_n_r = point_n[1]; end
6'b111_011:begin data = (temp_data / 10000) % 10 ; point_n_r = point_n[2]; end
6'b110_111:begin data = (temp_data % 10000) / 1000 ; point_n_r = point_n[3]; end
6'b101_111:begin data = ((temp_data % 10000) % 1000) / 100 ; point_n_r = point_n[4]; end
6'b011_111:begin data = ((temp_data % 10000) % 100) / 10 ; point_n_r = point_n[5]; end
default: data = 4'd0;
endcase
end
always @(*)begin
case (data)
4'h0:seg = {point_n_r,7'b100_0000};
4'h1:seg = {point_n_r,7'b111_1001};
4'h2:seg = {point_n_r,7'b010_0100};
4'h3:seg = {point_n_r,7'b011_0000};
4'h4:seg = {point_n_r,7'b001_1001};
4'h5:seg = {point_n_r,7'b001_0010};
4'h6:seg = {point_n_r,7'b000_0010};
4'h7:seg = {point_n_r,7'b111_1000};
4'h8:seg = {point_n_r,7'b000_0000};
4'h9:seg = {point_n_r,7'b001_0000};
default: seg = 8'b1100_0000;
endcase
end
endmodule