12864
點陣式液晶顯示模塊(LCD)廣泛應用于單片機控制系統,比數碼管、段式液晶能模塊顯示很多其它、更直觀的信息,如漢字、曲線、圖片等。點陣液晶顯示模塊集成度非常高,一般都內置控制芯片、行驅動芯片和列驅動芯片,點陣數量較大的LCD還配置RAM芯片,帶漢字庫的LCD還內嵌漢字庫芯片,有負壓輸出的LCD還設有負壓驅動電路等。單片機讀寫LCD實際上就是對LCD的控制芯片進行讀寫命令和數據。編程驅動LCD時,不須要對LCD的結構和點陣行列驅動原理深入了解,僅僅要理解LCD接口的定義和LCD的控制芯片的讀寫時序和命令就能夠了。
12864LCD屬于點陣圖形液晶顯示模塊,不但能顯示字符,還能顯示漢字和圖形,分帶漢字庫和不帶那字庫兩種,價格也有區別。帶漢字庫的12864LCD使用起來很方便,不須要編寫復雜的漢字顯示程序,僅僅要按時序寫入兩個字節的漢字機內碼,漢字就能顯示出來了,驅動程序簡單很多。本文例程就是基于帶漢字庫的12864液晶顯示模塊。
常見的12864LCD使用的控制芯片是ST7920。ST7920一般和ST7921(列驅動芯片)配合使用,做成顯示2行每行16個漢字的顯示屏25632LCD,或者是做成4行每行8個漢字的顯示屏12864LCD。12864LCD的讀寫時序和1602LCD是一樣的,全然能夠照搬1602LCD驅動程序的讀寫函數。須要注意的是,12864LCD分成上半屏和下半屏,并且兩半屏之間的點陣內存映射地址不連續,給驅動程序的圖片顯示函數的編寫添加�了難度。
二.電路設計
通常,12864LCD屏內都會自帶背光限流電阻,背光管腳能夠直接連接DC5V電源使用。12864LCD對照度調節的電位器取值10K-20K歐姆。假設說明書有明白要求的,請使用說明書規定的參數。
?
???????????????????? ????? ??????????????????
??
三.軟件設計
/*****************************************************************
*程序名稱:帶漢字庫的12864液晶顯示模塊驅動
*程序功能:顯示字符、漢字和圖片
*開發工具:WSF-51DB開發板
* MCU型號:AT89S52-24PU
*時鐘頻率:12MHZ
*程序作者:吳師傅
*版權說明:吳師傅版權全部。轉載請注明來源和作者
*****************************************************************/
#i nclude<reg52.h>
???????????????????? ??????
sbit E=P3^4;//脈沖使能
sbit RW=P3^3;//讀寫選擇
sbit RS=P3^2;//數據命令選擇
sbit rst=P1^0;//12864復位
????????????????????????????????????????????????????????????????????????????
unsigned char code pictrue2[192]={//圖片:機器貓48*32
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X7F,0X80,0X00,0X00,0X00,0X1F,0XFF,
0XFE,0X00,0X00,0X00,0X7F,0X1F,0XFF,0X80,0X00,0X01,0XFC,0X0C,0X3F,0XE0,0X00,0X07,
0XF8,0X48,0X1F,0XF8,0X00,0X0F,0X98,0XD1,0X8F,0XFC,0X00,0X1C,0X4C,0XF3,0X9F,0XFE,
0X00,0X1A,0X33,0X39,0XB3,0XFE,0X00,0X33,0XE3,0XFC,0X40,0XFE,0X00,0X31,0X81,0XE1,
0X9E,0X7F,0X00,0X10,0XC1,0X03,0XC0,0X3E,0X00,0X18,0X01,0X03,0X70,0X9E,0X00,0X1F,
0X03,0X03,0X83,0X9E,0X00,0X09,0XE2,0X00,0X3E,0X1C,0X00,0X04,0X3F,0X80,0XFF,0X3C,
0X00,0X07,0X01,0XFF,0XC0,0X70,0X00,0X0F,0XC0,0X00,0X00,0XE0,0X00,0X1F,0XF8,0X00,
0X03,0X80,0X0F,0X0C,0X3F,0XE0,0X1E,0X00,0X39,0XED,0X3B,0XFF,0XFF,0X00,0X20,0X7A,
0XFE,0X07,0XFF,0X80,0X60,0X1C,0X1C,0X07,0XFF,0X80,0X60,0X0F,0X03,0XF7,0XFF,0X80,
0X20,0X0F,0XDE,0X3F,0XFF,0X80,0X30,0X0F,0XF0,0X0F,0XFF,0XA0,0X1C,0X0F,0XE0,0X07,
0XF8,0X30,0X0F,0XFF,0XE0,0X03,0XC8,0X60,0X01,0XE0,0X20,0X03,0X87,0XC0,0X00,0X00,
0X30,0X07,0X00,0X00,0X00,0X00,0X0C,0X0C,0X00,0X00,0X00,0X00,0X07,0XF0,0X00,0X00,
};
?????????????
// 延時ms函數:
void Delayms(unsigned int t)
{
??? unsigned int i,j;
??? for(i=t;i>0;i--)
?????? ????? for(j=0;j<120;j++);
}
?
// 12864檢查狀態函數:
void Check12864State(void)
{?
??????? P2=0xff;
??????? E=0;//讀狀態前三控制線的狀態
??????? RS=0;
?????? ?RW=1;
?????? ?E=1;//拉高,讀狀態
?????? ?while((P2&0x80)==0x80);//等待空暇
?????? ?E=0;//寫命令后三控制線的狀態
?????? ?RS=1;
?????? ?RW=0;
}
?
// 12864寫命令函數:
void Write12864Command( unsigned char com)
{?
?????? Check12864State();//檢查狀態
?????? P2=com;//賦值
?????? E=0;//寫命令前三控制線的狀態
?????? RS=0;
?????? RW=0;
?????? E=1;//拉高,寫命令
?????? E=0;//寫命令后三控制線的狀態
?????? RS=1;
?????? RW=1;
}
?
//12864寫數據函數:
void Write12864Data( unsigned char dat)
{
?????? Check12864State();//檢查狀態
?????? P2=dat;//賦值
?????? E=0;//寫數據前三控制線的狀態
?????? RS=1;
?????? RW=0;???
???????E=1;//拉高,寫數據
?????? E=0;//寫數據后三控制線的狀態
?????? RS=0;
?????? RW=1;
}????
?
//在指定的位置顯示變量值函數:
void LCD12864DisplayValue( unsigned char y,unsigned char x,unsigned char v)
??????????????????? //y-行數值0-3,x-列數值0-7,v-變量
{
?? unsigned char row;
?? Write12864Command(0x30);//基本指令
???Write12864Command(0x06);//地址計數器自己主動加以,光標右移
?? switch(y)//依據行號選擇行地址
?? {
?????????????? case 0:row=0x80;break;//第一行首地址
????????????? ?case 1:row=0x90;break;//第二行首地址
????????????? ?case 2:row=0x88;break;//第三行首地址
????????????? ?case 3:row=0x98;break;//第四行首地址
????????????? ?default:;
?? }
?? Write12864Command(row+x);//寫地址
?? Write12864Data(0x30+v/100);//百位,先將數字化成ASCII碼,再寫入
?? Write12864Data(0x30+v%100/10);/十位/先將數字化成ASCII碼,再寫入
?? Write12864Data(0x30+v%10);//個位,先將數字化成ASCII碼,再寫入
}????
?
//在指定的位置顯示字符串(漢字和ASCII碼字符)函數:
void LCD12864DisplayString( unsigned char y,unsigned char x, unsigned char *pstr)
? //y-行數值0-3,x-列數值0-7,pstr-字符串指針
?//12864能夠顯示32個漢字(四行每行8個),一個地址相應一個漢字
//能夠顯示64個ASCII碼字符(四行每行16個),一個地址相應兩個字符
? //為了實現自己主動換行功能,這個函數比較繁瑣
{
???? unsigned char row,n=0;
???? Write12864Command(0x30);//基本指令
???? Write12864Command(0x06);//地址計數器自己主動加以,光標右移
???? switch(y)//依據行號選擇行地址
???? {
???????????????? case 0:row=0x80;break;//第一行首地址
????????????? ?? case 1:row=0x90;break;//第二行首地址
????????????? ?? case 2:row=0x88;break;//第三行首地址
????????????? ?? case 3:row=0x98;break;//第四行首地址
????????????? ?? default:;
???? }
???? Write12864Command(row+x);//寫地址
???? while(*pstr!='\0')
???? {
?????? ???????? Write12864Data(*pstr);//寫字符
????????????? ? pstr++;
????????????? ? n++;//計數
????????????? ? if((n+x*2)==16)//假設一行寫完,繼續寫第二行
????????????? ? {
????????????? ???????? if(y==0) Write12864Command(0x90);//寫下一行地址
????????????? ???????? else if(y==1) Write12864Command(0x88);//寫下一行地址
????????????????????? ?else if(y==2) Write12864Command(0x98);//寫下一行地址
????????????????????? ?else ;
????????????? ? }
????????????? ? else if((n+x*2)==32)//假設第二行寫完,繼續寫第三行
????????????? ? {
????????????? ???????? ?if(y==0) Write12864Command(0x88);//寫下一行地址
????????????? ????????? else if(y==1) Write12864Command(0x98);//寫下一行地址
???????????????????? ?? else ;
????????????? ? }
????????????? ? else if((n+x*2)==48)//假設第三行寫完,繼續寫第四行
????????????? ? {
????????????? ????????? if(y==0) Write12864Command(0x98);//寫下一行地址
???????????????????? ?? else ;
????????????? ? }
????????????? ? else ;
??? }
}????
?
//圖片模式清屏函數:
void Clear12864Screen()
{
?? unsigned char i,j;
?? Write12864Command(0x34);//功能設定:8位控制方式,使用擴充指令
?? Write12864Command(0x36);//使用擴充指令,畫圖顯示控制
?? for(i=0;i<32;i++)
//ST7920可控制256*32點陣(32行256列),而12864液晶實際的行地址僅僅有0-31行,
//12864液晶的32-63行的行是0-31行地址從第128列劃分一半出來的,所以分為上下兩半屏,
//也就是說第0行和第32行同屬一行,行地址同樣;第1行和第33行同屬一行,以此類推
?? {???????????????????????????
?????? ?? Write12864Command(0x80|i);//寫行地址(垂直地址)
????????? Write12864Command(0x80);//寫列地址(水平地址)
?????? ?? for(j=0;j<32;j++)
????????????? ????? Write12864Data(0x00);//清屏
?? }
}
?
//在任何位置顯示隨意大小的圖片函數:
void LCD12864DisplayPictrue(unsigned char y,unsigned char x,
????????????????????????????? unsigned char px,unsigned char py, unsigned char *pp)
//y-起始行(數值0-63),x-起始列(16位寬,數值0-7),
//px-圖片寬度,py-圖片高度,pp-指針指向圖片數組
//由于上下屏的地址不連續,要在任何位置顯示完整的圖像,處理起來比較繁瑣
{
?? unsigned char i,j,k;
?? Clear12864Screen();//清屏
?? if(y<32)//假設起始行在上半屏
?? {
?????? ?? k=32-y;//算出上半屏的行數
?????? ?? for(i=0;i<k;i++,y++)//上半屏行數
?????? ?? {
????????????? ?????? Write12864Command(0x80|y);//寫行地址(垂直地址)
?????? ????????????? Write12864Command(0x80|x);//寫列地址(水平地址)
???????????????????? for(j=0;j<px/8;j++)
??????????????????????????? ? Write12864Data(pp[i*px/8+j]);//寫圖片數據
?????? ?? }
?????? ?? y=0;//下半屏起始行,接上半屏繼續寫數據
?????? ?? for(;i<py;i++,y++)//下半屏剩下的行數
?????? ?? {
????????????? ?????? Write12864Command(0x80|y);//寫行地址(垂直地址)
?????? ????????????? Write12864Command(0x80|(8+x));//寫列地址(水平地址)
???????????????????? for(j=0;j<px/8;j++)
?????? ???????????????????? ? Write12864Data(pp[i*px/8+j]);//寫圖片數據
?????? ?? }
?? }
?? else //假設起始行在下半屏
?? {
?????? ?? for(i=0;i<py;i++,y++)//行數
?????? ?? {
????????????? ?????? Write12864Command(0x80|(y-32));//寫行地址(垂直地址)
?????? ????????????? Write12864Command(0x80|(8+x));//寫列地址(水平地址)
???????????????????? for(j=0;j<px/8;j++)
??????????????????????????? ?? Write12864Data(pp[i*px/8+j]);//寫圖片數據
?????? ?? }
?? }?
}????
?
//12864初始化函數:
void Initialize12864()
{?
?????? rst=0;//復位12864
? ???? Delayms(30);
?????? rst=1;
?????? Delayms(20);
?????? Write12864Command(0x30);//功能設定:8位控制方式,使用基本指令
?????? Write12864Command(0x08);//顯示關
?????? Write12864Command(0x01);//清屏
?????? Write12864Command(0x06);//地址計數器加一、光標右移
?????? Write12864Command(0x0c);//顯示開
}
?
//主函數:
int main(void)
{
?????? Initialize12864();
?????? LCD12864DisplayString(0,0,"歡迎您來到吳師傅博客學習和交流! wellcom!");
//顯示漢字和字符
?????? LCD12864DisplayPictrue(32,4,48,32,pictrue2);//顯示機器貓
????? ?LCD12864DisplayValue(3,0,255);//顯示255
?????? while(1);
? ???? return 0;???? ??????
}
總結
 
                            
                        - 上一篇: IOS开发之——颜色设置
- 下一篇: Scrapy -- 05
