主页 > 生活 > 详情
22-数码管的动态显示-头条

博客园   2023-07-06 05:35:31


【资料图】

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 仿真