/*------------------------------------------------------------
ST7920中文字库液晶显示模块LCD12232并行8位显示C30演示程序
C30菜鸟HotPower@126.com 2007.12.9 于雁塔菜地
-------------------------------------------------------------*/
#include "lcd.h"
unsigned char LcdRowWriteEnable[2] = {0, 0};//显示行刷新允许标志
unsigned char LcdBuffer[2][15];//LCD显示缓冲区(2行15个字符)
unsigned char LcdRow = 0, LcdCol = 0;//虚拟光标
void LcdInit(void)//LCD初始化
{
LcdIOInit();//LCD管脚初始化
LcdClearBuffer();//清空LCD显示缓冲区
// LcdWriteCommand(0x20);//发送功能设定控制命令(4位)
LcdWriteCommand(0x30);//发送功能设定控制命令(8位)
LcdWriteCommand(0x02);//发送位址归位命令,设定DDRAM位址计数器为0
LcdWriteCommand(0x04);//发送进入点命令
LcdWriteCommand(0x0c);//发送开显示关光标命令
LcdWriteCommand(0x01);//发送清除显示命令
LcdWriteCommand(0x80);//发送设定DDRAM地址0x00命令,光标定位到(0,0)
/*----------------------------------------------------------------------
LcdWriteCommand(0x30);//发送功能设定控制命令(8位)
LcdWriteCommand(0x30);//发送功能设定控制命令(8位)
LcdWriteCommand(0x30);//发送功能设定控制命令(8位)
LcdWriteCommand(0x01);//发送清除显示命令
LcdWriteCommand(0x06);//发送进入点命令0x06
LcdWriteCommand(0x0a);//发送开关显示关光标命令
LcdWriteCommand(0x0c);//发送开显示关光标命令
LcdWriteCommand(0x02);//发送位址归位命令,设定DDRAM位址计数器为0
LcdWriteCommand(0x17);//游标或显示移位控制
LcdWriteCommand(0x80);//发送设定DDRAM地址0x00命令,光标定位到(0,0)
----------------------------------------------------------------------*/
LCD_BK = 0;//打开背光
}
void LcdIOInit(void)//LCD管脚初始化
{
LCD_BK = 0;//打开背光
LCD_E = 0;//不使能
LCD_RW = 1;//写读数据
TRIS_E = PORTOUTMODE;//定义E为输出IO
TRIS_RW = PORTOUTMODE;//定义RW为输出IO
TRIS_RS = PORTOUTMODE;//定义RS为输出IO
TRIS_BK = PORTOUTMODE;//定义BK为输出IO
TRIS_DATA = 0;//定义RE0~RE7为输出IO
}
void LcdWriteCommand(unsigned char Command)//写LCD命令字
{
LCD_RS = 0;//命令
Nop();
LCD_RW = 0;//写命令
Nop();
LCD_E = 1;//使能
Nop();
LCD_BUS = Command;//发送8位命令
Nop();
LCD_E = 0;//不使能,读出数据 打入命令
Nop();
LCD_RW = 1;//写命令结束
if (Command == 0x01)//清除显示命令,需要等待时间相对较长
{
LcdWaitBusy(1600);
// _delay_loop(1600);//st7920要求等待1.6mS
}
else
{
LcdWaitBusy(72);
// _delay_loop(72);//st7920要求等待72uS
}
}
void LcdWriteData(unsigned char data)//写LCD显示数据
{
LCD_RS = 1;//数据
Nop();
LCD_RW = 0;//写数据
Nop();
LCD_E = 1;//使能
Nop();
LCD_BUS = data;//发送8位数据
Nop();
LCD_E = 0;//不使能,打入数据
Nop();
LCD_RW = 1;//写数据结束
LcdWaitBusy(72);
// _delay_loop(72);//st7920要求等待72uS
}
void LcdWaitBusy(unsigned int count)//LCD忙标志测试(有时死机,故没用参数可以防止死机)
{
TRIS_DATA = 0xff;//定义RE0~RE7为输入IO
LCD_BUS = 0xff;
Nop();
LCD_RS = 0;//命令
Nop();
LCD_RW = 1;//读数据
Nop();
LCD_E = 1;//使能
while (count --)
{
if (!LCD_BF) break;//读取忙碌标志BF(LCD_DATA.7)
ClrWdt();
}
LCD_E = 0;//不使能,读出状态
Nop();
TRIS_DATA = 0;//定义RE0~RE7为输出IO
Nop();
}
void LcdClearBuffer(void)
{
unsigned char i, j;
for (i = 0;i < 2;i ++)//2行字符
{//2行汉字
for (j = 0;j < 15; j ++)//15个字符
{//每行7个半汉字15个字符
LcdBuffer[j] = ' ';//空白字符
}
LcdRowWriteEnable = 1;//允许此行刷新汉字显示
}
LcdRow = 0;//虚拟光标定位在0行
LcdCol = 0;//虚拟光标定位在0列
}
void LcdDisplayPos(unsigned char row, unsigned char col)
{
if ((row < 2) && (col < 15))//容错处理,光标越界
{
LcdRow = row;//刷新虚拟光标
LcdCol = col;//刷新虚拟光标
LcdRowWriteEnable[row] = 1;//允许此行刷新汉字显示
}
}
void LcdDisplay(const char * string)//不真的LCD显示
{
while(*string)//0字符结束
{
LcdBuffer[LcdRow][LcdCol ++] = *string ++;//写入显示缓冲区
}
}
unsigned char LcdDisplayBuffer(void)//显示刷新LCD缓冲区内的数据(一般0.25S~0.5S刷新一次)
{
unsigned char i, j;
unsigned char num = 0;//刷新字符个数
for (i = 0; i < 2; i ++)
{//2行汉字
if (LcdRowWriteEnable)
{//允许此行刷新汉字显示
LcdWriteCommand(0x80 + (i << 4));//移动真的LCD光标
for (j = 0; j < 15; j ++)
{//每行7个半汉字15个字符
LcdWriteData(LcdBuffer[j]);//刷新显示字符
num ++;//刷新字符个数计数
}
LcdRowWriteEnable = 0;//过后不允许此行刷新汉字显示
}
}
return num;//返回实际刷新字符个数(这个"黑奔时有用~~~")
}
文章评论(0条评论)
登录后参与讨论