22-数码管的动态显示01

1.数码管动态显示

  • 不同位的数码管显示不同的数值
  • 使用动态扫描的方式,使用6位8段数码管显示1,2,3,4,5,6,选中第一个数码管让其显示1,显示时间位T;经过时间T之后选中第二个数码管显示2,显示时间为T,依次进行相似的操作,显示到6之后,经过时间T之后再显示1
  • 显示一个周期所有的时间为6个周期,6T,如果T为1s则六位8段数码管依次显示1,2,3,4,5,6显示时间间隔为1s
  • T = 0.2s,会进行闪烁显示
  • T = 1ms,闪烁频率过快,肉眼不能分辨出闪烁,近似常亮
  • 视觉暂留:人眼在观察景物的时候,光信号传递到大脑需要一定的时间,光的作用结束之后,视觉影像不会立刻消失,这种残留的视觉称之为后像,这种现象称之为视觉暂留。
  • 数码管的余晖效应:停止向数码管供电之后,数码管的亮度还能够维持一段时间。
  • 人眼可见的频率在60Hz

2.FPGA

使用6位8段数码管显示从0-999999,计数到最大值之后循环显示,每0.1s加1

2.1 模块框图

2.1.1 顶层模块框图

2.1.2 产生数据模块框图

显示的数据需要一个新的模块产生data_gen

2.1.3 数码管动态显示的模块

  • 输入信号有时钟和复位信号sys_clk,sys_rst_n
  • 需要输入数据生成模块生成的数据,seg_595_dynamic
  • 数码管动态显示芯片经常用到,所以增加一些功能,增加显示小数点的功能,输入小数点信号point,使用的是6位8段数码管,所以小数点位数是6bit
  • 增加一个符号位sign,可以用于显示符号
  • 增加一个使能端口seg_en,更好的控制数码管的显示,高电平显示数据,低电平不显示数据

2.1.4 动态显示驱动模块和控制模块

参考数码管静态显示,将seg_595_dynamic模块划分为两个模块,一个是动态显示驱动模块,第二个是595控制模块

  • seg_dynamic - 产生位选信号和段选信号

2.1.5 seg_595_dynamic框图

2.1.6 系统框图绘制

2.2 波形图

2.2.1 数据生成模块波形图

  • 生成一个计数器cnt_100ms变量对0.1s进行计数
  • 系统时钟是50MHz,周期20ns,0.1s = 100ms = 1*10^8ns
  • 计数个数:5*10^6
  • 计数最大值是:4999_999
  • 生成计数器标志信号:cnt_flag(计数器计数到最大值减一的时候拉高一个时钟周期)
  • 待显示数据生成,初值为0,在第一个0.1s内显示为0,当cnt_flag为高的时候,显示数据加1,计数到最大值,归0
  • 小数点位数据,定义为高电平小数点位有效,这里一直保持无效的低电平
  • 符号位波形绘制,高电平有效,这里一直保持为高电平(计数值都是正的)
  • 数码管使能信号,初值为低电平,这里信号始终保持高电平,因为数码管一直有效

2.3 RTL

2.3.1 数据生成模块

module data_gen
#(
  parameter CNT_MAX = 23'd4999_999,
  parameter DATA_MAX = 20'd999_999
)
(
  input wire sys_clk,
  input wire sys_rst_n,
  
  output reg [19:0] data,
  output wire [5:0] point,
  output wire sign,
  output reg seg_en
);
  
  reg [22:0] cnt_100ms;
  reg cnt_flag;

  always @ (posedge sys_clk or negedge sys_rst_clk)
    if(sys_rst_n == 1'b0)
      cnt_100ms <= 23'd0;
    else if(cnt_100ms == CNT_MAX)
      cnt_100ms <= 23'd0;
    else 
      cnt_100ms <= 23'd0 + 1'b1;

   always @ (posedge sys_clk or negedge sys_rst_clk)
    if(sys_rst_n == 1'b0)
      cnt_flag <= 1'b0;
    else if(cnt_100ms == CNT_MAX-1)
      cnt_flag <= 1'b1;
    else
      cnt_flag <= 1'b0;

   always @ (posedge sys_clk or negedge sys_rst_clk)
    if(sys_rst_n == 1'b0)
      data <= 20'd0;
    else if((data == DATA_MAX)&&(cnt_flag == 1'b1))
      data <= 20'd0;
    else if(cnt_flag == 1'b1)
      data <= data + 1'b1; 
    else
      data <= data;

  // 小数点赋值
  assign point = 6'b000_000
  // 符号位
  assign sign = 1'b0;   

  // 使能信号
  always @ (posedge sys_clk or negedge sys_rst_clk)
    if(sys_rst_n == 1'b0)
      seg_en <= 1'b0;
    else 
      seg_en <= 1'b1;
endmodule

2.3.2 数据生成模块testbench

module tb_data_gen();
  input reg sys_clk;
  input reg sys_rst_n;
  
  output wire [19:0] data;
  output wire [5:0] point;
  output wire sign;
  output wire seg_en;
  
  always #10 sys_clk = -sys_clk;
  
  module data_gen
#(
  .CNT_MAX (23'd4999_999),
  .DATA_MAX (20'd999_999)
)
(
  .sys_clk (sys_clk),
  .sys_rst_n,
  
  .data (data),
  .point (point),
  .sign (sign),
  .seg_en (seg_en)
);
    

endmodule

2.3.3 仿真

posted @ 2023-07-05 22:54  Icer_Newer  阅读(250)  评论(0编辑  收藏  举报