LED點陣顯示屏被用到很多領域,随着電子技術的發展,LED點陣書寫顯示屏的廣泛應用是一種趨勢。傳統的LED點陣顯示是由微處理器實作的,但是以FPGA做控制器将成為發展趨勢。FPGA的結構靈活,其邏輯單元、可程式設計内部連線和I/O單元都可以由使用者程式設計,可以實作複雜邏輯功能,滿足各種設計需求。其速度快,功耗低,通用性強,特别适用于大型系統的設計。使用FPGA還可以實作動态配置、線上系統重構(可以在系統運作的不同時刻,按需要改變電路的功能,使系統具備多種空間相關或時間相關的任務)及硬體軟化、軟體硬化等功能。本作品用FPGA做為控制器,來實作LED點陣書寫顯示屏的功能。
1.2 本課題主要研究内容
設計任務:設計并制作一個基于32×32點陣LED子產品的書寫顯示屏,其系統結構如圖1所示。在控制器的管理下,LED點陣子產品顯示屏工作在人眼不易覺察的掃描微亮和人眼可見的顯示點亮模式下;當光筆觸及LED點陣子產品表面時,先由光筆檢測觸及位置處LED點的掃描微亮以擷取其行列坐标,再依據功能需求決定該坐标處的LED是否點亮至人眼可見的顯示狀态(如圖1中光筆接觸處的深色LED點已被點亮),進而在屏上實作“點亮、劃亮、反顯、整屏擦除、筆畫擦除、連寫多字、對象拖移”等書寫顯示功能。

圖1-1 LED點陣書寫顯示屏系統結構示意圖
(1)在“點亮“功能下,當光筆接觸屏上某點LED時,能即時點亮該點LED,并在控制器上同步顯示該點LED的行列坐标值(左上角定為行列坐标原點)。
(2)在“劃亮”功能下,當光筆在屏上快速劃過時,能同步點亮劃過的各點LED,其速度要求2s内能劃過并點亮40點LED。
(3)在“反顯”功能下,能對屏上顯示的資訊實作反相顯示(即:字型筆畫處不亮,無筆畫處高亮)。
(4)在“整屏擦除”功能下,能實作對屏上所顯示資訊的整屏擦除。
從理論上說,不論顯示圖形還是文字,隻要控制與組成這些圖形或文字的各個點所在位置相對應的LED器件發光,就可以得到我們想要的顯示結果,這種同時控制各個發光點亮滅的方法稱為靜态驅動顯示方式。32*64的點陣共有2048個發光二極管,顯然單片機沒有這麼多端口,如果我們采用鎖存器來擴充端口,按8位的鎖存器來計算,32*64的點陣需要256個鎖存器。這個數字很龐大,而且成本很昂貴,我們僅僅是32*64的8個漢字點陣,在實際應用中的顯示屏往往要大得多,這樣在鎖存器上花的成本将是一個很龐大的數字。是以在實際應用中的顯示屏幾乎都不采用這種設計,而采用另一種稱為動态掃描的顯示方法。
動态掃描的意思簡單地說就是逐行輪流點亮,這樣掃描驅動電路就可以實作多行(比如8行)的同名列共用一套列驅動器。具體就32*64的點陣來說,把所有同一列的發光管的陰極連在一起,再去驅動這一列LED (共陽接法),每一列先送出對應第1行發光管對應的資料并鎖存,再選通第1行使其點亮一定的時間,然後熄滅;再送出第2行的資料并鎖存,再選通第2行使其點亮相同的時間,然後熄滅……第8行之後,又重新點亮第1行,反複輪回。當這樣輪回的速度足夠快(每秒24次以上),由于人眼的視覺暫留現象,就能看到顯示屏上穩定的圖形了。
采用掃描方式進行顯示時,每行有一個行驅動器,各行的同名列共用一個列驅動器。顯示資料通常存儲在單片機的程式存儲器中,按8位一個位元組的形式順序排放。顯示時要把一行中各列的資料都傳送到相應的列驅動器上去,這就存在一個顯示資料傳輸的問題。從控制電路到列驅動器的資料傳輸可以采用并行方式或串行方式。采用并行方式時,32*64的LED點陣有8列8*8的點陣,需要8*8=64個列資料輸入口,而一個89C51隻有32個I/O接口,還要同時驅動行資料,根本不夠用;并且從控制電路到列驅動器的線路數量大,相應的硬體數目多,由此可以得出,當列數很多時,并行傳輸的方案是不可取的。
采用串行傳輸的方法,控制電路可以隻用2根線:資料線、時鐘線。将行資料一位一位傳往行驅動器,在硬體方面無疑是十分經濟的。但是,串行傳輸過程較長,資料按順序一位一位地輸出給行驅動器,隻有當一行的各列資料都已傳輸到位之後,這一行的各列才能并行地進行顯示。這樣,對于一行的顯示過程就可以分解成列資料準備(傳輸)和列資料顯示兩個部分。對于串行傳輸方式來說,列資料準備時間可能相當長,在行掃描周期确定的情況下,留給顯示的時間就太少了,以緻影響到LED的亮度。
解決串行傳輸中列資料準備和列資料顯示的時間沖突問題,可以采用重疊處理的方法。即在顯示本行資料的同時,傳送下一行的資料。為了達到重疊處理的目的,列資料的顯示驅動電路就需要具有鎖存功能。經過上述分析,可以歸納出列驅動器電路應具備的主要功能:對資料準備來說,它應能實作串入并出的移位功能;對資料顯示來說,應具有并行鎖存的功能。這樣,本行已準備好的資料打人并行鎖存器進行顯示時,串并移位寄存器就可以準備下一行的列資料,而不會影響本行的顯示。同時為了LED顯示的亮度,采用8行掃描,每個漢字上面有2個16列驅動器驅動,列驅動器的位置應該是在第1行跟第9
行,即每個16*16的漢字點陣是有4個8*8的點陣組成的陣列,掃描的時候同時掃描顯示第1行跟第9行,第二次掃描的時候顯示第2行跟第10行,以此類推,最後顯示第8行跟第16行,如圖所示:
圖 4-1 16*16LED顯示屏
4.2 系統總體方案的确定
·主要器選擇方案論證
方案一:以ARM為系統控制器
采用32位RISC微處理器ARM實作點陣屏的控制和編碼功能,基本上能完成題目的要求,但是 ARM 不适合多線程操作,如果應用在系統中會使電路和軟體設計變得複雜。
方案二:用 FPGA 作為系統控制器
FPGA可以直接用硬體掃描、編碼、解碼、糾錯,速度快、穩定性高、擴充性能好、體積小,可以提供豐富的邏輯單元和I/O 資源。用SOPC工具可以快速生成片上軟核處理器,将所有的控制單元內建在一片FPGA晶片内,降低了額外的功耗開支。采用并行的輸入/輸出方式,可以達到很快的速度。這樣合理的配置設定了FPGA 資源,具有很強的實時性和準确性。可以實作各種靈活控制。
本系統我們采用方案二。
·點陣驅動方案論證
方案一:串行方式顯示
這種顯示方式由譯碼器單元74HC138、資料移位寄存器74HC595和列驅動器組成,點陣顯示屏可以用少量I/O口接收控制器傳輸下來的大量資料,此方案為點陣顯示屏系統中比較常用的,所用器件也比較常用,容易買到。但是它存在一個緻命的缺點,就是重新整理速度不夠快,高速度的位址編碼資訊無法發送。
方案二:并行方式顯示
可以通過鎖存器晶片來增強FPGA的I/O口的驅動能力,将32位寬的資料同時輸入到LED點陣列中,達到并行控制LED點陣的目的。方案中運用4片鎖存器74HC573來組成雙緩沖寄存器,驅動LED點陣行線,用5片3-8譯碼器74HC138組合成5-32譯碼器對LED點陣的32列進行選取。這樣就避免了各行資料顯示不同步的問題。由于并行資料傳輸速度非常快,是以高速度的位址編碼資訊可以同步發出。
本設計選擇第二個方案。
系統總體結構如下所示:
圖 4-2 系統工作原理框圖
系統總體工作流程如下所示:
由于本系統有四中工作模式, “點亮“功能,“劃亮”功能,“反顯”功能,“整屏擦除”功能,在這裡,我們第一這四個工作模式為四個狀态S1,S2,S3,S4,系統的初始狀态S0,那麼這個系統可以設計為狀态機的工作模式。其工作模式如下所示:
本章,我們将詳細介紹系統的設計與實作。
5.1“點亮“功能
5.1.1設計要求
當光筆接觸屏上某點LED時,能即時點亮該點LED,并在控制器上同步顯示該點LED的行列坐标值(左上角定為行列坐标原點)。
5.1.2設計思路
通過按鍵的控制,我們将系統切換到點亮功能子產品,由于本系統采用的LED顯示屏是32*32的,估當光筆點選某個LED的時候,顯示屏将産生一個中斷給FPGA,然後由FPGA控制發出中斷的LED點亮,然後通過中斷值,分析出目前LED所在的位置,在發光數位管中顯示出相應的坐标點。同時對于LED點陣,我們對其産生中斷掃描,用于準确的識别被點選的LED燈。
5.1.3設計流程
整個S1狀态的設計代碼如下所示:
·坐标計算子產品:
case(x[31:0])
32'b00000000_00000000_00000000_00000001:xc<=0;
32'b00000000_00000000_00000000_00000010:xc<=1;
32'b00000000_00000000_00000000_00000100:xc<=2;
32'b00000000_00000000_00000000_00001000:xc<=3;
32'b00000000_00000000_00000000_00010000:xc<=4;
32'b00000000_00000000_00000000_00100000:xc<=5;
32'b00000000_00000000_00000000_01000000:xc<=6;
32'b00000000_00000000_00000000_10000000:xc<=7;
32'b00000000_00000000_00000001_00000000:xc<=8;
32'b00000000_00000000_00000010_00000000:xc<=9;
32'b00000000_00000000_00000100_00000000:xc<=10;
32'b00000000_00000000_00001000_00000000:xc<=11;
32'b00000000_00000000_00010000_00000000:xc<=12;
32'b00000000_00000000_00100000_00000000:xc<=13;
32'b00000000_00000000_01000000_00000000:xc<=14;
32'b00000000_00000000_10000000_00000000:xc<=15;
32'b00000000_00000001_00000000_00000000:xc<=16;
32'b00000000_00000010_00000000_00000000:xc<=17;
32'b00000000_00000100_00000000_00000000:xc<=18;
32'b00000000_00001000_00000000_00000000:xc<=19;
32'b00000000_00010000_00000000_00000000:xc<=20;
32'b00000000_00100000_00000000_00000000:xc<=21;
32'b00000000_01000000_00000000_00000000:xc<=22;
32'b00000000_10000000_00000000_00000000:xc<=23;
32'b00000001_00000000_00000000_00000000:xc<=24;
32'b00000010_00000000_00000000_00000000:xc<=25;
32'b00000100_00000000_00000000_00000000:xc<=26;
32'b00001000_00000000_00000000_00000000:xc<=27;
32'b00010000_00000000_00000000_00000000:xc<=28;
32'b00100000_00000000_00000000_00000000:xc<=29;
32'b01000000_00000000_00000000_00000000:xc<=30;
32'b10000000_00000000_00000000_00000000:xc<=31;
endcase
·亮燈子產品
begin
if(enable==1'b1)
begin
if(interrupt==1'b1)
begin
light<=1'b1;
x_out<=x;
end
else begin
light<= light;
x_out<= x_out;
end
end
else begin
light<=1'b0;
x_out<=33'd0;
end
end
·數位管坐标顯示子產品
begin
if(enable==1'b1)
begin
LED_x<=xc;
LED_y<=yc;
end
else begin
LED_x<=8'd0;
LED_y<=8'd0;
end
end
5.1.4設計仿真
圖5-1 S1狀态仿真圖
如圖所示:當輸入的坐标信号為1_00001000_00000000_00000000_00000000, 0_00000000_00000000_00000000_01000000,即輸入的中斷坐标為X:27,Y:6,是以最後數位管要顯示的資料為(27,06)即中斷點的坐标。
5.2“劃亮”功能
5.2.1設計要求
在“劃亮”功能下,當光筆在屏上快速劃過時,能同步點亮劃過的各點LED,其速度要求2s内能劃過并點亮40點LED。
5.2.2設計思路
我們要求同時點亮40個點,即在2S中内,我們要保持所有點的坐标資訊,然後對這些坐标所對應的資料在LED點陣上顯示出來,由于這個子產品對應的點比較多,是以我們不在對這些點顯示坐标。當光筆在LED上滑動的時候,會不斷的産生中斷信号,當中斷産生的時候,我們通過FPGA内部的計數器來記錄中斷所持續的時間,然後當中斷結束的時候,計數器停止計數,同時LED點燈使能信号被鎖存,進而在顯示屏上顯示出一條線段。
那麼在設計本質上,這個功能主要是實作當光筆劃結束以後,系統能夠記錄光筆劃過的LED點,然後FPGA循環的發出使能信号和其對應的坐标信号使線段持續顯示。
5.2.3 設計流程
begin
if(enable==1'b1)
begin
if(interrupt==1'b1)//産生中斷
begin
men_x[1]<=x;
for(i=2;i<=50;i=i+1)
men_x[i]<=men_x[i-1];
end
else begin
for(i=1;i<=50;i=i+1)
men_x[i]<=men_x[i];
end
end
else begin
cnt <=8'b00000000;
final_number<=8'b00000000;
end
end
5.2.4設計仿真
圖5-2 線段顯示
從仿真圖中,可以看到,當輸入中斷結束以後,FPGA可以循環輸出被光筆劃過的LED燈,進而達到持續顯示多個LED燈的效果。
5.3“反顯”功能
5.1.1設計要求
在“反顯”功能下,能對屏上顯示的資訊實作反相顯示(即:字型筆畫處不亮,無筆畫處高亮)。
5.1.2設計思路
反顯的功能和前面我們介紹的相似,就是将光筆點選的LED燈熄滅,而初始的LED燈全為亮,故我們要做的就是改變系統的初始狀态,然後輸出的LED使能信号取反即可。這個子產品的功能比較簡單,我們在這裡就不多做介紹了。
5.4“整屏擦除”功能
5.1.1設計要求
當光筆接觸屏上某點LED時,能即時點亮該點LED,并在控制器上同步顯示該點LED的行列坐标值(左上角定為行列坐标原點)。
5.1.2設計思路
這個子產品就是使LED的顯示傳回到初始的狀态,如初始為全亮,則LED會自動消除暗的燈,如LED初始為全暗,則LED會熄滅所有亮的燈。這個子產品設計比較簡單,這裡就不做詳細介紹了。
5.5 系統總體設計
5.5.1系統初始狀态的設計與實作
這個子產品主要功能就是使LED顯示屏全滅或則全亮。即通過循環發送LED燈的位址,達到全亮或則全滅的效果。其實作代碼如下所示:
//坐标掃描
always @(posedge flag)
begin
if(!rst)
begin
xc<=0;
yc<=0;
end
else begin
if(xc==31)
begin
xc<=0;
if(yc==31)
yc<=0;
else
yc<=yc+1'b1;
end
else begin
xc<=xc+1'b1;
end
end
end
//X,Y坐标交替輸出
always @(posedge clk)
begin
if(!rst)
x_out<=33'd0;
else begin
if(flag==1'b1)
x_out<=x_tmp;
else
x_out<=y_tmp;
end
end
其仿真結果:
圖5-3 坐标輸出
下面我們将對每個子產品在頂層檔案進行調用。
always @(posedge clk)
begin
if(~rst)
begin
x_out<=33'd0;
light<=1'd0;
LED_x<=8'd0;
LED_y<=8'd0;
end
else begin
if(k3==0)//正顯示
begin
if(k1==1'b1)//點亮
begin
x_out<=x_out_tmp1;
light<=light_tmp1;
LED_x<=LED_x_tmp1;
LED_y<=LED_y_tmp1;
end
else if(k2==1'b1)劃亮
begin
x_out<=x_out_tmp2;
light<=light_tmp2;
end
else if(k4==1'b1)//清屏
begin
x_out<=x_out_tmp0;
light<=~light_tmp0;
end
end
if(k3==1)//反顯示
begin
if(k1==1'b1)//點亮
begin
x_out<=x_out_tmp1;
light<=~light_tmp1;
LED_x<=LED_x_tmp1;
LED_y<=LED_y_tmp1;
end
else if(k2==1'b1)劃亮
begin
x_out<=x_out_tmp2;
light<=~light_tmp2;
end
else if(k4==1'b1)//清屏
begin
x_out<=x_out_tmp0;
light<=light_tmp0;
end
end
end
end
5.5.3 仿真
點亮:
圖5-5 點亮
劃亮:
圖5-6 點亮
清屏:
圖5-7 清屏