12864點陣液晶顯示模塊的原理和實例程序(HJ12864M-1)


 12864點陣液晶顯示模塊(LCM)就是由128*64個液晶顯示點組成的一個128列*64行的陣列。每個顯示點對應一位二進制數,1表示亮,0表示滅。存儲這些點陣信息的RAM稱為顯示數據存儲器。要顯示某個圖形或漢字就是將相應的點陣信息寫入到相應的存儲單元中。圖形或漢字的點陣信息當然由自己設計,問題的關鍵就是顯示點在液晶屏上的位置(行和列)與其在存儲器中的地址之間的關系。

 

由於多數液晶顯示模塊的驅動電路是由一片行驅動器和兩片列驅動器構成,所以12864液晶屏實際上是由左右兩塊獨立的64*64液晶屏拼接而成,每半屏有一個512*8 bits顯示數據RAM。左右半屏驅動電路及存儲器分別由片選信號CS1和CS2選擇。(少數廠商為了簡化用戶設計,在模塊中增加譯碼電路,使得128*64液晶屏就是一個整屏,只需一個片選信號。)

 

顯示點在64*64液晶屏上的位置由行號(line,0~63)與列號(column,0~63)確定。512*8 bits RAM中某個存儲單元的地址由頁地址(Xpage,0~7)和列地址(Yaddress,0~63)確定。每個存儲單元存儲8個液晶點的顯示信息。

 

為了使液晶點位置信息與存儲地址的對應關系更直觀關,將64*64液晶屏從上至下8等分為8個顯示塊,每塊包括8行*64列個點陣。每列中的8行點陣信息構成一個8bits二進制數,存儲在一個存儲單元中。(需要注意:二進制的高低有效位順序與行號對應關系因不同商家而不同)存放一個顯示塊的RAM區稱為存儲頁。即64*64液晶屏的點陣信息存儲在8個存儲頁中,每頁64個字節,每個字節存儲一列(8行)點陣信息。因此存儲單元地址包括頁地址(Xpage,0~7)和列地址(Yaddress,0~63)。

 

例如點亮128*64的屏中(20,30)位置上的液晶點,因列地址30小於64,該點在左半屏第29列,所以CS1有效;行地址20除以8取整得2,取余得4,該點在RAM中頁地址為2,在字節中的序號為4;所以將二進制數據00010000(也可能是00001000,高低順序取決於制造商)寫入Xpage=2,Yaddress=29的存儲單元中即點亮(20,30)上的液晶點。

/////LCD12864液晶屏測試程序(已通過)//////  
////////液晶屏型號:HJ12864M-1//////////
///////////////////////////////////////

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int

//8bit數據接入IO口
#define Part P0 //P0接8位數據線
//控制數據端
sbit LCD_RS=P2^5; //定義12864液晶RS端,寄存器選擇信號 H:數據寄存器 L:指令寄存器
sbit LCD_RW=P2^6; //定義12864液晶RW端,讀/寫信號 H:讀 L:寫
sbit LCD_EN=P2^7; //定義12864液晶LCDEN端, 片選信號 下降沿觸發,鎖存數據
//
sbit LCD_PSB=P3^2; //定義12864液晶PSB端, H:並行 L:串行
sbit LCD_RST=P3^4; //定義12864液晶RST端, H:不復位 L:復位
uchar code dis1[]={"床前明月光"};
uchar code dis2[]={"疑是地上霜"};
uchar code dis3[]={"舉頭望明月"};
uchar code dis4[]={"低頭思故鄉"};
//=====================================
//毫秒延時函數
void delay(uint xms)
{
uint i,j;
for(j=0;i<xms;j++)
for(i=0;i<110;i++);
}
//====================================
//LCD忙檢測函數
bit lcd_busy()
{
bit result;
LCD_RS=0;
LCD_RW=1;
LCD_EN= 1;
result=(bit)(Part & 0x80);
LCD_EN=0;
return result;
}
//=====================================
//液晶寫命令函數
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;
}
//=====================================
//液晶寫一個字符數據函數
void lcd_write_dat(uchar date)
{
while(lcd_busy());
LCD_RS=1; //選擇數據寄存器
LCD_RW=0; //
LCD_EN=0;
P0=date; //數據值賦給P0口
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
//=====================================
//液晶寫一個字符串函數
void lcd_write_string(uchar *str)
{
while(*str!='\0') //未結束
{
lcd_write_dat(*str++);
delay(5);
}
}
//=====================================
//液晶顯示位置函數
void lcd_pos(uchar x,uchar y) //從第X行的第Y位置開始顯示
{
uchar pos;
if(x==1) //第一行
{ x=0x80;}
else if(x==2) //第二行
{ x=0x90;}
else if(x==3) //第三行
{ x=0x88;}
else if(x==4) //第四行
{ x=0x98;}
pos=x+y-1; //首地址為0X80
lcd_write_cmd(pos);
}
//=====================================
//液晶初始化函數
void lcd_init()
{
LCD_PSB=1; //並行方式
LCD_RST=1; //不復位
lcd_write_cmd(0x30);
delay(5);
lcd_write_cmd(0x0c); //開顯示,不顯示光標
delay(5);
lcd_write_cmd(0x06); //寫一個字符后地址指針自動加1
delay(5);
lcd_write_cmd(0x01); //清屏
delay(5);
}
//=====================================
//主函數函數
void main()
{
// uchar i;
lcd_init();
while(1)
{
lcd_pos(1,1);
// lcd_write_string(dis1);
lcd_write_string("床前明月光");
delay(5);
lcd_pos(2,1);
// lcd_write_string(dis2);
lcd_write_string("疑是地上霜");
delay(5);
lcd_pos(3,1);
// lcd_write_string(dis3);
lcd_write_string("舉頭望明月");
delay(5);
lcd_pos(4,1);
// lcd_write_string(dis4);
lcd_write_string("低頭思故鄉");
delay(500);
}
}


 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM