/********************************************
*山东建筑大学 锐思实验室 *
*函数名称:LCD12864程序 *
*CPU型号:STC89C52 *
*晶振参数:12MHZ *
*程序作者:2009级机械2班 许方超 *
*联系方式:QQ:610949704 *
* *
********************************************/
#include "LCD12864.h"
void Delay_40US(void)
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=17;a>0;a--);
}
/**************************************
为加速逻辑运算而设置的掩码表,
这是以牺牲空间而换取时间的办法
***************************************/
code unsigned int LcdMaskTab[]=
{0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080,
0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
/*************
测试LCD是否处于忙状态
如果忙则返回0x80,
否则返回0
**************/
void LCD12864_checkbusy(void)
{
unsigned char Busy,num;
LcdData=0xff;
num=100;
LCD12864_RS=0;
LCD12864_RW=1;
LCD12864_EN=1;
Delay_40US();
Busy=LcdData&0x80;
LCD12864_EN=0;
while(Busy&num--);
}
/*********************************
向LCD写入字节数据
**********************************/
void LCD12864_writedata(unsigned char Data)
{
LCD12864_checkbusy();
LCD12864_RS=1;
LCD12864_RW=0;
LCD12864_EN=0;
LcdData=Data;
Delay_40US();
LCD12864_EN=1;
Delay_40US();
LCD12864_EN=0;
}
/***********************************
从LCD中读出数据
************************************/
unsigned char LCD12864_readdata(void)
{
unsigned char Temp;
LCD12864_checkbusy();
LcdData=0xff;
LCD12864_RS=1;
LCD12864_RW=1;
LCD12864_EN=1;
Delay_40US();
Temp=LcdData;
LCD12864_EN=0;
return Temp;
}
/*************************************
向LCD中写入指令代码
**************************************/
void LCD12864_writecommand(unsigned char CmdCode)
{
LCD12864_checkbusy();
LCD12864_RS=0;
LCD12864_RW=0;
LCD12864_EN=0;
Delay_40US();
LcdData=CmdCode;
Delay_40US();
LCD12864_EN=1;
Delay_40US();
LCD12864_EN=0;
}
/***********************
12864设定初始显示位置
X为行的数目
Y为列的数目
***********************/
void LCD12864_setplace(uchar X,uchar Y)
{
uchar pos;
LCD12864_writecommand(0x30);
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;
LCD12864_writecommand(pos);
}
/*****************************************
设置图像显示模式
select=0时,关闭图形显示模式
Select=1时,开启图形显示模式
LCD_EXTEND_FUNCTION为 扩展指令集
LCD_GRAPH_ON 打开绘图模式命令
LCD_GRAPH_OFF 关闭绘图模式命令
******************************************/
void LCD12864_graphsetmode(unsigned char Select)
{
LCD12864_writecommand(LCD_EXTEND_FUNCTION);
if(Select){LCD12864_writecommand(LCD_GRAPH_ON);}
else {LCD12864_writecommand(LCD_GRAPH_OFF);}
}
/*************************************
向LCD指定起始位置写入一个字符串
*************************************/
void LCD12864_displaystring(unsigned char x,unsigned char y,unsigned char *Str)
{
if((y>4)||(x>8)) return;
LCD12864_setplace(x,y);
while(*Str>0)
{ LCD12864_writedata(*Str); Str++;}
}
/*******************************************
按页显示,同时显示四行
*******************************************/
void LCD12864_displaypage( uchar code *adder1)
{
unsigned char i;
LCD12864_writecommand(0x80);
for(i=0;i<32;i++)
{LCD12864_writedata(*adder1);adder1++;}
LCD12864_writecommand(0x90);
for(i=32;i<64;i++)
{LCD12864_writedata(*adder1);adder1++;}
}
/*********************************************
向LCD写入一个8位的ASCII码
以显示相应的字符
**********************************************/
void LCD12864_sendascii(uchar hang,uchar lie,char sign)
{
LCD12864_setplace(hang,lie);
LCD12864_writedata(sign);
}
/*********************************************
向LCD写入一个16位的GB2312码
以显示相应的字符
**********************************************/
void LCD12864_sendgb2312(uchar hang,uchar lie,unsigned int sign)
{
unsigned char templ, temph;
templ=sign&0x00ff;
temph=sign>>8 ;
LCD12864_writecommand(0x30);
LCD12864_setplace(hang,lie);
LCD12864_writedata(temph);
Delay_40US();
LCD12864_writedata(templ);
}
/***************************************
向LCD指定坐标写入一个象素,象素颜色有两种,
0代表白(无显示),1代表黑(有显示)
****************************************/
void LCD12864_writepixel(unsigned char x,unsigned char y,unsigned char color)
{
unsigned char x_Dyte,y_Dyte,x_bite; //定义列地址的字节位,及在字节中的哪1位
unsigned char GDRAM_hbit,GDRAM_lbit; //定义为上下两个屏(取值为0,1),行地址(取值为0~31)
x_Dyte=x/16;
x_bite=x&0x0f;
if(y<32)
{
y_Dyte=y;
}
else
{
y_Dyte=y-32;
x_Dyte=x_Dyte+8;
}
LCD12864_writecommand(LCD_EXTEND_FUNCTION);
LCD12864_writecommand(LCD_GRAPH_ON);
LCD12864_writecommand(0x80+y_Dyte);
LCD12864_writecommand(0x80+x_Dyte);
LCD12864_readdata();
GDRAM_hbit=LCD12864_readdata();
GDRAM_lbit=LCD12864_readdata();
if(x_bite<8)
{
switch(color)
{
case 0 :GDRAM_hbit&=(~(1<<(7-x_bite)));break;
case 1 :GDRAM_hbit|=(1<<(7-x_bite)); break;
case 2 :GDRAM_hbit^=(1<<(7-x_bite)); break;
default :break;
}
}
else
{
switch(color)
{
case 0 :GDRAM_lbit&=(~(1<<(15-x_bite)));break;
case 1 :GDRAM_lbit|=(1<<(15-x_bite)); break;
case 2 :GDRAM_lbit^=(1<<(15-x_bite)); break;
default :break;
}
}
LCD12864_writecommand(0x80+y_Dyte);
LCD12864_writecommand(0x80+x_Dyte);
LCD12864_writedata(GDRAM_hbit);
LCD12864_writedata(GDRAM_lbit);
LCD12864_writecommand(LCD_EXTEND_FUNCTION);
LCD12864_writecommand(LCD_GRAPH_OFF);
}
/*********************************
清空LCD的DRAM
*********************************/
void LCD12864_cleardram(void)
{ unsigned char i,j;
LCD12864_writecommand(0x34);
LCD12864_writecommand(0x34);
LCD12864_writecommand(0x30);
for(i=1;i<5;i++)
for(j=1;j<9;j++)
LCD12864_sendgb2312(i,j,0xB0A0);
}
/*****************************************
清除Lcd全屏,如果清除模式Mode为0,则为全屏清除为颜色0(无任何显示)
否则为全屏清除为颜色1(全屏填充显示)
******************************************/
void LCD12864_cleargram(unsigned char Mode)
{
unsigned char x,y,ii;
unsigned char Temp;
if(Mode%2==0)Temp=0x00;
else Temp=0xff;
LCD12864_writecommand(0x34);
LCD12864_writecommand(0x36);//扩充指令 绘图显示
for(ii=0;ii<9;ii+=8)
for(y=0;y<0x20;y++)
for(x=0;x<8;x++)
{
LCD12864_writecommand(y+0x80); //行地址
LCD12864_writecommand(x+0x80+ii); //列地址
LCD12864_writedata(Temp); //写数据 D15-D8
LCD12864_writedata(Temp); //写数据 D7-D0
}
}
/**********************************************
清空LCD中的GRAM 和 DRAM
**********************************************/
void LCD12864_cleargdram(void)
{
LCD12864_cleardram();
LCD12864_cleargram(0);
}
/***********************************************************
函数名: dispU_picture
函数说明: 上半屏显示一幅128*32的图画
传入参数:图形指针*img
传出参数:无
返回值: 无
**********************************************************/
void LCD12864_displaypicture_up(unsigned char *img)
{
unsigned char i,j;
LCD12864_graphsetmode(0);
for(j=0;j<32;j++)
{
for(i=0;i<8;i++)
{
LCD12864_writecommand(0x34);
LCD12864_writecommand(0x80+j);
LCD12864_writecommand(0x80+i);
LCD12864_writecommand(0x30);
LCD12864_writedata(img[j*16+i*2]);
LCD12864_writedata(img[j*16+i*2+1]);
}
}
LCD12864_graphsetmode(1);
}
/***********************************************************
函数名: dispD_picture
函数说明: 下半屏显示一幅128*32的图画
传入参数:图形指针*img
传出参数:无
返回值: 无
***********************************