/***測試OK,我的是12864-15型引腳。并口驅(qū)動****/- #include "reg52.h"- #include <intrins.h>- #define LCD12864_IOP0- #define LINE10- #define LINE21- #define HIGH1- #define LOW 0- #defineCLERADISPLAYLCD12864_command(0x01);- code unsigned char gImage_test[1024] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04} ; sbit LCD12864_EN=P2^7; sbit LCD12864_DIN=P2^6; sbit LCD12864_CLK=P2^5; void LCD12864_busy(void);- void LCD12864_command(unsigned char command);- void LCD12864_data(unsigned char dat);- void LCD12864_address(unsigned char row,unsigned char line);- void LCD12864_char(unsigned char dat);- void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s);- void LCD12864_picture(unsigned char *gImage);- void LCD12864_init(void);- /********************************************************************/- - - void Mcu_init(void)- {- - LCD12864_init();- - - CLERADISPLAY - CLERADISPLAY - LCD12864_init();- }- - - - void Delay(void)- {- unsigned char i;- unsigned int j;- for(i=0;i<200;i++)- for(j=1000;j>0;j--);- }- void main(void)- {- Mcu_init();- LCD12864_picture((unsigned char*)gImage_test); - Delay();Delay();- CLERADISPLAY - while(1)- {- LCD12864_string(1,1," LCD12864-15 "); - LCD12864_string(1,2,"中文顯示測試實驗"); - LCD12864_string(1,3," 少占魚 ");- LCD12864_string(1,4," 2010-1-26 ");- - - }- }- - - void LCD12864_DELAY(unsigned int a)- {- for(;a>0;a--) - _nop_();- }- /*******************************************************************/- void LCD12864_busy(void)- {- bit BF = 0;- LCD12864_EN=0; - LCD12864_DIN=0;- LCD12864_CLK=1;- LCD12864_IO=0xff;//單片機讀數(shù)據(jù)之前必須先置高位- do- {- LCD12864_EN=1;- BF=LCD12864_IO&0x80;- LCD12864_EN=0;- } while(BF);- - }- /*******************************************************************/- // 寫入命令- /*******************************************************************/- void LCD12864_command(unsigned char command)- {- LCD12864_busy();- LCD12864_EN=0;- LCD12864_DIN=0;- LCD12864_CLK=0; - - LCD12864_EN=1;- LCD12864_IO=command;- LCD12864_EN=0;- }- /*******************************************************************/- // 寫入一字節(jié)數(shù)據(jù)- /*******************************************************************/- void LCD12864_data(unsigned char dat)- {- - LCD12864_busy();- LCD12864_EN=0;- LCD12864_DIN=1;- LCD12864_CLK=0;- - LCD12864_EN=1;- LCD12864_IO=dat;- LCD12864_EN=0;- }- -//讀數(shù)據(jù)函數(shù) unsigned char LCD12864_ReadData() { unsigned char read_data; LCD12864_busy(); LCD12864_IO=0xff; LCD12864_RS=1; LCD12864_RW=1; LCD12864_EN=0; LCD12864_EN=1; read_data=LCD12864_IO; LCD12864_EN=0; return(read_data); } void LCD12864_char(unsigned char dat)- {- if((dat>=0)&&(dat<=9))- dat|=0x30;- LCD12864_data(dat);- } - - /*******************************************************************/- // 設置顯示位置 X(1~8),Y(1~4)- /*******************************************************************/- void LCD12864_address(unsigned char line,unsigned char row)- {- switch(row) - {- case 1:LCD12864_command(0x7f + line);- break;- case 2:LCD12864_command(0x8f + line);- break;- case 3:LCD12864_command(0x87 + line);- break;- case 4:LCD12864_command(0x97 + line);- default:- break;- }- }- // 在指定位置顯示字符串- /*******************************************************************/- void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s)- { - unsigned char LCD12864_temp; - LCD12864_address(row,line); - LCD12864_temp=*s;- while(LCD12864_temp != 0x00) - { - LCD12864_data(LCD12864_temp);- LCD12864_temp=*(++s);- } - }- // 繪制一幅圖片- /*******************************************************************/- void LCD12864_picture(unsigned char *gImage) - {- unsigned char X = 0x80,Y = 0x80;- unsigned char i,j;- for(i=0;i<64;i++) - { - for(j=0;j<16;j++) - { - LCD12864_command(0x34);- LCD12864_command(Y);- LCD12864_command(X);- LCD12864_data(*(gImage+i*16+j)); // low 8 bits- LCD12864_data(*(gImage+i*16+j+1)); // high 8 bits- LCD12864_command(0x36);- X++;- j++;- } - Y++; - if(Y>0x9f) - Y=0x80; - X=0x80+((i+1)/32)*8; - } - LCD12864_command(0x30);- - }- // 初始化設置- /*******************************************************************/- void LCD12864_init(void)- {- CLERADISPLAY // clear DDRAM- LCD12864_command(0x30); // 8 bits unsigned interface,basic instrument- LCD12864_command(0x02); // cursor return- LCD12864_command(0x0c); // display,cursor on- LCD12864_command(0x03); - LCD12864_command(0x06);- CLERADISPLAY // clear DDRAM- }- /**************************** 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐標,表示的是多少列 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐標,每組8列,每列16位,共128位, 0x80 0x81 0x82 0x83 ........ 0x9f //列坐標,共32個,表示的是行數(shù) ,分兩個半屏,每個32行,共64行 //Y坐標 只是用來確定具體坐標,在哪一行 功能:圖形模式下,顯示(X,Y)點 輸入:X(0~127) Y(0~63) 相對屏幕坐標 輸出:無 點亮某一點的操作步驟: 1.求出水平坐標X對應的地址和是哪一位 0x80-----0x8f (范圍0-15) X/16求地址 X%16求該地址哪一位 2.求垂直坐標Y對應的地址和上下半屏 0x80------0x9f(范圍0-63) Y本身就是8位地址,Y=63-Y ,Y--(0-31) 3.寫入行列地址(Y是行X是列),0x80+Y ,0X80+X/16 4.讀要顯示的數(shù)據(jù) DAT 5.區(qū)分上下半屏(X%16<=7&&X%16>=0是上半屏)寫入數(shù)據(jù)每一位 DAT|0x80 ;DAT<<1 注意:這個函數(shù)顯示某一點時,可能會把上次顯示的處于同一地址的其他位的點擦掉,所以先保存所有數(shù)據(jù),最后顯示,就連貫起來了 *******************************/ /*******************************************************************/ /**************************************************************/ //------------------清整個GDRAM空間---------------------------- /**************************************************************/ void clrgdram() { unsigned char x,y ; for(y=0;y<64;y++) for(x=0;x<16;x++) { LCD12864_command(0x34); LCD12864_command(y+0x80); LCD12864_command(x+0x80); LCD12864_command(0x30); LCD12864_data(0x00); LCD12864_data(0x00); } } /******************************************/ /*******8========================================================================== 功能:圖形模式下,顯示(X,Y)點 輸入:X(0~127) Y(0~63) 輸出:無 0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐標,表示的是多少列,X地址 0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐標,X地址 (水平地址 ) 0x80 (垂直地址) 0x81 0x82 0x83 ........ 0x9f //列坐標,共32個,表示的是行數(shù) ,分兩個半屏,每個32行,共64行 ====================================================================**********/ void LCD12864_Drawpoint(uchar X,uchar Y) { uchar i= 0, j = 0,ok=0; uchar temp1 = 0x00,temp2 = 0x00; LCD12864_command(0x34); //8位,擴充指令,繪圖關(guān) LCD12864_command(0x36); //8位,擴充指令,繪圖開 i = X/16; //計算出X字節(jié)地址(0X80-0X8F) j = X%16; //計算出該字節(jié)的具體位(0-15) //Y = 63 - Y; if(Y>=0 && Y<=31)//判斷上下半屏 { ok=1; } else if(Y>=32 && Y<=63)//下半屏 { Y = Y - 32;//Y只有0-31共32個 地址 i = i + 8;//X地址進入下半屏 (0X88-0X8F) ok=1; } if(ok) { //讀數(shù)據(jù)操作 LCD12864_command(0x80+Y); //第一步:設置Y坐標,讀數(shù)據(jù)先寫地址,寫GDRAM時先寫垂直地址(0X80-0X9F) LCD12864_command(0x80+i); //第二步:設置X坐標 LCD12864_ReadData(); //第三步:空讀取一次 temp1 =LCD12864_ReadData(); //第四步:讀取高字節(jié),先讀高字節(jié) temp2 =LCD12864_ReadData(); //第五步:讀取低字節(jié) //圖形模式下的寫數(shù)據(jù)操作 LCD12864_command(0x80+Y); //第一步:設置Y坐標 LCD12864_command(0x80+i); //第二步:設置X坐標 if(j>=0 && j<=7) //判斷是高字節(jié) { LCD12864_data(temp1|(0x80>>j)); //第三步:寫高字節(jié)數(shù)據(jù) LCD12864_data(temp2); //第四步:寫低字節(jié)數(shù)據(jù) } else if(j>7 && j<=15) //判斷是低字節(jié) { j = j - 8; LCD12864_data(temp1); LCD12864_data(temp2|(0x80>>j)); //改變字節(jié)里的位 } } } /******************************************/ //畫線 /********************************************/ //畫水平線 void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y) { unsigned char Temp ; if( X0 > X1 ) { Temp = X1 ; //交換X0 X1值 X1 = X0 ; //大數(shù)存入X1 X0 = Temp; //小數(shù)存入X0 } for( ; X0 <= X1 ; X0++ ) LCD12864_Drawpoint(X0,Y); } //畫垂直線 void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1) { unsigned char Temp ; if( Y0 > Y1 )//交換大小值 { Temp = Y1 ; Y1 = Y0 ; Y0 = Temp ; } for(; Y0 <= Y1 ; Y0++) LCD12864_Drawpoint( X, Y0) ; } /******************************************/ /**************畫圖************************/ void LCD12864_DrawPicture( unsigned char code *pic) { unsigned char i, j, k ; LCD12864_command(0x34);//開擴充指令 LCD12864_command(0x36);//開繪圖功能 for( i = 0 ; i < 2 ; i++ )//分上下兩屏寫 { for( j = 0 ; j < 32 ; j++)//垂直地址遞加 ,行掃方式 { LCD12864_command( 0x80 + j ) ;//寫Y坐標(Y的范圍: 0X80-0X9F ) if( i == 0 ) //寫X坐標 { LCD12864_command(0x80);//上半屏 } else { LCD12864_command(0x88);//下半屏開始地址 } for( k = 0 ; k < 16 ; k++ ) //寫一整行數(shù)據(jù) { LCD12864_data( *pic++ );//前面只寫入首地址,后面依次寫入數(shù)據(jù),地址會自動遞增 } } } LCD12864_command( 0x30);//恢復到一般模式 } //