/*------------------------------------------------------------------------------------------[文件名] 12864.c[功能] 128X64驱动程序[版本] 2.0[作者] 鞠春阳[最后修改时间] 2003年5月12日[版权所有] [资料] 请到下载================================================================================= ==========*/#include "absacc.h"#include "intrins.h"//自定义库在"C:\comp51\UserLib\"文件夹中#include ".\inc\ASCII816.h" //字符点阵库 32-127#include ".\inc\HZTable.h" //汉字点阵库(自做)#include ".\inc\Menu.h" //汉字点阵库(自做)// LCD128*64 数据线#define LCD12864DataPort P1// LCD128*64 I/O 信号管脚sbit di =P3^1; // 数据\指令选择sbit rw =P3^3; // 读\写选择sbit en =P3^2; // 读\写使能sbit cs1 =P3^4; // 片选1,低有效(前64列)sbit cs2 =P3^5; // 片选2,低有效(后64列)sbit reset=P0^7; // 复位/*----------------------------------------------------------------------------------------------------*//* ****函数列表****//开关显示void SetOnOff(unsigned char onoff)//选择屏幕//screen: 0-全屏,1-左屏,2-右void SelectScreen(unsigned char screen)//清屏//screen: 0-全屏,1-左屏,2-右void ClearScreen(unsigned char screen)//显示8*8点阵//旋转90度:字模被竖着切分//lin:行(0-7), column: 列(0-15)//address : 字模区首地址void Show88(unsigned char lin,unsigned char column,unsigned int address)//显示8*16字符//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//character:字符代码(标准ASCII码)void ShowChar(unsigned char lin,unsigned char column,unsigned char character)//显示8*16字符串//!!!只能显示在一行上即: 串长+column <=15//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//address : 字模区首地址void ShowString(unsigned char lin,unsigned char column, unsigned char *string)//显示一个汉字//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//hzcode: 汉字代码(自定义的)void ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode)//显示图片//旋转90度 :字模被竖着切分//startline :开始行//startcolumn:开始列//linechar :图片行点除8(图片以8*8点阵为单位)//columnchar :图片列点除8(图片以8*8点阵为单位)//address : 字模区首地址void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnc har,unsigned int address)//!!问题大户//显示一行汉字//lin:行//lineheadaddr: 此行汉字代码区首地址void ShowLine(unsigned char lin,unsigned int lineheadaddr)//显示一屏汉字//pageheadaddr:此屏汉字代码地址区首地址void ShowPage(unsigned int pageheadaddr)//反显一个8*8字块//lin:行(0-3), column: 列(0-7)void ReverseShow88(unsigned char lin,unsigned char column)//反显一个字符//lin:行(0-4), column: 列(0-15)void ReverseShowChar(unsigned char lin,unsigned char column)//反显一个汉字//lin:行(0-3), column: 列(0-7)ReverseShowHZ(unsigned char lin,unsigned char column)//反显一行汉字//lin:行ReverseShow(unsigned char lin)//初始化LCDvoid InitLCD()****函数列表结束**** *//*----------------------------------------------------------------------------------------------------*//*--基本函数源程序------------------------------------------------------------------------------------*/ //延时Lcd12864delay(){unsigned int i=500;while(i--) {;}}/*----------------------------------------------------------------------------------------------------*///状态检查void CheckState(){unsigned char dat;di=0;rw=1;do{LCD12864DataPort=0xff;en=1; dat=LCD12864DataPort; en=0;dat=0x90 & dat; //仅当第4,7位为0时才可操作}while(!(dat==0x00));}/*----------------------------------------------------------------------------------------------------*/ //写显示数据//dat:显示数据void WriteByte(unsigned char dat){CheckState();di=1; rw=0;LCD12864DataPort=dat;en=1; en=0;}/*-----------------------------------------------------------------------------------------------------*/ //向LCD发送命令//command :命令SendCommandToLCD(unsigned char command){CheckState();rw=0;LCD12864DataPort=command;en=1; en=0;}/*----------------------------------------------------------------------------------------------------*/ //设定行地址(页)--X 0-7void SetLine(unsigned char line){line=line & 0x07; // 0<=line<=7line=line|0xb8; //1011 1xxxSendCommandToLCD(line);}//设定列地址--Y 0-63void SetColumn(unsigned char column){column=column &0x3f; // 0=<column<=63column=column | 0x40; //01xx xxxxSendCommandToLCD(column);}//设定显示开始行--XXvoid SetStartLine(unsigned char startline) //0--63{startline=startline & 0x07;startline=startline|0xc0; //1100 0000SendCommandToLCD(startline);}//开关显示void SetOnOff(unsigned char onoff){onoff=0x3e | onoff; //0011 111xSendCommandToLCD(onoff);}/*---------------------------------------------------------------------------------------------------*///选择屏幕//screen: 0-全屏,1-左屏,2-右屏void SelectScreen(unsigned char screen){ //北京显示器:负有效 cs1: 0--右; cs2: 0--左switch(screen){ case 0: cs1=0;//全屏_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); cs2=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); break;case 1: cs1=1;//左屏_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); cs2=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); break;case 2: cs1=0;//右屏_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); cs2=1;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); break;}}/*---------------------------------------------------------------------------------------------------*///清屏//screen: 0-全屏,1-左屏,2-右void ClearScreen(unsigned char screen){ unsigned char i,j;SelectScreen(screen);for(i=0;i<8;i++){ SetLine(i);for(j=0;j<64;j++){WriteByte(0x00);}}}/*--------------------------------------------------------------------------------------------------*/ //显示8*8点阵//旋转90度:字模被竖着切分//lin:行(0-7), column: 列(0-15)//address : 字模区首地址void Show88(unsigned char lin,unsigned char column,unsigned int address){ unsigned char i;if(column>16) {return;}if(column<8) SelectScreen(1); //如果列数<8(0,1,2,3,4,5,6,7)则写在第一屏上else {SelectScreen(2); //否则 (8,9,10,11,12,13,14,15)写在第二屏上column=column & 0x07; //防止越界}SetLine(lin);SetColumn(column<<3);for(i=0;i<8;i++) WriteByte( CBYTE[address+i] );}/*------------------------------------------------------------------------------------------------*/ //显示8*16字符//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//character:字符代码(标准ASCII码)void ShowChar(unsigned char lin,unsigned char column,unsigned char character) { lin=lin<<1;Show88(lin ,column,ASCII816[character-0x20] );Show88(lin+1,column,ASCII816[character-0x20]+8 );}/*-----------------------------------------------------------------------------------------------*/ /*//显示8*16字符串//!!!只能显示在一行上即: 串长+column <=15//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-15)//address : 字模区首地址void ShowString(unsigned char lin,unsigned char column, unsigned char *string) { unsigned char ch;unsigned char i=0;while(*string!='\0'){ch=*string;if(i+column >15) break; //(只能显示在一行上即: 串长+column <=15) ShowChar(lin,i+column,ch);string++; i++;}*//*----------------------------------------------------------------------------------------------*///显示一个汉字//旋转90度:字模被竖着切分//lin:行(0-3), column: 列(0-7)//hzcode: 汉字代码(自定义的)//uchar code HZtablevoid ShowHZ(unsigned char lin,unsigned char column,unsigned int hzcode){lin=lin<<1; //lin*2Show88(lin,column,HZTable[hzcode]);Show88(lin,column+1,HZTable[hzcode]+8);Show88(lin+1,column,HZTable[hzcode]+16);Show88(lin+1,column+1,HZTable[hzcode]+24);}/*----------------------------------------------------------------------------------------------*///显示图片//旋转90度 :字模被竖着切分//startline :开始行//startcolumn:开始列//linechar :图片行点除8(图片以8*8点阵为单位)//columnchar :图片列点除8(图片以8*8点阵为单位)//address : 字模区首地址void ShowPicture(unsigned char startline,unsigned char startcolumn,unsigned char linechar,unsigned char columnc har,unsigned int address){ unsigned char i,j;for(i=0;i<columnchar;i++)for(j=0;j<linechar;j++)Show88(startline+i , startcolumn+j , address+(i*linechar+j)*8 );}/*----------------------------------------------------------------------------------------------*///显示一行字符串(汉字,字母混排,一行16字节)//lin:行//lineheadaddr: 此行汉字代码区首地址void ShowLine(unsigned char lin,unsigned char linehead[]){ unsigned char i;unsigned char byte;unsigned int hzcode;for( i=0; i<16; ){ byte=linehead[i];if(byte < 0x80) //字母if(i>15) return; //!!编译器有问题,须强制退出ShowChar(lin, i , byte);i=i+1;}else // byte >= 0x80(汉字){if(i>15) return; //!!编译器有问题,须强制退出byte=byte & 0x7f; //最高位置0,即:减去0x8000hzcode=(unsigned int)byte<<8; //?? //高8位hzcode=hzcode+linehead[i+1]; //加低8位,组合成整型数地址ShowHZ( lin,i,hzcode);i=i+2;}}}/*----------------------------------------------------------------------------------------------------*/ //显示一屏汉字//pageheadaddr:此屏汉字代码地址区首地址void ShowPage(unsigned char pagehead[][16]){ unsigned char i;for(i=0;i<4;i++) ShowLine(i,pagehead[i]); //1行8个汉字,16字节}/*----------------------------------------------------------------------------------------------------*/ //读显示数据unsigned char ReadByte(){unsigned char dat;CheckState();di=1; rw=1;LCD12864DataPort=0xff;en=1; dat=LCD12864DataPort; en=0;return(dat);}/*----------------------------------------------------------------------------------------------------*/ //反显一个8*8字块//lin:行(0-3), column: 列(0-7)void ReverseShow88(unsigned char lin,unsigned char column){ unsigned char i;unsigned char tab[8];if(column<8) SelectScreen(1); //如果列数<4(0,1,2,3),则写在第一屏上else SelectScreen(2); //否则 (4,5,6,7), 写在第二屏上//读上部8列column=column<<3; //每个方块8*8大小SetLine(lin);SetColumn(column);tab[0]=ReadByte(); //空读!!!!! //?for(i=0;i<8;i++) tab[i]=~ReadByte();//写回SetLine(lin);SetColumn(column);for(i=0;i<8;i++) WriteByte(tab[i]);}/*----------------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------------*/ //反显一个字符//lin:行(0-4), column: 列(0-15)void ReverseShowChar(unsigned char lin,unsigned char column){ lin=lin<<1;ReverseShow88(lin ,column);ReverseShow88(lin+1,column);}/*----------------------------------------------------------------------------------------------------*/ //反显一个汉字//lin:行(0-3), column: 列(0-7)ReverseShowHZ(unsigned char lin,unsigned char column){lin=lin<<1;column=column<<1;ReverseShow88(lin ,column );ReverseShow88(lin ,column+1);ReverseShow88(lin+1,column );ReverseShow88(lin+1,column+1);}/*----------------------------------------------------------------------------------------------------*/ //反显一行汉字//lin:行ReverseShow(unsigned char lin){ unsigned char i;for(i=0;i<8;i++) ReverseShowHZ(lin,i);}/*----------------------------------------------------------------------------------------------------*/ void InitLCD() //初始化LCD{ unsigned char i=250; //延时while(i--);//reset=0;//复位//reset=1;SelectScreen(0);SetOnOff(0); //关显示ClearScreen(1);//清屏ClearScreen(2);SelectScreen(0);SetOnOff(1); //开显示SelectScreen(0);SetStartLine(0); //开始行:0}/*----------------------------------------------------------------------------------------------------*/void Reset() //液晶复位{//reset 低复位 _|-reset=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); reset=1;//全屏cs1=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); cs2=0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SendCommandToLCD(0x3F);}/*----------------------------------------------------------------------------------------------------*/。