资讯详情

FPGA零基础学习:数码管驱动设计

开发板上有六位一体的数码管,可以用数码管显示一些数据。

通过电阻直接与数字管有八个段选信号FPGA连接;三极管连接有六个供电端。三极管的控制端由三八翻译器的输出控制,三八翻译器的输入由三八翻译器控制FPGA控制输出。

数码管也称LED数码管,不同行业人士对数码管的称呼不一样,其实都是同样的产品。

数码管可分为七段数码管和八段数码管。八段数码管比七段数码管多一个发光二极管单元,即多一个小数点(DP)这个小数点可以更准确地表示数字管想要显示的内容;可分为1、2、3、4、5、6、7等数字管。

根据发光二极管单元的连接方式,可分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极连接在一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到 5V,当一个字段发光二极管的阴极是低电平时,相应的字段被点亮,当一个字段的阴极是高电平时,相应的字段就不亮了。共阴数码管是指将所有发光二极管的阴极连接在一起形成公共阴极(COM)在应用数字管和共阴数字管时,应使用公共极端COM接到地线GND当一个字段发光二极管的阳极是高电平时,相应的字段就会被点亮,当一个字段的阳极是低电平时,相应的字段就不会被点亮。

例如,如果要显示数字1B、C段亮,其他段不亮就够了。

数字管动态显示接口是单片机中应用最广泛的显示方式之一。动态驱动是所有数字管的8个显示笔划"a,b,c,d,e,f,g,dp"同名端连接在一起,是每个数字管的公共极COM增加位选通控制电路,位选通独立I/O线控制,当FPGA输出字形码时,所有数字管都收到相同的字形码,但哪个数字管会显示字形取决于FPGA对位选通COM端电路的控制,所以只要打开需要显示的数码管的选通控制,这个位置就会显示字形,没有选通的数码管就不会亮。

开发板上的数字管是共阳极数字管,是动态显示接口COM端三极管是PNP三极管,所以输出低电时,三极管导通。

三八译码器的原理是C、B、A根据C、B、A输入值,相应选择Y(低电平选择)。

三八译码器的使能端已经通过电路固定,一直处于使能状态。FPGA只需要控制C、B、A然后选择相应的数码管。

通过分时轮流控制轮流控制COM端,使每个数字管轮流控制显示,这就是动态驱动。在轮流显示过程中,每个数字管的点亮时间为1~2ms,由于人类的视觉暂留现象和发光二极管的余辉效应,虽然数字管不同时点亮,但只要扫描速度足够快,印象是一组稳定的显示数据,没有闪烁感,动态显示效果和静态显示相同,可以节省很多I/O端口,功耗更低。

每个数字管都可以显示十进制0~9,或显示16进制0~9以及A~F。一个数字管可以显示任何四位二进制,六个数字管可以显示任何24位二进制。

24位二进制实际上分为6组四位二进制,分别显示在相应的数字管上。

设计时,首先设计1ms的计时器。1ms切换一次选定的管道;根据选定的管道,选择相应的四位二进制,然后将二进制翻译成相应的段选信号输出。

共阳极数码管段选信号码表为:

该模块命名为seven_tube_drive。

编写代码时,将data信号作为端口信号,由于下板时没有外界提供,下板时会从端口省略信号,直接在内部产生固定值。

设计一个1ms计数器,每1ms切换要点亮的数码管。根据要点亮的位置,从data在24位中选择相应的四位,然后将四位数据翻译成段选信号。

设计代码为:

module seven_tube_drive (      input   wire            clk,   input   wire            rst_n,      input   wire    [23:0]  data,      output  reg     [7:0]   seven_tube_seg_n,   output  reg     [2:0]   seven_tube_sel );    localparam  T_1ms   =   50_000;      reg             [15:0]  cnt;   reg             [2:0]   sel;   reg             [3:0]   show_data;      always @ (posedge clk, negedge rst_n) begin     if (rst_n == 1'b0)       cnt <= 16'd0;     else       if (cnt < T_1ms - 1'b1)         cnt <= cnt   1'b1;       else         cnt <= 16'd0;   end      always @ (posedge clk, negedge rst_n) begin     if (rst_n == 1'b0)       sel <= 3'd0;     else       if (cnt == T_1ms - 1'b1)         if (sel < 3'd5)           sel <= sel   1'b1;         else           sel <= 3'd0;       else         sel <= sel;   end      always @ (posedge clk) seven_tube_sel <= sel;      always @ * begin     case (sel)       3'd0    :   show_data = data[23:20];       3'd1    :   show_data = data[19:16];       3'd2    :   show_data = data[15:12];       3'd3    :   show_data = data[11:8];       3'd4    :   show_data = data[7:4];       3'd5    :   show_data = data[3:0];       default :   show_data = 4'd0;     endcase   end    always @ (posedge clk, negedge rst_n) begin     if (rst_n == 1'b0)       seven_tube_seg_n <= 8'hff;     else       case (show_data)         4'd0    :  seven_tube_seg_n <= 8'b1100_0000;         4'd1    :  seven_tube_seg_n <= 8'b1111_1001;         4'd2    :  seven_tube_seg_n <= 8'ha4;         4'd3    :  seven_tube_seg_n <= 8'hb0;         4'd4    :  seven_tube_seg_n <= 8'h99;         4'd5    :  seven_tube_seg_n <= 8'h92;         4'd6    :  seven_tube_seg_n <= 8'h82;         4'd7    :  seven_tube_seg_n <= 8'hf8;         4'd8            :     seven_tube_seg_n <= 8'h80;         4'd9    :  seven_tube_seg_n <= 8'h90;         4'd10    :  seven_tube_seg_n <= 8'h88;         4'd11    :  seven_tube_seg_n <= 8'h83;         4'd12    :  seven_tube_seg_n <= 8'hc6;         4'd13    :  seven_tube_seg_n <= 8'ha1;         4'd14    :  seven_tube_seg_n <= 8'h86;         4'd15    :  seven_tube_seg_n <= 8'h8e;         default        :  seven_tube_seg_n <= 8'hff;       endcase   end  endmodule 

在设计中,定义了一个sel寄存器,端口seven_tube_sel为sel寄存器的寄存信号在时间顺序上会比较sel晚一拍。show_data信号的产生是利用sel寄存器和外部data时序上和sel同步;端口seven_tube_seg_n为show_data信号的寄存信号在时间顺序上会比较show_data晚一拍信号。因此seven_tube_seg_n和seven_tube_sel信号是同步的,都比sel晚一拍信号。此时数码管不会出现鬼影。

当数码管的seven_tube_sel和seven_tube_seg_n当不同步时,选定的管道和要显示的数字将不完全同步。由于不同步时间相对较少,错误数字显示时间较短,照明程度较小,称为鬼影。

模拟时,将T_1ms将参数修改为10。

data按照16进制的方式赋值数据,赋值后不要更改,否则不利于仿真图的查看。

仿真代码为:

`timescale 1ns/1ps  module seven_tube_drive_t;

  reg                 clk;
  reg                 rst_n;
  
  reg     [23:0]      data;
  
  wire    [7:0]       seven_tube_seg_n;
  wire    [2:0]       seven_tube_sel;
  
  seven_tube_drive seven_tube_drive_inst(
  
      .clk                (clk),
      .rst_n              (rst_n),
      
      .data               (data),
      
      .seven_tube_seg_n   (seven_tube_seg_n),
      .seven_tube_sel     (seven_tube_sel)
    );
    
  initial clk = 1'b0;
  always # 10 clk = ~clk;
  
  initial begin
    rst_n = 1'b0;
    data = 24'h123456;
    # 201
    rst_n = 1'b1;
    # 5000
    $stop;
  end

endmodule

在仿真图中,将cnt、sel、show_data信号调出;将data信号设置为十六进制显示,cnt设置为无符号位显示,sel设置为无符号位显示,show_data设置为十六进制显示。

可以从图中看出,设计符合我们的设计要求。

下板时,将T_1ms修改为50_000。并且将部分设计代码修改为下列格式:

module seven_tube_drive (
  
  input   wire            clk,
  input   wire            rst_n,
  
//  input   wire    [23:0]  data,
  
  output  reg     [7:0]   seven_tube_seg_n,
  output  reg     [2:0]   seven_tube_sel
);

  wire            [23:0]  data;
  assign data = 24'h123456;
  
  localparam  T_1ms   =   50_000;
  
  reg             [15:0]  cnt;
  reg             [2:0]   sel;
  reg             [3:0]   show_data;
  ······

进行分析综合后,进行分配管脚。下板后,就可以看到数码管上显示123456。

设计者可以修改data的赋值,再次综合后,观测数码管显示数据是否正确。

测试完成后,在后续使用过程中,还是需要将data设置为端口,以供给其他模块进行驱动。

 大家好,我是【FPGA功夫熊猫】精益求精,不断推荐好文章。

 

 

 

标签: d1o47三极管参数三极管dp3080d5d电阻

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台