//用户版
//描述: LCD12864液晶显示模块,对于芯片KS0108(HD61202)驱动程序.
//编写:微控设计网 DC版主 日期:2007.9.
//编译环境:IAR EW430 V3.42A
//验证平台: www.microcontrol.cn MC430F14+开发板 V1.0
//声明:此程序只供微控用户使用.在未得到DC版主的许可请勿将资料外公开和用于商业用途.
//******************************************************************************
#include "lcd12864.h"
extern unsigned char ASCII86[][6];
//******************************************************************************
//LCD12864函数声明
void Lcd12864delay(); //延时
void CheckState(); //忙状态检查
void WriteByte(unsigned char dat); //写显示数据
void SEdCommandToLCD(unsigned char command); //向LCD发送命令
void SetLine(unsigned char line); //设定行地址(页)--X 0-7
void SetColumn(unsigned char column); //设定列地址--Y 0-63
void SetOnOff(unsigned char onoff); //开关显示
void SetStartLine(unsigned char startline); //设定显示开始行--XX
void ClearScreE(unsigned char screE); //清屏
void SelectScreE(unsigned char screE); //选择屏幕
unsigned char ReadByte(); //读显示数据
//显示8*6字符串
void ShowString86(unsigned char lin,unsigned char column, unsigned char *string);
//反显一个8*6字块
void ReverseShow86(unsigned char lin,unsigned char column);
//反显某行某几个字符
void ReverseLinChar(unsigned char lin,unsigned char startcolumn,unsigned char ShowQuantity);
void InitLCD(void); //初始化LCD
//******************************************************************************
//初级函数列表
//******************************************************************************
//延时
void Lcd12864delay()
{
unsigned int i=500;
while(i--) {;}
}
void LcdDelay()
{
unsigned int i=2;
while(i--) {;}
}
//******************************************************************************
//忙状态检查(已整理)
void CheckState()
{
MCU_BUS_DIR_IN; //设置BUS口为输入
LVC4254_5Vto3V; //LVC4254数据方向为5V往3V
RS0;
RW1;
E1;
while(BUSIN & busy) _NOP(); //等待LCD_DB7为0
E0; //重设E=0
MCU_BUS_DIR_OUT; //设置BUS口为输出
LVC4254_3Vto5V; //LVC4254数据方向为3V往5V
}
//******************************************************************************
//写显示数据(已整理)
//dat:显示数据
void WriteByte(unsigned char dat)
{
CheckState(); //忙状态检查
RS1;
RW0;
BUSOUT = dat; //写向数据口
E1;
LcdDelay();
E0;
}
//******************************************************************************
//向LCD发送命令(已整理)
//command :命令
void SEdCommandToLCD(unsigned char command)
{
CheckState(); //忙状态检查
RS0;
RW0;
BUSOUT = command; //写入
E1;
LcdDelay();
E0;
}
//******************************************************************************
//清屏(已整理)
//screE:1-左屏,2-右
//每个屏的显示RAM共64行,分8页,每页8行(一行对相一个字节)
void ClearScreE(unsigned char screE)
{
unsigned char i,j;
SelectScreE(screE); //选择指定屏
for(i=0;i<8;i++) //共8页(每页8行*64列)
{ SetLine(i); //选择某一页
for(j=0;j<64;j++) //每一页全送0x00为清屏
{
WriteByte(0x00); //一个数据对应8行,8*64=1页,64*8页
}
}
}
//******************************************************************************
//开关显示(已整理)
//onoff=1开,onoff=0为关
//当DB0=1时LCD显示RAM中的内容DB0=0时关闭显示
void SetOnOff(unsigned char onoff)
{
onoff=0x3e | onoff; //0011 111x
SEdCommandToLCD(onoff); //发命令到LCD
}
//******************************************************************************
//选择屏幕(已整理)
//screE: 0-全屏,1-左屏,2-右屏
void SelectScreE(unsigned char screE)
{ //MSC-G12864DYSY-2N:选中高电平
switch(screE)
{ case 0: //开全屏
CS1_1;
_NOP();
CS2_1;
_NOP();
break;
case 1: //开左屏
CS1_0;
_NOP();
CS2_1; //关右屏
_NOP();
break;
case 2:
CS1_1;//关左屏
_NOP();
CS2_0;//开右屏
_NOP();
break;
}
}
//******************************************************************************
//设定行地址(页,也就是字行)--X 0-7(已整理)
void SetLine(unsigned char line)
{
line=line & 0x07; //保证在 0<=line<=7
line=line|0xb8; //1011 1xxx,
SEdCommandToLCD(line); //设定指定页
}
//******************************************************************************
//设定列地址--Y 0-63(已整理)
void SetColumn(unsigned char column)
{
column=column &0x3f; //0=<column<=63
column=column | 0x40; //01xx xxxx
SEdCommandToLCD(column); //指定列
}
//******************************************************************************
//设定显示开始行--XX(已整理)
//0--63
void SetStartLine(unsigned char startline)
{
startline=startline & 0x07; //保证 0<=startline<8
startline=startline|0xc0; //1100 0000(显示起始行ROW设置指令)
SEdCommandToLCD(startline); //指定行
}
//******************************************************************************
//初始化LCD (已整理)
void InitLCD(void)
{
LVC4254_DIR0; //MCU对LVC4254 DIR控制端IO方向设为0
LVC4254_3Vto5V; //LVC4254方向为3V转5V,DIR=0
MCU_BUS_DIR_OUT; //MCU总线方向为输出
LCDCTL_RSRWE_DIR; //MCU对LCD 控制组端IO方向设为
LCDCTL_CS1CS2_DIR; //
Lcd12864delay();
SelectScreE(0); //选择屏
SetOnOff(0); //关显示
ClearScreE(1); //清屏1
ClearScreE(2); //清屏2
SelectScreE(0);
SetOnOff(1); //开显示
SelectScreE(0);
SetColumn(0); //开始列:0
SetStartLine(0); //开始行:0
ClearScreE(0);
}
//******************************************************************************
//读显示数据(已整理)
unsigned char ReadByte(void)
{unsigned int i;
unsigned char dat;
CheckState();
RS1;
RW1;
MCU_BUS_DIR_IN; //设置BUS口为输入
LVC4254_5Vto3V;
E1;
for(i=0;i<10;i++); //这个延时是不同MCU速度而不同
dat=BUSIN; //读入,(原文件是没有此句的)
E0;
MCU_BUS_DIR_OUT; //设置BUS口为输出
LVC4254_3Vto5V;
return(dat);
}
//******************************************************************************
//显示8*6点阵,如显ASCII86[][6],字符(已整理)
//旋转90度:字模被竖着切分
//lin:字行(0-7), column: 字列(0-31)
//address : 字模区首地址 由Microcontrol dc 编写
void Show86(unsigned char lin,unsigned char column, unsigned char *address)
{
unsigned char i,j=0;
if(column>31) //列地址大于31返回
{return;}
//第0-9个字列
else if(column<=9)
{SelectScreE(1);
SetLine(lin);
SetColumn((column<<3)-(column<<1)); //计算列地址,以6为倍数.每6列显示一个字符.
for(i=0;i<6;i++)
WriteByte(address[i]);
}
//第10个字列
else if(column==10)
{ j=(column<<3)-(column<<1);
if(j<=63) //第10个字列的前4列
{ SelectScreE(1);
SetLine(lin);
SetColumn(j);
for(i=0;i<4;i++)
{ WriteByte(address[i]);
j++;
}
}
if(j>=64)
{ SelectScreE(2); //第10个字列的后2列
j=j-64;
SetLine(lin);
SetColumn(j);
for(i=4;i<6;i++) //在12864中第10个字列的最后两个字节
{WriteByte(address[i]);
}
}
}
//第11-20个字列
else if(10<column&&column<21)
{ column=column-11;
SelectScreE(2);
SetLine(lin);
SetColumn((column<<3)-(column<<1)+2);
for(i=0;i<6;i++)
WriteByte(address[i]);
}
//第21个字列
else if(column==21) //第21个字列
{ j=(column<<3)-(column<<1);
if(j<128) //第21个字列的前2列
{ Selec