FPGA Verilog HDL 系列实例---七段数码管扫描显示

2016-07-29  醉饮千殇v
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代码。
  
  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.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章
    喜欢该文的人也喜欢 更多