专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

LED阵列之FPGA显示

作者:kb129   来源:kb129   点击数:  更新时间:2014年06月08日   【字体:
   LED阵列已经普遍使用在我们生活中,出去逛逛随处可见。不太清楚业内是使用什么来控制显示的,估计用单片机,毕竟便宜多了。作为一个搞电子的,一定要了解LED阵列显示。我的理解:LED阵列显示主要有两种:静态显示,滚动显示。

一:静态显示    

  LED阵列显示有些类似于数码管显示,都是扫描显示。这里略讲讲原理:在我们看到的LED阵列显示一个画面或是一行字,其实在硬件显示的时候,应该是一行一行或是一列一列来显示。例如8*8led阵列,在我使用过程中,显示方式是一列一列的显示,也就是先点亮第一列led,其他列都不亮,然后点亮第二列led,其他列都不亮,依次到第八列,然后又回来点亮第一列,以此循环。这样就能实现led阵列的静态显示。

二:左移或右移显示   

      led滚动显示是一个不容易理解的显示方式。实际使用中,可以看到,led阵列都是一行字缓慢的向左或是向右移动。

      显示方法:一列一列显示。(如果是上下移动,则选择一行一行显示)

思考的方向:单独考虑每一列数值的改变,先考虑第一列在滚动显示过程中数值有哪些。

举例说明:


就像上图我们要滚动显示一个字母T,从最上面图1一直右移到最后一个图,然后又回到了图1,这就是典型的滚动循环显示。
按照上面的思考方法来做,假定最左边为第一列,最右边为第八列。首先考虑在滚动显示中第一列的数据变化:

    8'h00,  8'h00,  8'h00,  8'h40,  8'h40,  8'h7e,  8'h40,  8'h40

第二列数据变化:

    8'h40,   8'h00, 8'h00,  8'h00,  8'h40,  8'h40,  8'h7e,  8'h40

对比第一列数据和第二列数据,会发现第一列第一张图的数据8'h00,是第二列第二张图的数据8'h00.


由此可知:对于右移滚动循环显示,所有列的数据都是同样的,也就是,如果把列出现的所有数据存在一个数组或是库里面,所有列的数据都可以在该数组或是库取。这就诞生了网上很多字模软件,我们只要知道第一张图上面所有列的数据,然后存在一个数组里面,显示的时候只需要每一列取不同的值即可。

具体代码没有保存,故不贴出来。

三:最外围顺时针滚动显示

      之所以特别说说这个显示,是因为上周末,和朋友逛校园。走到体育馆,她指着体育馆门口的led,跟我讲,最外围的那一圈一直在顺时针旋转怎么做到的。当时觉得很少见,琢磨难道是横着的设置为左右移动,竖着的设置为上下移动。接着就想,那么怎么在同一个显示中,既使用上下移动模式,又使用左右移动模式,想了很久。昨晚自己在纸上乱画了一下,发现方法还是和上面一样。


其实在旋转过程中,每一列的数据还是周期发生变化,

拿第一列(最左边一列)举例:变化的值为:8'h99, 8'h33,8'h66,8'hCC.这样就可以将问题转换到第二种显示,所以在led阵列显示中,如果是一列一列的显示,需要着重考虑每一列的数据的变化;如果是一行一行的显示,需要着重考虑的是每一行的数据变化。

verilog代码为:(其中中行为1,列为0则led亮)

//pro : 8*8 led show
//data: 2014-04-23 qs336
//info: this is a pro exe that play the show of 8*8 led
module led88(
    input                     clk,
    output     reg [7:0] R,   //this is row
    output     reg [7:0] L
);
integer cnt1,cnt2,cnt3;
reg clk_lk,clk_h;
reg [2:0] p;
reg [1:0] i;
reg [7:0] char0[3:0];
reg [7:0] char1[3:0];
reg [7:0] char2[3:0];
reg [7:0] char3[3:0];
reg [7:0] char4[3:0];
reg [7:0] char5[3:0];
reg [7:0] char6[3:0];
reg [7:0] char7[3:0];

always@(posedge clk )
begin
      char0[0] <= 8'b1001_1001; char0[1] <= 8'b0011_0011; char0[2] <= 8'b0110_0110; char0[3]<= 8'b1100_1100;
      char1[0] <= 8'b1000_0001; char1[1] <= 8'b1000_0000; char1[2] <= 8'b0000_0000; char1[3] <= 8'b0000_0001;
      char2[0] <= 8'b0000_0000; char2[1] <= 8'b1000_0000; char2[2] <= 8'b1000_0001; char2[3] <= 8'b0000_0001;
      char3[0] <= 8'b0000_0000; char3[1] <= 8'b0000_0001; char3[2] <= 8'b1000_0001; char3[3] <= 8'b1000_0000;
      char4[0] <= 8'b1000_0001; char4[1] <= 8'b0000_0001; char4[2] <= 8'b0000_0000; char4[3] <= 8'b1000_0000;
      char5[0] <= 8'b1000_0001; char5[1] <= 8'b1000_0000; char5[2] <= 8'b0000_0000; char5[3] <= 8'b0000_0001;
      char6[0] <= 8'b0000_0000; char6[1] <= 8'b1000_0000; char6[2] <= 8'b1000_0001; char6[3] <= 8'b0000_0001;
      char7[0] <= 8'b0110_0110; char7[1] <= 8'b0011_0011; char7[2] <= 8'b1001_1001; char7[3] <= 8'b1100_1100;
 if(cnt1==8'd124)
       begin
                 cnt1 <= 0;
                 if(cnt2==8'd199)
                 begin
                       clk_lk <= ~clk_lk;
                       cnt2 <= 0;
                 end
                else cnt2 <= cnt2+1;
       end
 else cnt1 <= cnt1+1;
end

always@(posedge clk_lk)
begin
         if(cnt3==8'd70)
         begin
              cnt3   <= 0;
              clk_h  <= ~clk_h;
         end
         else  cnt3 <= cnt3+1;
         if(p==3'b111) p <= 0;
         else                p <= p+1;

end
always@(p)
case(p)
    3'b000:begin    
                    L <= 8'b1111_1110;
                    R[7:0] <= char0[i];
               end
    3'b001:begin    
                    L <= 8'b1111_1101;
                    R[7:0] <= char1[i];  
               end  
    3'b010:begin    
                    L <= 8'b1111_1011;
                    R[7:0] <= char2[i];  
              end 
    3'b011:begin    
                    L <= 8'b1111_0111;
                    R[7:0] <= char3[i];   
              end 
    3'b100:begin    
                    L <= 8'b1110_1111;
                    R[7:0] <= char4[i];   
               end 
    3'b101:begin    
                     L <= 8'b1101_1111;
                     R[7:0] <= char5[i];   
              end    
     3'b110:begin    
                     L <= 8'b1011_1111;
                     R[7:0] <= char6[i];   
                end    
      3'b111:begin    
                     L <= 8'b0111_1111;
                     R[7:0] <= char7[i];  
                 end      
endcase

always@(posedge clk_h)
begin
        i <= i+1;

end

endmodule
其实led阵列显示有很多种方法,上面介绍的是一个很容易理解的方法,可以以此为基本来灵活改变显示方法。

关闭窗口

相关文章