/***測試OK,我的是12864-15型引腳。并口驅動****/-
#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;//單片機讀數據之前必須先置高位-
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;-
}-
/*******************************************************************/-
// 寫入一字節數據-
/*******************************************************************/-
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;-
}-
-//讀數據函數
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個,表示的是行數 ,分兩個半屏,每個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.讀要顯示的數據 DAT
5.區分上下半屏(X%16<=7&&X%16>=0是上半屏)寫入數據每一位 DAT|0x80 ;DAT<<1
注意:這個函數顯示某一點時,可能會把上次顯示的處于同一地址的其他位的點擦掉,所以先保存所有數據,最后顯示,就連貫起來了
*******************************/
/*******************************************************************/
/**************************************************************/
//------------------清整個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個,表示的是行數 ,分兩個半屏,每個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位,擴充指令,繪圖關
LCD12864_command(0x36); //8位,擴充指令,繪圖開
i = X/16; //計算出X字節地址(0X80-0X8F)
j = X%16; //計算出該字節的具體位(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)
{
//讀數據操作
LCD12864_command(0x80+Y); //第一步:設置Y坐標,讀數據先寫地址,寫GDRAM時先寫垂直地址(0X80-0X9F)
LCD12864_command(0x80+i); //第二步:設置X坐標
LCD12864_ReadData(); //第三步:空讀取一次
temp1 =LCD12864_ReadData(); //第四步:讀取高字節,先讀高字節
temp2 =LCD12864_ReadData(); //第五步:讀取低字節
//圖形模式下的寫數據操作
LCD12864_command(0x80+Y); //第一步:設置Y坐標
LCD12864_command(0x80+i); //第二步:設置X坐標
if(j>=0 && j<=7) //判斷是高字節
{
LCD12864_data(temp1|(0x80>>j)); //第三步:寫高字節數據
LCD12864_data(temp2); //第四步:寫低字節數據
}
else if(j>7 && j<=15) //判斷是低字節
{
j = j - 8;
LCD12864_data(temp1);
LCD12864_data(temp2|(0x80>>j)); //改變字節里的位
}
}
}
/******************************************/
//畫線
/********************************************/
//畫水平線
void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y)
{
unsigned char Temp ;
if( X0 > X1 )
{
Temp = X1 ; //交換X0 X1值
X1 = X0 ; //大數存入X1
X0 = Temp; //小數存入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++ ) //寫一整行數據
{
LCD12864_data( *pic++ );//前面只寫入首地址,后面依次寫入數據,地址會自動遞增
}
}
}
LCD12864_command( 0x30);//恢復到一般模式
}
//