12864液晶驱动程序库V2.0

//-----------------------------------------------------
//12864液晶驱动程序库V2.0(校赛过后修改)
//-----------------------------------------------------

#include
#include"LCD12864.h"
#include"ReadKey.h"

uchar busy = 0;
uchar LCD_Flash = 0;
uchar mSecond = 0; // 系统计时变量
uchar Second = 0;
uchar Minute = 0;
uchar Hour = 0;
uchar nCount = 0;
uchar NowTime[6];
uchar OldTime[6] = {1,1,1,1,1,1};


//---------------------------------------------------------------
// 函数名称: DelayMs( )
// 功能描述: 毫秒级延时函数
//---------------------------------------------------------------

void DelayMs( uint nDelay ) //延时
{
uint i ;
for( ; nDelay > 0 ; nDelay-- )
{
for( i = 125 ; i > 0 ; i-- ) ;
}
}



uchar const sign[][1] =
{
//摄氏度符号
0xa1,0xe6,
};
uchar const table[][16] =
{
//福建师范大学
{0xb8,0xa3,0xbd,0xa8,0xca,0xa6,0xb7,0xb6,0xb4,0xf3,0xd1,0xa7},
//C题 智能充电器
{0xa3,0xc3,0xcc,0xe2,0x20,0x20,0xd6,0xc7,0xc4,0xdc,0xb3,0xe4,0xb5,0xe7,0xc6,0xf7}

};
uchar const status[][4] =
{
//温度
0xce,0xc2,0xb6,0xc8,0xa3,0xba,
};

//---------------------------------------------------------------
// 函数名称: Check_Busy( )
// 功能描述: 液晶查忙程序,如果液晶忙,则一直在函数中循环
//---------------------------------------------------------------
void Check_Busy(void)
{
busy = 1; //先置位繁忙标志位
TRISD = 0XFF; //更改通信为输入
LCD12864_RS = 0; //设置该字节数据为命令代码
LCD12864_RW = 1; //设置此次操作为读
while(busy)
{
asm("nop");
asm("nop");
asm("nop");
LCD12864_EN = 1; //使能
asm("nop");
asm("nop");
asm("nop");
if(!RD7) busy = 0; //检测LCD是否工作繁忙
asm("nop");
asm("nop");
asm("nop");
LCD12864_EN=0; //禁止
}
LCD12864_EN=0; //禁止
TRISD=0X00; //恢复通信为输出
}

//---------------------------------------------------------------
// 函数名称: LCD12864SendCmd( )
// 功能描述: 液晶发送命令函数
//---------------------------------------------------------------
void LCD12864SendCmd( uchar byCmd ) //发送命令
{
Check_Busy( );
LCD12864_RS = 0 ;
LCD12864_RW = 0 ;
LCD12864_EN = 0 ;
LCD12864_DATAPORT = byCmd ;
asm("nop");
asm("nop");
LCD12864_EN = 1 ;
asm("nop");
asm("nop");
LCD12864_EN = 0 ;
LCD12864_RW = 1 ;
LCD12864_RS = 0 ;
}

//---------------------------------------------------------------
// 函数名称: LCD12864SendData( )
// 功能描述: 液晶发送数据函数
//---------------------------------------------------------------


void LCD12864SendData( uchar byData ) //发送数据
{
Check_Busy( );
LCD12864_RS = 1 ;
LCD12864_RW = 0 ;
LCD12864_EN = 0 ;
LCD12864_DATAPORT = byData ;
asm("nop");
asm("nop");
LCD12864_EN = 1 ;
asm("nop");
asm("nop");
LCD12864_EN = 0 ;
LCD12864_RW = 1 ;
LCD12864_RS = 0 ;
}

//---------------------------------------------------------------
// 函数名称: LCD12864ReadByte( )
// 功能描述: 从液晶读字节,画点函数使用
//---------------------------------------------------------------

uchar LCD12864ReadByte( void )
{
uchar byReturnValue ;
Check_Busy( ); ;
LCD12864_DATAPORT = 0xff ;
LCD12864_RS = 1 ;
LCD12864_RW = 1 ;
LCD12864_EN = 0 ;
LCD12864_EN = 1 ;
byReturnValue = LCD12864_DATAPORT ;
LCD12864_EN = 0 ;
return byReturnValue ;
}

//---------------------------------------------------------------
// 函数名称: Clean_12864
// 功能描述: 清屏函数
//---------------------------------------------------------------

void Clean_12864(void)
{
LCD12864SendCmd(0x30); //基本指令
LCD12864SendCmd(0x01); //清屏处理
DelayMs(5); //要做至少几百US的延时,不然清屏指令不起作用!
}

//---------------------------------------------------------------
// 函数名称: LCD12864Init
// 功能描述: 液晶初始化函数
//---------------------------------------------------------------
void LCD12864Init( void ) //初始化
{
LCD12864SendCmd( 0x30 ) ; //基本指令集
DelayMs( 50 ) ;
LCD12864SendCmd( 0x01 ) ; //清屏
DelayMs( 50 ) ;
LCD12864SendCmd( 0x06 ) ; //光标右移
DelayMs( 50 ) ;
LCD12864SendCmd( 0x0c ) ; //开显示
DelayMs( 50 ) ;
}

//---------------------------------------------------------------
// 函数名称: LCD12864SetAddress
// 功能描述: 选择写入的地址,地址为一个字
// 参数设置:x为0~3,y为0~7,4行8列。
//---------------------------------------------------------------
void LCD12864SetAddress( uchar x, uchar y ) //地址转换
{
uchar byAddress ;
switch( y )
{
case 0 : byAddress = 0x80 + x ;
break;
case 1 : byAddress = 0x90 + x ;
break ;
case 2 : byAddress = 0x88 + x ;
break ;
case 3 : byAddress = 0x98 + x ;
break ;
default :
break ;
}
LCD12864SendCmd( byAddress ) ;
}

//---------------------------------------------------------------
// 函数名称: Display_RAM_Str
// 功能描述: 在指定位置显示数组中指定长度的数据,程序中已经将数值转化为ASCII
//---------------------------------------------------------------

void Display_RAM_Str(uchar x, uchar y,char *p,uchar len)
{
LCD12864SetA

ddress( x, y );
while(len--)
{
LCD12864SendData( *p+0x30 );
p++;
}
}

//---------------------------------------------------------------
// 函数名称: Display_ROM_Str
// 功能描述: 在指定位置显示指定长度的汉字,nCount为汉字数乘2。
//---------------------------------------------------------------
void Display_ROM_Str( uchar x, uchar y, char const *pData, uchar nCount )
{
uchar i = 0;
LCD12864SetAddress( x, y ) ;

for (i = 0; i < nCount; i++)
{ // 发送指定个字节数据
LCD12864SendData( *pData++ ) ;
}

}

void PrintStr(uchar x, uchar y,char const *str)
{
LCD12864SetAddress( x, y ) ;
while (1)
{
if (*str == 0) //判断ROM区数组自加的0
{
break; // 遇到结束符,退出
}
LCD12864SendData( *str++ ) ;
}
}

//---------------------------------------------------------------
// 函数名称: DisplayChar
// 功能描述: 在指定位置显示一个字符
//---------------------------------------------------------------

void DisplayChar( uchar x, uchar y, uchar dat )
{

LCD12864SetAddress( x, y ) ;
LCD12864SendData( dat ) ;


}

//---------------------------------------------------------------
// 函数名称: LCD12864DrawPicture
// 功能描述: 液晶画图程序,图片数据保存在*pPicture指向的位置
//---------------------------------------------------------------

void LCD12864DrawPicture( uchar const *pPicture )
{
uchar i, j, k ;
LCD12864SendCmd( 0x36 ) ; //扩展指令,绘图开
for( i = 0 ; i < 2 ; i++ ) //分上下两屏写
{
for( j = 0 ; j < 32 ; j++ ) //一个半屏有32列
{
LCD12864SendCmd( 0x80 + j ) ; //先写入垂直位置
if( i == 0 )
{
LCD12864SendCmd( 0x80 ) ; //再写入水平位置
}
else
{
LCD12864SendCmd( 0x88 ) ;
}
for( k = 0 ; k < 16 ; k++ ) //一行有16个字符,1代表亮,0灭
{
LCD12864SendData( *pPicture++ ) ;
}
}
}
LCD12864SendCmd( 0x30 ) ; //设置基本指令集
}

//---------------------------------------------------------
//函数功能:写入16X32图形,适用于st7920型液晶
//形式参数:uchar x,uchar y,uchar *bmp
//行参说明:横坐标X,纵坐标Y,要显示的图形BMP
//使用说明:在1~3行内任意一行开始,写入16*32图形
//---------------------------------------------------------

void write1632GDRAM(uchar x,uchar y,uchar const *bmp)
{
uchar i,j,basex,basey;
switch(y) //由y纵坐标定是上半屏还是下半屏
{
case 1: basex=0x80; break; //上半屏
case 2: basex=0x80; break; //先上半屏,下面再下半屏。
case 3: basex=0x88; break; //下半屏
default: return; //别的则返回
}
basey=basex+x-1;

LCD12864SendCmd(0x36); //绘图模式

命令
if(y==1||y==3) //如为第一第三行,则直接是在同一半屏,直接绘完32行数据。
{
for(i=0;i<32;i++) //写入32行点阵
{
LCD12864SendCmd(0x80+i); //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80
LCD12864SendCmd(basey); //再写入水平位址(选上下半屏)
for(j=0;j<2;j++) //2个8位元的数据,即16BIT宽度
LCD12864SendData(*bmp++);
}
}
if(y==2) //从第二行开始则画图将上下半屏都有,所以先画完上半屏16行,再画下半屏16行。
{
for(i=0;i<16;i++) //写入上半屏16行点阵
{
LCD12864SendCmd(0x90+i); //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80,第二行为0X90。
LCD12864SendCmd(basey); //(选上半屏)再写入水平位址
for(j=0;j<2;j++) //2个8位元的数据,即16BIT宽度
LCD12864SendData(*bmp++);
}
for(i=0;i<16;i++) //写入下半屏16行点阵
{
LCD12864SendCmd(0x80+i); //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80
LCD12864SendCmd(basey+8); //(选下半屏)入水平位址
for(j=0;j<2;j++) //2个8位元的数据,即16BIT宽度
LCD12864SendData(*bmp++);
}
}

LCD12864SendCmd(0x30);
}

//---------------------------------------------------------
//函数名称:Clean_12864_GDRAM(void)
//函数功能:清屏函数
//使用说明:GDRAM填满0,想写入新的自定义内容需要先调用本函数清屏
//---------------------------------------------------------

void Clean_12864_GDRAM(void)
{
uchar x,y;
LCD12864SendCmd(0x34);
Clean_12864( );
LCD12864SendCmd(0x36); //需要两次,本次设置扩展指令集。

for (y=0;y<32;y++)
{
LCD12864SendCmd(0x80+y); //设置y=1000+00xx,y+1则往下一行
LCD12864SendCmd(0x80); //设置x=1000 0000
for (x=0;x<16;x++)
{
LCD12864SendData(0x00); //高字节数据
LCD12864SendData(0x00); //低字节数据
}
}
LCD12864SendCmd(0x30);
}

//-----------------------------------------------------------------------
//函数功能:使用绘图的方法让一个16*16的汉字符反白
//形式参数:uchar x,uchar y,uchar wide,uchar bkcor
//行参说明:坐标水平位置,坐标垂直位置,反白行数,要反白还是清除(1:反白,0:清除)
//功能说明:反白的是自定义的字符
//-----------------------------------------------------------------------

void write1616GDRAM(uchar x,uint y,uchar sign,uchar *bmp)
{
uchar i,j,basex;
LCD12864SendCmd(0x36);
if(y==1||y==2) //第一第二行
{
basex=0x80; //上半屏
y=(y-1)*16; //垂直位址从0X80开始.
}
if(

y==3||y==4) //第三第四行
{
basex=0x88; //下半屏
y=(y-3)*16; //垂直位址都是从0X80开始的,不管上下半屏。
}
for(i=0;i<16;i++)
{
LCD12864SendCmd(0x80+y+i); //写入垂直位址。
LCD12864SendCmd(basex+x-1); //再写入水平位址(上半屏第一字为0X80,……第七字为0X87)
//下半屏第一字为0X88,……第七字为0X8F;
for(j=0;j<2;j++) //再写入两个8位元的数据,AC会自动增一,接着写数据
{
if(sign==1)
LCD12864SendData(~(*bmp++));
else
LCD12864SendData(*bmp++);
}
}
LCD12864SendCmd(0x30);
}

//-----------------------------------------------------------------------
//函数功能:使用绘图的方法让一行反白
//形式参数:uchar row,uchar bkcor
//行参说明:坐标水平位置,坐标垂直位置,反白行数,要反白还是清除(1:反白,0:清除)
//使用说明:无
//------------------------------------------------------------------------

void SetRowBackColor(uchar row,uchar bkcor)
{
uchar i,j,basex,basey,color;
LCD12864SendCmd(0x36); //扩展指令
if(bkcor==1) color=0xff; //全写入0XFF,反白。
if(bkcor==0) color=0x00; //全写入0X00,消白。

if(row==1||row==2) //第一第二行
{
basex=0x80; //上半屏
}
if(row==3||row==4) //第三第四行
{
basex=0x88; //下半屏
row=row-2; //垂直位址都是从0X80开始的,不管上下半屏。
}
basey=0x80+(row-1)*16; //从哪一行的首行点阵开始
for(i=0;i<16;i++) //一行有16行点阵
{
LCD12864SendCmd(basey+i); //写入垂直位址。
LCD12864SendCmd(basex); //水平位址(上半屏第一字为0X80)//下半屏第一字为0X88;

for(j=0;j<16;j++) //再写入两个8位元的数据,AC会自动增一,接着写数据
LCD12864SendData(color);
}

LCD12864SendCmd(0x30);
}


//-----------------------------------------------------------------------
//函数功能:使用绘图的方法让任意个汉字进行反白
//形式参数:uchar x,uchar y,uchar end_x,uchar clear
//行参说明:水平起始位置,垂直位置,水平结束位置,要反白还是清除(1:反白,0:清除)
//使用说明:无
//------------------------------------------------------------------------
void Set_White(uchar x,uchar y,uchar end_x,uchar clear)
{
uchar i, j, white_x, white_y,white_end_x,clr_x,clr_y;
LCD12864SendCmd(0x36); //扩展指令,写图片时,关图片显示
white_end_x = (end_x-x+1);
white_end_x <<= 1;
if(y==1)
{
white_x = (0x80+x-1);
white_y = 0x80;
clr_x = 0x80;
clr_y = 0x80;
}
else if(y==2)
{
white_x = (0x80+x-1);
white_y = 0x90;
clr_x = 0x80;
clr_y = 0x90;
}
else if(y==3)
{
white_x = (0x88+x-1);
white_y = 0x80;
clr_x = 0x88;
clr_y = 0x80;
}
else if(y==4)
{
white_x = (0x88

+x-1);
white_y = 0x90;
clr_x = 0x88;
clr_y = 0x90;
}

for(i=0;i<16;i++ ) //16行,因为是16*16汉字
{
LCD12864SendCmd(white_y++); //设置绘图区的Y地址坐标0
LCD12864SendCmd(white_x); //设置绘图区的X地址坐标0
for(j=0;j{
if(clear==1)
{
LCD12864SendData(0x00); //取消这一行的8个点的反白,液晶地址自动加1
//(此处行指一个一个液晶点所组成的行)
}
else
{
LCD12864SendData(0xff); //反白这一行的8个点,液晶地址自动加1
//(此处行指一个一个液晶点所组成的行)
}
}
}
LCD12864SendCmd(0x30);

}

相关文档
最新文档