本文解析一段基於8051單片機的LCD12864圖形點陣液晶驅動程式碼。程式碼採用C語言編寫,包含底層埠定義、時序控制、資料寫入、中文字元顯示等核心功能,適合嵌入式開發者學習參考。
sfr P0 = 0x80; // 資料埠
sfr P1 = 0x90;
sfr P2 = 0xA0; // 控制埠
sfr P3 = 0xB0;
sbit cs1 = P2^0; // 片選1(左半屏)
sbit cs2 = P2^1; // 片選2(右半屏)
sbit e = P2^2; // 使能訊號
sbit rw = P2^3; // 讀/寫控制(可接地常態寫入)
sbit di = P2^4; // 資料/指令選擇
sbit rst = P2^5; // 複位腳(預設高電平,可接電源)
extern unsigned char code abc[]; // 外部字模資料表(存放於程式碼區)
關鍵點:cs1/cs2 控制左右半屏(各64列),e 訊號下降沿有效,di=0 寫指令,di=1 寫資料。
void ys(int ms) {
int k, d;
for (k = 0; k < ms; k++)
for (d = 0; d < 123; d++); // 簡易延時,需根據晶振頻率校準
}
雙層迴圈實現毫秒級延時,實際專案建議使用定時器中斷或 _nop_() 精確延時。
write()void write(bit s, unsigned char d) {
rw = 0; // 允許寫入
di = s; // 0=指令, 1=資料
P0 = d; // 輸出資料到資料埠
e = 1; // 使能高電平
e = 0; // 使能低電平(產生下降沿,鍵存資料)
rw = 1; // 禁止寫入
}
採用標準8080介面時序:資料建立 → E拉高 → E拉低(下降沿鎖存) → 釋放總線。
writexy()void writexy(unsigned char x, unsigned char y, unsigned char d) {
cs1 = (y / 64) % 2; // y>=64 選右半屏
cs2 = ~cs1; // 互斥選擇
write(0, 0x3F); // 開啟顯示
write(0, 0xC0); // 設定起始行
write(0, 0xB8 + x); // 設定X地址(頁地址,0-7)
write(0, 0x40 + (y % 64)); // 設定Y地址(列地址,0-63)
write(1, d); // 寫入顯示資料
}
LCD12864 分為兩個獨立控制器(KS0108相容),每邊64列。x 對應頁(每頁8行),y 對應列。
hzk16()void hzk16(unsigned char x, unsigned int y, unsigned int d) {
unsigned int k;
for (k = 0; k < 16; k++) {
writexy(x * 2 + 0, y * 16 + k, abc[d * 32 + k]); // 上半部 16x16
writexy(x * 2 + 1, y * 16 + k, abc[d * 32 + k + 16]); // 下半部
}
}
每個漢字佔 16x16 點陣,共32字節字模。abc[] 為字模庫,索引 d 選擇字元。顯示時將一個漢字拆為上下兩半,分別寫入相鄰兩頁。
void main() {
unsigned int k, d;
while (1) {
for (k = 0; k < 4; k++) // 4行
for (d = 0; d < 8; d++) // 8列
hzk16(k, d, d); // 顯示字模索引為 d 的漢字
}
}
無限迴圈掃描 4 行 × 8 列位置,顯示前 32 個漢字字模,形成字模測試畫面。
ys() 延時不精確,移植時請根據目標MCU時鐘重寫或使用硬體定時器。abc[] 應放置於Flash(code 關鍵字),大字庫建議外掛SPI Flash。write() 底層傳輸邏輯,上層座標邏輯可復用。xdata/code 空間分配。這段程式碼展示了LCD12864並口驅動的經典實現:埠定義、時序控制、雙控制器座標映射、中文字模拆分顯示。理解其邏輯有助於快速移植到其他單片機平台或改寫為其他介面的圖形顯示驅動。