單片機點陣 LED 顯示屏設計,商場廣告屏就是這麼來的!
LED點陣的介紹
點陣 LED 顯示屏作為一種現代電子媒體,具有靈活的顯示面積(可任意分割和拼裝)、高亮度、長壽命、數字化、實時性等特點,應用非常廣泛。
前邊學了 LED 小燈和 LED 數碼管後,學 LED 點陣就要輕鬆得多了。一個數碼管是 8 個LED 組成,同理,一個 8*8 的點陣就是由 64 個 LED 小燈組成。圖 7-1 就是一個點陣 LED 最小單元,即一個 8*8 的點陣 LED,圖 7-2 是它的內部結構原理圖。
圖 7-1 8*8LED 點陣外觀
圖 7-2 8*8 點陣結構原理圖
從圖 7-2 上可以看出,其實點陣 LED 點亮原理還是很簡單的。在圖中大方框外側的就是點陣 LED 的引腳號,左側的 8 個引腳是接的內部 LED 的陽極,上側的 8 個引腳接的是內部LED 的陰極。那麼如果我們把 9 腳置成高電平、13 腳置成低電平的話,左上角的那個 LED小燈就會亮了。下面我們就用程序來實現一下,特別注意,控制點陣左側引腳的 74HC138是原理圖上的 U4,8 個引腳自上而下依次由 U4 的 Y0~Y7 輸出來控制。
那麼同樣的方法,通過對 P0 的整體賦值我們可以一次點亮點陣的一行,那麼這次我們用程序來點亮點陣的第二行,對應的就需要編號 U4 的 74HC138 在其 Y1 引腳輸出低電平了。
從這裡我們可以逐步發現點陣的控制原理了。我們前面講了一個數碼管就是 8 個 LED 小燈,一個點陣是 64 個 LED 小燈。同樣的道理,我們還可以把一個點陣理解成是 8 個數碼管。經過前面的學習已經掌握了 6 個數碼管同時顯示的方法,那 8 個數碼管也應該輕輕鬆鬆了。下面我們就利用定時器中斷和數碼管動態顯示的原理來把這個點陣全部點亮。
LED點陣的圖形顯示
獨立的 LED 小燈可以實現流水燈,數碼管可以顯示多位數字,那點陣 LED 就得來顯示一點花樣了。
我們要顯示花樣的時候,往往要先做出來一些小圖形,這些小圖形的數據要轉換到我們的程序當中去,這個時候就需要取模軟體。給大家介紹一款簡單的取模軟體,這種取模軟體在網上都可以下載到,大家來了解一下如何使用,先看一下操作界面,如圖 7-3 所示。
圖 7-3 字模提取軟體界面
滑鼠點一下「新建圖形」,根據我們板子上的點陣,把寬度和高度分別改成 8,然後點確定,如圖 7-4 所示。
圖7-4 新建圖形
點擊左側的「模擬動畫」菜單,再點擊「放大格點」選項,一直放大到最大,那我們就可以在我們的 8*8 的點陣圖形中用滑鼠填充黑點,就可以畫圖形了,如圖 7-5 所示。
圖7-5 字模提取軟體畫圖
經過我們的一番精心設計,畫出來一個心形圖形,並且填充滿,最終出現我們想要的效果圖,如圖 7-6 所示。
圖 7-6 心型圖形
由於取模軟體是把黑色取為 1,白色取為 0,但我們點陣是 1 對應 LED 熄滅,0 對應 LED點亮,而我們需要的是一顆點亮的「心」,所以我們要選「修改圖像」菜單里的「黑白反顯圖像」這個選項,再點擊「基本操作」菜單裡邊的「保存圖像」可以把我們設計好的圖片進行保存,如圖 7-7 所示。
圖 7-7 保存圖形
保存文件只是為了再次使用或修改使方便方便,當然你也可以不保存。操作完了這一步後,點擊「參數設置」菜單里的「其他選項」,如圖 7-8 所示。
圖 7-8 選項設置
這裡的選項,要結合圖 7-2 來進行設置,大家可以看到 P0 口控制的是一行,所以用「橫向取模」,如果控制的是一列,就要選「縱向取模」。選中「位元組倒序」這個選項,是因為圖7-2 中左邊是低位 DB0,右邊是高位 DB7,所以是位元組倒序,其它兩個選項大家自己了解,點確定後,選擇「取模方式」這個菜單,點一下「C51 格式」後,在「點陣生成區」自動產生了 8 個位元組的數據,這 8 個位元組的數據就是取出來的「模」,如圖 7-9 所示。
圖 7-9 取模結果
大家注意,雖然我們用了軟體來取模,但是也得知道其原理是什麼,在這個圖片里,黑色的一個格子表示一位二進位的 1,白色的一個格子表示一位二進位的 0。第一個位元組是 0xFF,其實就是這個 8*8 圖形的第一行,全黑就是 0xFF;第二個位元組是 0x99,低位在左邊,高位在右邊,大家注意看,黑色的表示 1,白色的表示 0,就組成了 0x99 這個數值。同理其它的數據大家也就知道怎麼來的了。
那麼下面我們就用程序把這些數據依次送到點陣上去,看看運行效果如何。
對於 8*8 的點陣來說,我們可以顯示一些簡單的圖形,字元等。但大部分漢字通常來說要用到 16*16 個點,而 8*8 的點陣只能顯示一些簡單筆畫的漢字,大家可以自己取模做出來試試看。使用大屏顯示漢字的方法和小屏的方法是類似的,所需要做的只是按照相同的原理來擴展行數和列數而已。
LED點陣的縱向移動(動態顯示)
點陣的動畫顯示,說到底就是對多張圖片分別進行取模,使用程序演算法巧妙的切換圖片,多張圖片組合起來就成了一段動畫了,我們所看到的動畫片、遊戲等等,它們的基本原理也都是這樣的。
上一節我們學了如何在點陣上畫一個形,有時候我們希望這些顯示是動起來的,而不是靜止的。對於點陣本身已經沒有多少的知識點可以介紹了,主要就是編程演算法來解決問題了。比如我們現在要讓點陣顯示一個 I U 的動畫,首先我們要把這個圖形用取模軟體畫出來看一下,如圖 7-10 所示。
圖 7-10 上下移動橫向取模
這張圖片共有 40 行,每 8 行組成一張點陣圖片,並且每向上移動一行就出現了一張新圖片,一共組成了 32 張圖片。
用一個變數 index 來代表每張圖片的起始位置,每次從 index 起始向下數 8 行代表了當前的圖片,250ms 改變一張圖片,然後不停的動態刷新,這樣圖片就變成動畫了。首先我們要對顯示的圖片進行橫向取模,雖然這是 32 張圖片,由於我們每一張圖片都是和下一行連續的,所以實際的取模值只需要 40 個位元組就可以完成,我們來看看程序。
大家把這個程序下載到單片機上看看效果,一個 I U 一直往上走動的動畫就出現了,現在還有哪位敢說我們工科同學不懂浪漫的?還需要用什麼玫瑰花取悅女朋友嗎?一點技術含量都沒有,要玩就玩點高科技,呵呵。
當然,別光圖開心,學習我們還要繼續。往上走動的動畫我寫出來了,那往下走動的動畫,大家就要自己獨立完成了,不要偷懶,一定要去寫代碼調試代碼。瞪眼看只能了解知識,而能力是在真正的寫代碼、調試代碼這種實踐中培養起來的。
LED點陣的橫向移動(動態顯示)
上下移動我們會了,那我們還想左右移動該如何操作呢?
方法一、最簡單,就是把板子側過來放,縱向取模就可以完成。
這裡大家是不是有種頭頂冒汗的感覺?我們要做好技術,但是不能沉溺於技術。技術是我們的工具,我們在做開發的時候除了用好這個工具外,也得多拓展自己解決問題的思路,要慢慢培養自己的多角度思維方式。
那把板子正過來,左右移動就完不成了嗎?當然不是。大家慢慢的學多了就會培養了一種感覺,就是一旦硬體設計好了,我們要完成一種功能,大腦就可以直接思考出來能否完成這個功能,這個在我們進行電路設計的時候最為重要。我們在開發產品的時候,首先是設計電路,設計電路的時候,工程師就要在大腦中通過思維來驗證板子硬體和程序能否完成我們想要的功能,一旦硬體做好了,做好板子回來剩下的就是靠編程來完成了。只要是硬體邏輯上沒問題,功能上軟體肯定可以實現。
當然了,我們在進行硬體電路設計的時候,也得充分考慮軟體編程的方便性。因為我們的程序是用 P0 來控制點陣的整行,所以對於我們這樣的電路設計,上下移動程序是比較好編寫的。那如果我們設計電路的時候知道我們的圖形要左右移動,那我們設計電路畫板子的時候就要儘可能的把點陣橫過來放,有利於我們編程方便,減少軟體工作量。
方法二、利用二維數組來實現,演算法基本上和上下移動相似。
二維數組,前邊提過一次,他的使用其實也沒什麼複雜的。它的聲明方式是:
數據類型 數組名[數組長度 1][數組長度 2];
與一位數組類似,數據類型是全體元素的數據類型,數組名是標識符,數組長度 1 和數組長度 2 分別代表數組具有的行數和列數。數組元素的下標一律從 0 開始。
例如:unsigned char a[2][3];聲明了一個具有 2 行 3 列的無符號字元型的二維數組 a。
二維數組的數組元素總個數是兩個長度的乘積。二維數組在內存中存儲的時候,採用行優先的方式來存儲,即在內存中先存放第 0 行的元素,再存放第一行的元素......,同一行中再按照列順序存放,剛才定義的那個 a[2][3]的存放形式就如表 7-1 所示。
表7-1 二維數組的物理存儲結構
二維數組的初始化方法分兩種情況,我們前邊學一維數組的時候學過,數組元素的數量可以小於數組元素個數,沒有賦值的會自動給 0。當數組元素的數量等於數組個數的時候,如下所示:
unsigned char a[2][3] = {, };
或者是
unsigned char a[2][3] = ;
當數組元素的數量小於數組個數的時候,如下所示:
unsigned char a[2][3] = {, };
等價於
unsigned char a[2][3] = ;
而反過來的寫法
unsigned char a[2][3] = ;
等價於
unsigned char a[2][3] = {, };
此外,二維數組初始化的時候,行數可以省略,編譯系統會自動根據列數計算出行數,但是列數不能省略。
講這些,只是為了讓大家了解一下,看別人寫的代碼的時候別發懵就行了,但是我們今後寫程序的時候,按照規範,行數列數都不要省略,全部寫齊,初始化的時候,全部寫成unsigned char a[2][3] = {, };的形式,而不允許寫成一維數組的格式,防止大家出錯,同時也是提高程序的可讀性。
那麼下面我們要進行橫向做 I U 的動畫了,先把我們需要的圖片畫出來,再逐一取模,和上一張圖片類似的是,我們這個圖形共有 30 張圖片,通過程序每 250ms 改變一張圖片,就可以做出來動畫效果了。但是不同的是,我們這個是要橫向移動,橫向移動的圖片切換時的字模數據不是連續的,所以這次我們要對 30 張圖片分別取模,如圖 7-11 所示。
圖 7-11 橫向動畫取模圖片
圖 7-11 中最上面的圖形是橫向連在一起的效果,而實際上我們要把它分解為 30 個幀,每幀圖片單獨取模,取出來都是 8 個位元組的數據,一共就是 30*8 個數據,我們用一個二維數組來存儲它們。
下載進到板子上瞧瞧,是不是有一種帥到掉渣的感覺呢。技術這東西,外行人看的是很神秘的,其實我們做出來會發現,也就是那麼回事而已,每 250ms 更改一張圖片,每 1ms在定時器中斷里刷新單張圖片的某一行。
不管是上下移動還是左右移動,大家要建立一種概念,就是我們是對一幀幀的圖片的切換,這種切換帶給我們的視覺效果就是一種動態的了。比如我們的 DV 拍攝動畫,實際上就是快速的拍攝了一幀幀的圖片,然後對這些圖片的快速回放,把動畫效果給顯示了出來。因為我們硬體設計的緣故,所以在寫上下移動程序的時候,數組定義的元素比較少,但是實際上大家也得理解成是 32 張圖片的切換顯示,而並非是真正的「移動」。