LED(lite EMIt diode)顯示是項目開發中經常遇到的一種顯示方法,其具有亮度高、全視角、使用壽命長、驅動簡單等特點,因而在一些高端和大型的器材和設備上使用較為廣泛。下面就常用的led顯示及驅動方法作一說明:
led:本文所說的led主要是指下列幾種:
l 7-段數碼led,分共陰和共陽兩種,原理圖見1和2;
l 常用nxm led點陣:如8x8 led 點陣模塊、5x7 led點陣模塊等,其也分為共陰和共陽兩種;
l 單個led管。
所謂共陰極,即是將所有led的陰極連接到一起,而共陽極則相反,所有的陽極被連接到了一起。但不管哪種結構,其顯示設計的原理基本相同,唯一的是其驅動的電路的設計有所差異,一般共陰極采用推(push)電流的方式來驅動,而共陽極結構則采用拉(pull)電流的方式來驅動。
根據led顯示的硬件設計方法的不同,led顯示驅動分為靜態法和動態法兩大類,其具體的說明和編程方法分述如下:
1. 靜態顯示驅動法:
所謂靜態顯示驅動法,即是指每一個led燈分別對應一個獨立的io驅動口;其點亮和關閉由該io來對其進行控制,互不干擾,見圖3(注:對于io驅動能力弱的mcu,必須增加外部的驅動芯片或驅動三極管等器件)。此種設計一般應用在對單個led的驅動或led數量較少,且所選的mcu io比較充裕的情況下。比如一些項目的led指示燈、產品的設計中只有一個7-段led碼需要顯示等。
由于每一個led均由獨立的io口來控制,因此此種顯示驅動的軟件設計比較簡單明了,無需特別的處理,在需要點亮和關閉時設置相應的io輸出口的電平即可(即“0”或“1”,具體須根據驅動電路的設計來決定)。
圖 3
優點:電路設計簡單,編程簡單,而且led的亮度控制容易,只需在驅動端增加相應的電流調節電阻即可方便地實現亮度的調節(對于存在獨立驅動的設計,還可以通過調整驅動電壓來達到亮度的調節)。
缺點:由于每一個led燈需要一個io口,因此對io口的需求較大,不易實現大數量的led驅動和顯示,擴展性能差。
2. 動態的顯示驅動法:
與靜態顯示方法不同,動態led顯示的設計方法是將不同led模塊的所有的led的驅動端一對一地連接到一起,見圖4,而將其公共極(陰極或陽極)分別由不同的io口來驅動(主要針對7-段碼和led點陣模塊)。在此,我們稱其公共極為掃描線或地址線(因此種連接方法類似于存儲器的內部連接,每個led點相當與memory中的一個bit),不同的led模塊(類似于memory中的一個byte)用不同的掃描線地址線來進行選定。
圖 4
由于所有的led模塊公用了驅動端,因此led的驅動不再像靜態法一樣為每個led所獨享,因此其驅動的設計方法也與靜態法完全不同,需要采用分時掃描(也稱動態掃描)方法來實現對所有led的顯示驅動,其原理如下(以圖4為例):
a. 將a0設置為高電平,也即允許第一組led顯示,同時將a2,a3,a4設置為低電平,也即關閉該陰極所對應的led組的顯示;
b. 在p0口輸出a0組對應的顯示數據(也稱為pattern),如字符點陣數據,7-段碼對應的數字的數據等,該數據可以通過rom表的形式來預先定義;
c. 保持一定的時間t,該時間即為所設定定時器的中斷時間;
d. 將a0口設置為低電平,關閉a0組led的顯示;
e. 將a1設置為高電平,其他幾個設置為低電平,開啟a1組對應的led的顯示;
f. 在p0口輸出a1組對應的顯示數據(也稱為pattern,意義同上);
g. 重復以上步驟,直到所有組被掃描一遍,然后又從a0組開始下一個循環,如此周而復始,實現所有led的動態顯示。
1.該方法的原理利用了人眼對物體的視覺延遲來達到所有led的同時顯示,實際上,在每一個時刻,只有一組led是處于顯示的狀態,而其他led組均為關閉狀態。理論上,若兩次顯示之間的時間間隔小于32ms時,人眼即無法分辨,因此,為了達到此要求,led的掃描頻率一般可按照下式計算得出:
f = 32 * n式中,
f為掃描的頻率,對應為定時器的定時時間(t=1/f);
32 則是由32ms換算而來,32ms對應的頻率剛好為 32Hz;
n則是總的led的組數(此例中為n=4)。
根據此式算出的掃描頻率f實際上是led 驅動掃描的最小頻率,若低于此頻率,則有可能導致led的閃爍。當然,f也不可能越高越好,掃描的頻率太高,相對而言,每一組led的點亮的時間就越短,因此有可能導致led的亮度不夠或顯示效果不理想等一些問題。當然提高led的驅動電壓也可以彌補由此造成的亮度不夠的問題。
在此例中,由公式可知其掃描的頻率應大于等于128hz,則較為理想。
2. mcu程序的實現:
a. 模塊的劃分:
在說明其編程之前,先說明一下模塊化編程思想在led驅動設計中的應用。為了使程序的結構清晰和維護的便利,特別是為了使程序的移植等變得可行,在程序的設計過程中應盡可能地采用模塊化的設計思想,對于復雜的程序結構和功能的實現,更應該在編程之前理順其相互之間的關系,劃分好各功能模塊所應完成的功能,定義好各模塊之間的數據接口和相互關系。
一般而言,顯示部分所涉及到的內容和功能相對較廣,比如按鍵的變化、系統狀態的變化、數據的變化等均需在顯示的結果上表現出來。因此,為了保證不同的模塊之間的獨立性,我們將與led顯示的有關的功能進行如下的劃分:
1.掃描驅動模塊:此模塊的功能只完成對所有led的掃描,而不關心所顯示的數據的具體變化情況,其從固定的顯示緩沖其中提取每一掃描地址所對應的數據,該對應關系是固定的,由程序設計時來設定。該實現的方法類似與pc機中crt的顯示驅動和顯示緩沖;
2.字符、點陣發生器:由于實際的數據與顯示的數據(pattern)之間并非是相同的,因此,需要將實際的數據轉化成能夠顯示的數據。例如在mcu中的各種計算的數據是以bcd碼或二進制碼的形式來表示的,需要將其轉化成7-段碼或nxn點陣的pattern數據進行顯示;
3. 顯示緩沖刷新和處理模塊:該模塊的功能是接受諸如按鍵、系統狀態變化、數據變化所引起的顯示數據的變化。其需要調用到字符、點陣發生器來完成顯示緩沖的刷新,其與按鍵、系統狀態變化等之間的接口是采用消息的機制來實現。該模塊一般需要根據不同的顯示內容來進行分類,比如在跑步機的設計中,可以劃分為如下的內容:距離、速度、時間、能量消耗、心率及其他相關的數據。
b. 程序架構和實現
1. 掃描模塊的實現:由于led的掃描驅動是一個重復的不間斷的過程,自然,定時中斷是最好的實現方法,其流程如圖6所示,其中bufFPt用于指向當前的顯示緩沖區,ai則為當前所需顯示的led組的地址編號,從0到n(n為總的led組數);
2. 刷新模塊的實現:在mcu的程序設計中,一般將此模塊置于16hz的定時中斷中(若主程序的循環周期不固定且最大的循環時間大于1/10秒時,常采用此架構)或主程序循環體中(此種情況主要時針對mcu時鐘比較高的場合或不需考慮顯示延時的情況下),通過檢測對應的消息來決定其是否需要執行數據的刷新。以跑步機的設計為例,其功能流程如圖7所示;
3. 字符、點陣發生器:由于在一些實際的應用中,可能的顯示內容原則上是可預知的和有限的,特別是漢字的顯示,因此其主要是通過定義相應的點陣來保存各種需要顯示數據。為了便于程序的設計,一般需將其按照一定的排列規則來進行定義,同時也需要為各個需要顯示的字符和圖符進行編碼,編碼的規則必須有利于程序的設計和提高代碼的效率,以求能夠采用統一的查表指令來實現。
圖6
注:上述的流程只是一個原理性的程序說明,在實際的應用中,需要根據mcu的特點及具體的硬件設計來進行程序的設計與簡化。比如:在實際的項目中有8x8(或小于8x8)個led需要驅動,而且所選的mcu又是8位或16位的,則此時的地址線的掃描將變得非常的簡單,只要建立字節變量ai,其初始值為0x01,然后在每次中斷處理程序中需將ai直接輸出到led掃描線所對應的io口即可,隨后將ai左移一位,對8x8 led情況,當ai=0時,表示一遍掃描完成,此時再將ai設為0x01即可。對于顯示的緩沖區的分配,同樣可以根據實際的軟件設計來分配具體的ram地址空間,以進一步提高程序的執行效率。記住,由于led的掃描需要占用較多的mcu時間,因此在進行掃描驅動的程序設計時,需要盡可能采用簡潔高效的代碼,以便提高mcu的工作效率。舉例來說,假如需驅動8x8 led,根據前面所講的要求,所需的定時器的中斷頻率必須是大于等于8x32,即256hz,若在此驅動代碼中多增加一條語句,則mcu每秒就需要多執行256條代碼,由此可見高效的代碼對于led驅動程序來講是多么重要,特別是當mcu的時鐘不夠快時!
評論