使用 8 位 MCU、小型 BOM 和本文提供的可下載代碼來(lái)驅(qū)動(dòng)多路復(fù)用 4 段 LCD 是一件簡(jiǎn)單的事情。
無(wú)需微控制器上的專用 LCD 驅(qū)動(dòng)器即可直接驅(qū)動(dòng) LCD,并且需要很少的額外資源。LCD 有兩種類型——靜態(tài)和多路復(fù)用。本文討論了多路復(fù)用 LCD 與 Zilog 的 Z8 Encore!? 微控制器的編程。
Z8 安可!閃存微控制器概述
Zilog 的 Z8 安可!產(chǎn)品基于 eZ8? CPU,并將閃存引入 Zilog 廣泛的 8 位微控制器系列。閃存在線編程能力允許更快的開(kāi)發(fā)時(shí)間和現(xiàn)場(chǎng)程序更改。eZ8 內(nèi)核的高性能、基于寄存器到寄存器的架構(gòu)保持與 Zilog 流行的 Z8 MCU 的向后兼容性。
Z8 安可!MCU 將 20 MHz 內(nèi)核與閃存、線性寄存器 SRAM 和大量片上外設(shè)組合在一起。這些外圍設(shè)備造就了 Z8 Encore!MCU 適用于各種應(yīng)用,包括電機(jī)控制、安全系統(tǒng)、家用電器、個(gè)人電子設(shè)備和傳感器。
驅(qū)動(dòng)液晶顯示器
靜態(tài) LCD 具有用于 LCD 的每個(gè)段的單獨(dú)引腳和一個(gè)公共背板引腳。照亮分段的要求是使分段偏向背板。另一個(gè)要求是 LCD 不能讓直流電 (DC) 出現(xiàn)在段上。
為了防止段上出現(xiàn)直流,背板用低頻方波驅(qū)動(dòng),段相對(duì)于背板進(jìn)行切換。
多路 LCD 具有多個(gè)背板,并且多個(gè)段之間共享一個(gè)段引腳。為了照亮特定的段,段引腳與背板相反驅(qū)動(dòng),未使用的背板保持空閑狀態(tài)。背板再次使用低頻方波驅(qū)動(dòng),以防止分段上的直流偏置。
挑戰(zhàn)
由于段的多路復(fù)用排列,對(duì)多路復(fù)用 LCD 進(jìn)行編程可能是一項(xiàng)艱巨的任務(wù)。多路復(fù)用 LED 通常為每個(gè) LED 數(shù)字配備一個(gè)單獨(dú)的背板。然而,多路復(fù)用 LCD 將其背板布置在數(shù)字的頂部、中間和底部。這種安排會(huì)使解碼過(guò)程變得非常復(fù)雜,但重要的是,即使具有專用 LCD 驅(qū)動(dòng)器的微控制器仍然需要一個(gè)困難的解碼過(guò)程(見(jiàn)圖 1)。

圖 1:分段排列。
下一個(gè)工程任務(wù)與照亮一段所需的電壓有關(guān)。多路復(fù)用段的 ON 驅(qū)動(dòng)電平降低了,因?yàn)樵摱未蟛糠謺r(shí)間都處于空閑狀態(tài),并且只有 25% 的時(shí)間被斷言。實(shí)際上,這句話意味著在較低的工作電壓下,一個(gè)段可能不會(huì)發(fā)光。
更復(fù)雜的情況是,當(dāng)共享段引腳由當(dāng)前活動(dòng)的背板斷言時(shí),段可以在其關(guān)閉狀態(tài)下感知電壓電位。隨著更多的背板被添加到顯示器,這些對(duì)比問(wèn)題可能會(huì)變得更糟,因?yàn)槊吭黾右粋€(gè)背板,可用的導(dǎo)通電壓就會(huì)降低,而剩余的關(guān)斷電壓會(huì)增加。
圖 2 顯示了每個(gè)背板的對(duì)比度如何降低,因?yàn)?ON 段和 OFF 段之間的差異較小。在圖 2 中,帶有一個(gè)背板的靜態(tài)顯示器在開(kāi)啟電壓時(shí)接收其可用 Vcc 的 100%,在關(guān)閉電壓時(shí)接收 0%。在三平面示例中,V cc的一半可用于 ON 電壓,OFF 段接收 V cc的四分之一。LCD 因制造商而異,但典型閾值電壓為 2.3 V RMS。

圖 2:驅(qū)動(dòng)電平。
由于只有一半的 V cc可用于導(dǎo)通電壓,因此很容易看出 3.3 V 微控制器如何無(wú)法直接驅(qū)動(dòng)多路復(fù)用 LCD。本文的目的是展示您可以在 3 V Z8 Encore 上驅(qū)動(dòng)多路復(fù)用 LCD!單片機(jī)。
硬件架構(gòu)
要使用 3 V MCU 驅(qū)動(dòng)多路復(fù)用 LCD,必須提高驅(qū)動(dòng)電平。為了減少門(mén)數(shù)和復(fù)雜性,只對(duì)背板進(jìn)行了提升。段驅(qū)動(dòng)電壓擺動(dòng)高于和低于 Vcc 的二分之一;因此,增強(qiáng)的背板信號(hào)必須使用 Z8 Encore 以相同的方式執(zhí)行!MCU 的端口引腳作為兩個(gè)電荷泵,參考電壓為 V cc的二分之一。IC1,4050緩沖器用于提供電平轉(zhuǎn)換功能。
每個(gè)背板被驅(qū)動(dòng)為高電平,并在其他平面被驅(qū)動(dòng)時(shí)處于空閑狀態(tài)。該過(guò)程被反轉(zhuǎn)以去除任何直流分量,如圖 3 所示。

圖 3:背板波形。
通過(guò)在有源背板的相反方向上驅(qū)動(dòng)段引腳來(lái)打開(kāi)段,通過(guò)在有源背板的方向上驅(qū)動(dòng)引腳來(lái)關(guān)閉段。在背板的空閑狀態(tài)期間,任何段上的電壓都低于閾值電壓。結(jié)果,這些段保持不亮。
軟件實(shí)施
由于 Z8 Encore 的額外速度和內(nèi)存!家庭,假設(shè)開(kāi)發(fā)發(fā)生在 C 編程語(yǔ)言中。如果軟件被編寫(xiě)為易于移植,則用 C 編寫(xiě)的應(yīng)用程序可以輕松移植到不同的環(huán)境。
考慮到這一點(diǎn),宏用于特定于 I/O 的操作,以便在將代碼移植到另一個(gè)設(shè)備時(shí),大部分軟件將保持不變。
以下代碼段維護(hù)電荷泵。
/*電荷泵定義
電荷泵提升段驅(qū)動(dòng)電壓并在每個(gè)定時(shí)器中斷時(shí)提供服務(wù)。正泵被拉低以充電并浮動(dòng)到輸入狀態(tài)。充電時(shí)負(fù)泵懸空。電容以 1/2 VCC 為參考,電容器上的電荷似乎是 VCC +/- 參考。該宏還初始化端口的端口模式,因此它總是被刷新。
*/
#define ChargePumpsPDADDR=PxHD;
PDCTL|= B3|B4; PDOD&=~B3;
PDOD|=B4;PDADDR=PxOC;
PDCTL&=~(B3|B4); PDADDR=PxDDR;
PDCTL&=~(B3|B4)
#define FloatPumpsPDADDR=PxDDR; PDCTL|=B4|B3
以下宏管理背板驅(qū)動(dòng)器。這些宏很復(fù)雜,因?yàn)槊總€(gè)背板只需要一個(gè)引腳,但每個(gè)背板需要兩個(gè)引腳狀態(tài)。
/*背板驅(qū)動(dòng)器需要三種狀態(tài):ON、OFF 和 IDLE。通過(guò)將 BP1 與 BP2、BP2 與 BP3 以及 BP3 與 BP1 混合,可以在每個(gè)平面上獲得所有三種狀態(tài),而無(wú)需額外的引腳。
PlaneX123
_______________
BP11101
BP20110
BP31011
`BP10010
`BP21001
`BP30100
*/
#define SetUpBackplanePDADDR=PxOC;
PDCTL&=~(B0|B5|B6);
PDADDR=PxDDR;PDCTL&=~(B0|B5|B6)
#define BP1PDOD&=~B6; PDOD|=B0|B5
#define BP2PDOD&=~B5; PDOD|=B0|B6
#define BP3PDOD&=~B0; PDOD|=B6|B5
#define NotBP1PDOD&=~(B0|B5); PDOD|=B6
#define NotBP2PDOD&=~(B0|B6); PDOD|=B5
#define NotBP3PDOD&=~(B5|B6); PDOD|=B0
最后,用于驅(qū)動(dòng)段的宏。
/*下一個(gè)宏獲取存儲(chǔ)在顯示緩沖區(qū)中的各個(gè)段并將它們放在端口上。它可以在沒(méi)有宏的情況下完成,但這使它更通用。將有六個(gè)平面和兩個(gè)緩沖區(qū),因?yàn)橛谐^(guò) 8 個(gè)段*/
#define DisplaySegmentsPAOD&=~0xF8;
PAOD|=(緩沖區(qū)[平面]&0x00F8); PCOD=0;
PCOD|=((緩沖區(qū)[平面]&0x7F00)》》8)
如前所述,多路 LCD 中涉及的困難編程是一種相當(dāng)不尋常的多路復(fù)用方案。前面的宏只是將先前解碼的段從緩沖區(qū)放到端口上。由于解碼過(guò)程如此復(fù)雜,它不在中斷服務(wù)程序 (ISR) 中執(zhí)行。ISR 必須盡可能短;ISR 中所需的只是設(shè)置背板和驅(qū)動(dòng)段。緩沖區(qū)是一個(gè)整數(shù)數(shù)組,其中包含我們顯示中使用的 12 個(gè)段。該數(shù)組中的一維是平面。此維度中有六個(gè)平面,每個(gè)背板狀態(tài)一個(gè):A、B、C、A‘、B’ 和 C‘。解碼過(guò)程完成后,緩沖區(qū)必須加載跨越六個(gè)平面的 12 段數(shù)據(jù)。
解碼的第一步是定義字符的顯示方式。此定義適用于所有七段顯示器。因此,可以重用以下代碼段。
#define Dig_0Seg_a | 段_b | 段_c | 段_d | 賽段 | Seg_f
#define Dig_1Seg_b | Seg_c
#define Dig_2Seg_a | 段_b | 段_g | 賽段 | Seg_d
#define Dig_3Seg_a | 段_b | 段_g | 段_c | Seg_d
#define Dig_4Seg_f | 段_g | 段_b | Seg_c
#define Dig_5Seg_a | 段_f | 段_g | 段_c | Seg_d
#define Dig_6Seg_a | 段_f | 段_g | 段_c | 段_d | Seg_e
#define Dig_7Seg_a | Dig_1
#define Dig_8Seg_g | Dig_0
#define Dig_9Seg_a | 段_f | 段_g | 段_b | Seg_c
#define Dig_ASeg_a | 段_b | 段_c | 段_g | 賽段 | Seg_f
#define Dig_bSeg_f | 賽段 | 段_g | 段_d | Seg_c
#define Dig_CSeg_a | 段_f | 賽段 | Seg_d
#define Dig_dSeg_b | 段_c | 段_d | 賽段 | 說(shuō)_g
#define Dig_ESeg_a | 段_f | 賽段 | 段_d | Seg_g
#define Dig_FSeg_a | 段_f | 賽段 | Seg_g
#define Dig_gSeg_a | 段_f | 段_g | 段_b | 段_c | Seg_d
#define Dig_hSeg_g | 段_c | 賽段 | Seg_f
#define Dig_IDig_1
#define Dig_JDig_1 | Seg_d
#define Dig_LSeg_d | 賽段 | Seg_f
#define Dig_nSeg_c | 賽段 | Seg_g
#define Dig_ODig_0
#define Dig_PSeg_g | 段_a | 段_b | 賽段 | Seg_f
#define Dig_rSeg_g | 賽段 | Seg_f
#define Dig_SSeg_g | 段_a | 段_c | 段_d | Seg_f
#define Dig_tSeg_g | 賽段 | 段_f | Seg_d
#define Dig_USeg_b | 段_c | 段_d | 賽段 | Seg_f
這些段分散在三個(gè)獨(dú)立的背板上,并且必須以三個(gè)比特的三個(gè)數(shù)據(jù)包的形式排列在一個(gè)字節(jié)中。最后一位未使用。這種排列反映了顯示數(shù)字的物理布局(見(jiàn)表 1)

表 1:段分配。
#define Seg_a1
#define Seg_g2
#define Seg_d4
#define Seg_b8
#define Seg_c16
#define Seg_dp32
#define Seg_f64
#define Seg_e128
我們的目標(biāo)是將分段數(shù)據(jù)放入三個(gè)整數(shù)中——每個(gè)顯示背板一個(gè)。軟件必須將代表七段字符的單個(gè)字節(jié)分成三個(gè)平面的三個(gè)段。表 2 指示整數(shù)數(shù)組如何存儲(chǔ)各個(gè)段位。

由于 LCD 的每個(gè)數(shù)字都需要三個(gè)段,因此尋址正確的段引腳需要將每個(gè)數(shù)字的數(shù)據(jù)移位三位。最后,必須尋址微控制器的正確物理引腳。以下代碼段中的分配可以根據(jù)電路板布局和其他資源進(jìn)行更改。
#define Seg_1AGD8//PAOD|=B3
#define Seg_1BCDP16//PAOD|=B4
#define Seg_1FE32//PAOD|=B5
#define Seg_2AGD64//PAOD|=B6
#define Seg_2BCDP128//PAOD|=B7
#define Seg_2FE256// PCOD |=B0
#define Seg_3AGD512//PCOD|=B1
#define Seg_3B??CDP1024//PCOD|=B2
#define Seg_3FE2048//PCOD|=B3
#define Seg_4AGD4096//PCOD|=B4
#define Seg_4BCDP8192//PCOD|=B5
#定義 Seg_4FE16384//PCOD|=B6
以下代碼段確定哪些段為特定字符打開(kāi)。
for (digit=0, shift=9; digit《4; digit++,shift-=3)
{
段[0]|=(0x07 &
CharTbl[que[digit]])《
段[1]|=((0x38 & CharTbl[que[dig
它]])》》3)《
段[2]|=((0x1C0 & CharTbl[que[di
混帳]])》》6)《
}
存儲(chǔ)正確的段以打開(kāi)需要測(cè)試每個(gè)單獨(dú)的位。優(yōu)點(diǎn)是代碼變得非常可移植,如下所示:
對(duì)于(平面=0;平面《3;平面++)
{
如果(段[平面]&B0)
緩沖區(qū)[平面]|=Seg_1AGD;
如果(段[平面]&B1)
緩沖區(qū)[平面]|=Seg_1BCDP;
如果(段[平面]&B2)
緩沖區(qū)[平面]|=Seg_1FE;
如果(段[平面]&B3)
緩沖區(qū)[平面]|=Seg_2AGD;
等等
}
/*我們?cè)谶@里有一個(gè)賦值,而不是在上面的語(yǔ)句中設(shè)置單個(gè)變量,因?yàn)樵谑占螘r(shí)會(huì)發(fā)生計(jì)時(shí)器 IRQ,這將導(dǎo)致顯示閃爍。最后三個(gè)緩沖區(qū)只是前三個(gè)緩沖區(qū)的補(bǔ)充。*/
緩沖區(qū)[0]=臨時(shí)緩沖區(qū)[0];
緩沖區(qū)[1]=臨時(shí)緩沖區(qū)[1];
緩沖區(qū)[2]=臨時(shí)緩沖區(qū)[2];
緩沖區(qū)[3]=~緩沖區(qū)[0];
緩沖區(qū)[4]=~緩沖區(qū)[1];
緩沖區(qū)[5]=~緩沖區(qū)[2];
總結(jié)
直接驅(qū)動(dòng) LCD 所需的實(shí)際代碼并不是很復(fù)雜。在這個(gè) C 示例中,解碼各個(gè)分段平面所需的時(shí)間僅為 141 μs。優(yōu)點(diǎn)是無(wú)需額外的 LCD 驅(qū)動(dòng)器或使用帶有專用驅(qū)動(dòng)器的微控制器即可直接驅(qū)動(dòng)超大顯示器。唯一的缺點(diǎn)是電荷泵和背板驅(qū)動(dòng)需要額外的引腳,但在大多數(shù)情況下,額外的引腳比專用驅(qū)動(dòng)器便宜。
圖 4 顯示了使用 Z8 Encore 的 LCD 驅(qū)動(dòng)器的示意圖!單片機(jī)。

圖 4:使用 Z8 Encore 的 LCD 驅(qū)動(dòng)器示意圖!單片機(jī)。
評(píng)論