LED陣列已經(jīng)普遍使用在我們生活中,出去逛逛隨處可見。不太清楚業(yè)內(nèi)是使用什么來控制顯示的,估計(jì)用單片機(jī),畢竟便宜多了。作為一個搞電子的,一定要了解LED陣列顯示。我的理解:LED陣列顯示主要有兩種:靜態(tài)顯示,滾動顯示。
一:靜態(tài)顯示
LED陣列顯示有些類似于數(shù)碼管顯示,都是掃描顯示。這里略講講原理:在我們看到的LED陣列顯示一個畫面或是一行字,其實(shí)在硬件顯示的時候,應(yīng)該是一行一行或是一列一列來顯示。例如8*8led陣列,在我使用過程中,顯示方式是一列一列的顯示,也就是先點(diǎn)亮第一列l(wèi)ed,其他列都不亮,然后點(diǎn)亮第二列l(wèi)ed,其他列都不亮,依次到第八列,然后又回來點(diǎn)亮第一列,以此循環(huán)。這樣就能實(shí)現(xiàn)led陣列的靜態(tài)顯示。

二:左移或右移顯示
led滾動顯示是一個不容易理解的顯示方式。實(shí)際使用中,可以看到,led陣列都是一行字緩慢的向左或是向右移動。
顯示方法:一列一列顯示。(如果是上下移動,則選擇一行一行顯示)
思考的方向:單獨(dú)考慮每一列數(shù)值的改變,先考慮第一列在滾動顯示過程中數(shù)值有哪些。
舉例說明:

就像上圖我們要滾動顯示一個字母T,從最上面圖1一直右移到最后一個圖,然后又回到了圖1,這就是典型的滾動循環(huán)顯示。
按照上面的思考方法來做,假定最左邊為第一列,最右邊為第八列。首先考慮在滾動顯示中第一列的數(shù)據(jù)變化:
8'h00, 8'h00,
8'h00, 8'h40,
8'h40, 8'h7e,
8'h40, 8'h40
第二列數(shù)據(jù)變化:
8'h40, 8'h00, 8'h00,
8'h00, 8'h40,
8'h40, 8'h7e, 8'h40
對比第一列數(shù)據(jù)和第二列數(shù)據(jù),會發(fā)現(xiàn)第一列第一張圖的數(shù)據(jù)8'h00,是第二列第二張圖的數(shù)據(jù)8'h00.

由此可知:對于右移滾動循環(huán)顯示,所有列的數(shù)據(jù)都是同樣的,也就是,如果把列出現(xiàn)的所有數(shù)據(jù)存在一個數(shù)組或是庫里面,所有列的數(shù)據(jù)都可以在該數(shù)組或是庫取。這就誕生了網(wǎng)上很多字模軟件,我們只要知道第一張圖上面所有列的數(shù)據(jù),然后存在一個數(shù)組里面,顯示的時候只需要每一列取不同的值即可。
具體代碼沒有保存,故不貼出來。
三:最外圍順時針滾動顯示
之所以特別說說這個顯示,是因?yàn)樯现苣团笥压湫@。走到體育館,她指著體育館門口的led,跟我講,最外圍的那一圈一直在順時針旋轉(zhuǎn)怎么做到的。當(dāng)時覺得很少見,琢磨難道是橫著的設(shè)置為左右移動,豎著的設(shè)置為上下移動。接著就想,那么怎么在同一個顯示中,既使用上下移動模式,又使用左右移動模式,想了很久。昨晚自己在紙上亂畫了一下,發(fā)現(xiàn)方法還是和上面一樣。

其實(shí)在旋轉(zhuǎn)過程中,每一列的數(shù)據(jù)還是周期發(fā)生變化,
拿第一列(最左邊一列)舉例:變化的值為:8'h99,
8'h33,8'h66,8'hCC.這樣就可以將問題轉(zhuǎn)換到第二種顯示,所以在led陣列顯示中,如果是一列一列的顯示,需要著重考慮每一列的數(shù)據(jù)的變化;如果是一行一行的顯示,需要著重考慮的是每一行的數(shù)據(jù)變化。
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