• 【连载】 FPGA Verilog HDL 系列实例七段数码管扫描显示


    【连载】 FPGA Verilog HDL 系列实例

    Verilog HDL 之 七段数码管扫描显示

    原理:

      一般来说,多个数码管的连接并不是把每个数码管都独立的与可编程逻辑器件连接,而是把所有的LED管的输入连在一起。如图1.1所示。

        

                          图1.1 扫描数码管的原理图

      这样做的好处有两点:一是节约了器件的IO口;其二是降低了功耗。每次向LED写数据时,通过片选选通其中一个LED,然后把数据写入该LED管,因此每个时刻只有一个LED管是亮的。为了能持续看见LED上面的显示内容,必须对LED管进行扫描,即依次并循环地点亮各个LED管。利用人眼的视觉暂停效应,在一定的扫描频率下,人眼就会看见好几个LED一起点亮。每个LED的功耗较大,如果所有的LED一起点亮,其功耗较大。利用扫描的方式,每个时刻只有LED管是亮的,可以大大的减少功耗。
      扫描频率大小不许合适才能有很好的效果。如果太小,而每个LED开启的时间大于人眼的视觉暂停时间,那么会产生闪烁现象。而扫描频率太大,则会造成LED的频繁开启和关断,大大增加LED功耗(开启和关断的时刻功耗很大)。一般来说,稍描频率选在50Hz比较合适。

    实验实现:

      实现步骤请参照 【连载】 FPGA Verilog HDL 系列实例--------8-3编码器。这里就不再赘述。

    设计文件输入Verilog HDL代码。

    View Code
     1 //-------------------------------------------------------------------------------------------------
    2 //
    3 // File : scan_seg.v
    4 // Generated : 2011-07-23
    5 // Author : wangliang
    6 //
    7 //-------------------------------------------------------------------------------------------------
    8
    9 `timescale 1 ns / 1 ps
    10
    11 module scan_seg ( rst ,clk ,DIG ,Y );
    12
    13 input rst ;
    14 wire rst ;
    15 input clk ;
    16 wire clk ;
    17
    18 output [7:0] DIG ;
    19 wire [7:0] DIG ;
    20 output [7:0] Y ;
    21 wire [7:0] Y ;
    22
    23 reg clkout ;
    24 reg [31:0]cnt;
    25 reg [2:0]scan_cnt ;
    26
    27 parameter period= 100000;
    28
    29 assign Y = {1'b1,(~Y_r[6:0])};
    30 assign DIG =~DIG_r;
    31 reg [6:0] Y_r;
    32 reg [7:0] DIG_r ;
    33
    34 always @( posedge clk or negedge rst) //分频50Hz
    35 begin
    36 if (!rst)
    37 cnt <= 0 ;
    38 else begin
    39 cnt<= cnt+1;
    40 if (cnt == (period >> 1) - 1)
    41 clkout <= #1 1'b1;
    42 else if (cnt == period - 1)
    43 begin
    44 clkout <= #1 1'b0;
    45 cnt <= #1 'b0;
    46 end
    47
    48 end
    49 end
    50
    51 always @(posedge clkout or negedge rst)
    52 begin
    53 if (!rst)
    54 scan_cnt <= 0 ;
    55 else begin
    56 scan_cnt <= scan_cnt + 1;
    57 if(scan_cnt==3'd7) scan_cnt <= 0;
    58 end
    59 end
    60
    61 always @( scan_cnt) //数码管选择
    62 begin
    63 case ( scan_cnt )
    64 3'b000 : DIG_r <= 8'b0000_0001;
    65 3'b001 : DIG_r <= 8'b0000_0010;
    66 3'b010 : DIG_r <= 8'b0000_0100;
    67 3'b011 : DIG_r <= 8'b0000_1000;
    68 3'b100 : DIG_r <= 8'b0001_0000;
    69 3'b101 : DIG_r <= 8'b0010_0000;
    70 3'b110 : DIG_r <= 8'b0100_0000;
    71 3'b111 : DIG_r <= 8'b1000_0000;
    72 default :DIG_r <= 8'b0000_0000;
    73 endcase
    74 end
    75
    76 always @ (scan_cnt ) //译码
    77 begin
    78 case (scan_cnt)
    79 0: Y_r = 7'b0111111; // 0
    80 1: Y_r = 7'b0000110; // 1
    81 2: Y_r = 7'b1011011; // 2
    82 3: Y_r = 7'b1001111; // 3
    83 4: Y_r = 7'b1100110; // 4
    84 5: Y_r = 7'b1101101; // 5
    85 6: Y_r = 7'b1111101; // 6
    86 7: Y_r = 7'b0100111; // 7
    87 8: Y_r = 7'b1111111; // 8
    88 9: Y_r = 7'b1100111; // 9
    89 10: Y_r = 7'b1110111; // A
    90 11: Y_r = 7'b1111100; // b
    91 12: Y_r = 7'b0111001; // c
    92 13: Y_r = 7'b1011110; // d
    93 14: Y_r = 7'b1111001; // E
    94 15: Y_r = 7'b1110001; // F
    95 default: Y_r = 7'b0000000;
    96 endcase
    97 end
    98
    99 endmodule

    代码分析:

      可以看出这部分代码由4部分组成,第一部分是分频,因为我们扫描数码管不需要很快的频率,第二部分是选择控制数码管的位置,第三部分是对第二部分的译码,第四部分是显示数据。

    引脚分配:

      由Verilog HDL设计文件生成的.bsf文件如图1.2所示

     

            图1.2 七段数码管的外部接口图

      clk接系统时钟,rst接复位信号,DIG[7..0]接选择的的数码管(控制显示在哪一个数码管上),Y[7..0]接数码管的显示位(控制显示什么数字)。

    实验结果:

      在上面的数码管上从前到后一次显示76543210.

  • 相关阅读:
    MySQL显示数据库版本的SQL语句
    如何清空ostringstream对象中的内容
    C/C++中的Split函数
    关于socket长连接的心跳包
    利用MyEclipse配置S2SH三大框架篇-Spring配置
    利用MyEclipse配置S2SH三大框架篇-struts2配置
    Oracle OCP 11G 051答案解析目录
    AFX_EXT_CLASS
    C++中的explicit关键字
    SSH2三大框架整合警告
  • 原文地址:https://www.cnblogs.com/kongtiao/p/2114618.html
Copyright © 2020-2023  润新知