本文地址:https://www.cnblogs.com/jqdy/p/13906346.html
用12864顯示菜單時,將當前項菜單反白顯示是一個比較常見的顯示效果。然而,ST7920驅動的12864模塊擴展指令集中的反白顯示(Reverse)功能,卻沒有什么實際使用價值。因為反白第1行時,第3行也同時反白了;反白第2行時,第4行也同時反白了。
查閱網上資料,向DDRAM寫入文字,再向文字所在處的GDRAM內存相應位置寫入“1”,可實現反白效果。
為此,研究了一下ST7920的圖形操作。
1. GDRAM內存與屏幕的對應關系
GDRAM空間有64×256 bit 組成。使用擴展指令集中的Set Graphic RAM Address指令將GDRAM地址添加到AC(Address Counter)之后,就可向GDRAM寫入數據了。Set Graphic RAM Address是一個兩字節指令,連續寫入垂直地址(第一個字節)和水平地址(第二個字節)就可完成該指令。這樣就需要首先了解垂直地址、水平地址和GDRAM空間的關系。
- GDRAM的64個bit,每個 bit 對應着一行像素,從上到下分別記作0~63,這就是所謂“垂直地址”。
- GDRAM的256個bit,每個 bit 對應着一列像素,從左到右分成16組,每組包含16列像素,這16組像素依次分別記作0~15,這就是所謂“水平地址”,那么16組×16列像素/組=256列像素。
可見,GDRAM的垂直地址有64個(0~63),水平地址有16個(0~15)。利用Set Graphic RAM Address指令時,就是使用這兩組數據。那么,這兩組數據和屏幕的實際對應關系是怎樣的呢?
如下圖所示:12864屏幕只使用了上一半的GDRAM內存:
- 屏幕的第一行全寬字符:對應的垂直地址是0~15,水平地址是0~7
- 屏幕的第二行全寬字符:對應的垂直地址是16~31,水平地址是0~7
- 屏幕的第三行全寬字符:對應的垂直地址是0~15,水平地址是8~15
- 屏幕的第四行全寬字符:對應的垂直地址是16~31,水平地址是8~15
2. 如何向GDRAM寫入數據
使用Set Graphic RAM Address指令寫入垂直地址和水平地址之后,AC中就存儲了指定的GDRAM地址了,此時利用寫數據指令,就會向GDRAM中寫入圖形數據了。
垂直地址好理解,一個垂直地址就是一行像素的垂直位置。
一個水平地址指向16個 bit 數據,代表着屏幕上16個像素,這16位數據分別稱作 b15~b0,如上圖所示。值為1的位代表亮點,值為0的位代表暗點。因此連續寫入兩個字節的數據,就可完成一個水平地址的寫數據操作。根據Entry Mode設置的方向,寫完這兩個字節后,AC會自動±1。接着就可直接寫下一個水平地址包含的16位數據了。
連續寫入數據時有一個問題需要注意,當AC中的水平地址為15時,寫入16位數據后,AC中的水平地址將會自動變成0,而垂直地址不會發生變化。也就是說,當寫滿一行后,如果不調整垂直地址,就會反復在同一行中寫入,從而將前面寫入的數據擦除。
因此向GDRAM寫入數據的流程是:
- 使用Set Graphic RAM Address指令,連續寫入垂直地址和水平地址
- 使用寫數據指令,寫入b15~b8位構成的一個字節,再寫入b7~b0位構成的一個字節
- 根據需要看是否需要調整AC中的垂直地址和水平地址,然后再繼續寫入下一個水平地址的16個位
將一個全寬字符(漢字)位置對應的GDRAM全部寫1,就可實現這個漢字的反白效果,將一行全寬字符位置對應的GDRAM全部寫1,就可實現該行的反白,這樣就實現了菜單的反白顯示目的。
3. 切換基本指令集和擴展指令集需要注意的問題
寫字操作的是DDRAM,畫圖操作的是GDRAM,相關指令分屬基本指令集和擴展指令集。因此,在反白顯示操作時需要在兩個指令集中切換,切換涉及的寄存器結構如下,我采用的串行通訊,所以RS、RW不用考慮,僅考慮寄存器本身的位即可,其中DL位是8、4位並行通訊格式的選擇位,我也不用考慮,直接取0,使用8位並行通訊時取1。
在基本指令集和擴展指令集中切換時,注意不要影響DB1-G位。
- 執行指令:0x20(DB5=1,RE=0,G=0),可進入基本指令集,同時關閉圖形模式(將所畫圖形隱去,但GDRAM中的數據還在,再次開啟圖形模式時就會直接顯示圖形)
- 執行指令:0x22(DB5=1,RE=0,G=1),可進入基本指令集,同時保持圖形模式開啟(可操作DDRAM,例如寫字等,不影響后面的圖形,字型和圖形都是1的像素會反白)
- 執行指令:0x24(DB5=1,RE=1,G=0),可進入擴展指令集,但不開啟圖形模式
- 執行指令:0x26(DB5=1,RE=1,G=1),可進入擴展指令集,同時開啟圖形模式