12864點陣液晶顯示模塊的原理和實例程序(HJ12864M-1)
12864點陣液晶顯示模塊(LCM)就是由128*64個液晶顯示點組成的一個128列*64行的陣列。每個顯示點對應(yīng)一位二進制數(shù),1表示亮,0表示滅。存儲這些點陣信息的RAM稱為顯示數(shù)據(jù)存儲器。要顯示某個圖形或漢字就是將相應(yīng)的點陣信息寫入到相應(yīng)的存儲單元中。圖形或漢字的點陣信息當(dāng)然由自己設(shè)計,問題的關(guān)鍵就是顯示點在液晶屏上的位置(行和列)與其在存儲器中的地址之間的關(guān)系。
由于多數(shù)液晶顯示模塊的驅(qū)動電路是由一片行驅(qū)動器和兩片列驅(qū)動器構(gòu)成,所以12864液晶屏實際上是由左右兩塊獨立的64*64液晶屏拼接而成,每半屏有一個512*8 bits顯示數(shù)據(jù)RAM。左右半屏驅(qū)動電路及存儲器分別由片選信號CS1和CS2選擇。(少數(shù)廠商為了簡化用戶設(shè)計,在模塊中增加譯碼電路,使得128*64液晶屏就是一個整屏,只需一個片選信號。)
顯示點在64*64液晶屏上的位置由行號(line,0~63)與列號(column,0~63)確定。512*8 bits RAM中某個存儲單元的地址由頁地址(Xpage,0~7)和列地址(Yaddress,0~63)確定。每個存儲單元存儲8個液晶點的顯示信息。
為了使液晶點位置信息與存儲地址的對應(yīng)關(guān)系更直觀關(guān),將64*64液晶屏從上至下8等分為8個顯示塊,每塊包括8行*64列個點陣。每列中的8行點陣信息構(gòu)成一個8bits二進制數(shù),存儲在一個存儲單元中。(需要注意:二進制的高低有效位順序與行號對應(yīng)關(guān)系因不同商家而不同)存放一個顯示塊的RAM區(qū)稱為存儲頁。即64*64液晶屏的點陣信息存儲在8個存儲頁中,每頁64個字節(jié),每個字節(jié)存儲一列(8行)點陣信息。因此存儲單元地址包括頁地址(Xpage,0~7)和列地址(Yaddress,0~63)。
例如點亮128*64的屏中(20,30)位置上的液晶點,因列地址30小于64,該點在左半屏第29列,所以CS1有效;行地址20除以8取整得2,取余得4,該點在RAM中頁地址為2,在字節(jié)中的序號為4;所以將二進制數(shù)據(jù)00010000(也可能是00001000,高低順序取決于制造商)寫入Xpage=2,Yaddress=29的存儲單元中即點亮(20,30)上的液晶點。
/////LCD12864液晶屏測試程序(已通過)//////
////////液晶屏型號:HJ12864M-1//////////
///////////////////////////////////////
#include
#define uchar unsigned char
#define uint unsigned int
//8bit數(shù)據(jù)接入IO口
#define Part P0 //P0接8位數(shù)據(jù)線
//控制數(shù)據(jù)端
sbit LCD_RS=P2^5; //定義12864液晶RS端,寄存器選擇信號 H:數(shù)據(jù)寄存器 L:指令寄存器
sbit LCD_RW=P2^6; //定義12864液晶RW端,讀/寫信號 H:讀 L:寫
sbit LCD_EN=P2^7; //定義12864液晶LCDEN端, 片選信號 下降沿觸發(fā),鎖存數(shù)據(jù)
//
sbit LCD_PSB=P3^2; //定義12864液晶PSB端, H:并行 L:串行
sbit LCD_RST=P3^4; //定義12864液晶RST端, H:不復(fù)位 L:復(fù)位
uchar code dis1[]={"床前明月光"};
uchar code dis2[]={"疑是地上霜"};
uchar code dis3[]={"舉頭望明月"};
uchar code dis4[]={"低頭思故鄉(xiāng)"};
//=====================================
//毫秒延時函數(shù)
void delay(uint xms)
{
uint i,j;
for(j=0;i for(i=0;i<110;i++); } //==================================== //LCD忙檢測函數(shù) bit lcd_busy() { bit result; LCD_RS=0; LCD_RW=1; LCD_EN= 1; result=(bit)(Part & 0x80); LCD_EN=0; return result; } //===================================== //液晶寫命令函數(shù) void lcd_write_cmd(uchar com) { while(lcd_busy()); LCD_RS=0; //選擇指令寄存器 LCD_RW=0; //寫 LCD_EN=0; Part=com; //指令值賦給P0口 delay(5); LCD_EN=1; delay(5); LCD_EN=0; } //===================================== //液晶寫一個字符數(shù)據(jù)函數(shù) void lcd_write_dat(uchar date) { while(lcd_busy()); LCD_RS=1; //選擇數(shù)據(jù)寄存器 LCD_RW=0; //寫 LCD_EN=0; P0=date; //數(shù)據(jù)值賦給P0口 delay(5); LCD_EN=1; delay(5); LCD_EN=0; } //===================================== //液晶寫一個字符串函數(shù) void lcd_write_string(uchar *str) { while(*str!='