⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocm4x8c.c

📁 Keil c工程
💻 C
字号:


/*****************  version infermation ******************************/
//
//build on 2004/03/16
//2004/04/09 debug draw picture mode.pass.
//2004/04/14 update function DrawPicture() and revise CGRAM.
//
/******************* hardware connection discreption ************************************/
//ocm4x8c and with character mold lcd(ST7920) compatible provided
//pin1:GND
//pin2:VCC
//pin3:not connected
//pin4:RS(CS) connect to A1
//pin5:RW     connect to A0
//
//!!the follow is important ,please vary the address 0x4000 accord to your hardware!!
// 
//pin6:EN=(!A_LCD)&(!(WRn&RDn)  ;HARDWARE connect:WRn and RDn is 8031 P3.6,P3.7 respectively;
//				A_LCD is 74138 output Y2n,also as 8031 address of 0x4000
//				74138 input A connect to 8031 P2.7(A15),B to P2.6(A14),C to P2.5(A13)
//
//pin7:DB0 	connect to D0
//...		...
//pin14:DB7	connect to D7
//pin15:connect to vcc,parallel mode
//pin16:not used
//pin17:RESETn   not used
//pin18:not connected
//pin19:connect to VCC
//pin20:connect to GND
//
//D0-D7 is the data bus,and A0-A15 is the address bus(so you must use a 74373)
//
/**********************************************************************************/
//  NOTE: 必须成对使用半角字符,否则将出错										  //
/**********************************************************************************/

/****************************函数原型**********************************************
void WaitMode(void);
void OCM4X8C_initial(void);
void IndexShiftLeft(void);
void IndexShiftRight(void);
void WholeShiftLeft(void);
void WholeShiftRight(void);
void ClearLine(byte);
void WholeShiftLeft_Clear(void);
void WholeShiftRight_Clear(void);
void WholeShiftLeft_Roll(void);
void WholeShiftRight_Roll(void);
void SetStartPoisition(byte line,byte x);
void DisplayEChar(byte EChar);
void DisplayCChar(word CChar);
void DisplayString(byte *string);
void DeleteNumber(void);
void DisplayNumber(word number);
void DrawPicture(byte *bmpPicture);

*****************************************************************************/

#define OCM4X8C		//有字库液晶

#ifdef OCM4X8C
#include <absacc.h>
//#include <math.h>
#include "..\h\OCM4X8C.h"

bit CheckOdd;	//初始值为0,输入偶数个字节为0,奇数个字节为1
//byte ShiftLeftNumber=0,ShiftRightNumber=0;
char ShiftNumber=0;	//正值为右移,负值为左移
code byte SelfMadeChar[4][16*2];	//4 16*16 self made characters dot matrix data
	

bit CheckBusy(void)		//返回值为1,说明正忙
{
byte i;
if((i=XBYTE[OCM4X8C_READ_INSTRUCTION])>=0x80)return(1);
else return(0);
}
byte ReadAC(void)		// AC as the ADDRESS COUNTER
{
return(XBYTE[OCM4X8C_READ_INSTRUCTION]&0x7F);
}

//
byte OCM4X8C_ReadData(void)	  //add on 2004/06/30
{
	while(CheckBusy());   
	return(XBYTE[OCM4X8C_READ_DATA]);
}

void OCM4X8C_WriteData(byte data_w)	 //add on 2004/06/30
{
	while(CheckBusy());
	XBYTE[OCM4X8C_WRITE_DATA]=data_w;   
}

void OCM4X8C_WriteInstruction(byte instr)  //add on 2004/06/30
{
	while(CheckBusy());
	XBYTE[OCM4X8C_WRITE_INSTRUCTION]=instr;
}
void WaitMode(void)
{
OCM4X8C_WriteInstruction(CLEAR_DISPLAY);		//clear all DDRAM(20h),set AC to 00h
}

void SetToBasicOperation(void)		//基本指令集动作
{
OCM4X8C_WriteInstruction(SET_FUNCTION_BASIC);
}

void SetToExtendOperation(void)		//扩展指令集动作
{
OCM4X8C_WriteInstruction(SET_FUNCTION_EXTEND);
}

void OCM4X8C_initial(void)
//if you need the index and index position,add this function.
//note:after draw a picture,index and index position will be set off.
{
CheckOdd=0;			//add on 2004/06/29
WaitMode();
SetToBasicOperation();
OCM4X8C_WriteInstruction(DISPLAY_STATUS+7);	//whole display on,index on,index position on
OCM4X8C_WriteInstruction(SET_ENTRANCE_POINT+2);//index shift right;whole display no move 
}


void IndexShiftLeft(void)
//index shift left 16 pixels,but not clear display,it will be replaced by the follow character.
{
OCM4X8C_WriteInstruction(0x10);
}

void IndexShiftRight(void)
//index shift right as 16 pixels,left a space
{
OCM4X8C_WriteInstruction(0x14);
}

void SetCGRAM(byte index)
//index should be value in 00h to 03h
{
byte i;

OCM4X8C_WriteInstruction(SET_CGRAM+index*0x10);
for(i=0;i<32;i++) 
	{
	OCM4X8C_WriteData(SelfMadeChar[index][i]);
	}

}


void SetDDRAM(byte AC)		//设置指针AC的位置。
{
OCM4X8C_WriteInstruction(SET_DDRAM+AC);
}

void ClearLine(byte line)
//清空第line行
{
byte i,AC;

	AC=ReadAC();
	switch(line)
	{
	 case 1:SetDDRAM(0x0);break;
	 case 2:SetDDRAM(0x10);break;
	 case 3:SetDDRAM(0x8);break;
	 case 4:SetDDRAM(0x18);break;
	}
	for(i=0;i<16;i++) OCM4X8C_WriteData(' ');
	SetDDRAM(AC);			//设置为原来的指针AC
}

void WholeShiftLeft(void)
//no change in RAM,but need to vary line.
{
OCM4X8C_WriteInstruction(0x18);
}

void WholeShiftRight(void)
{
OCM4X8C_WriteInstruction(0x1c);
}

void ClearCChar(byte AC)		//add on 2004/07/02
{
SetDDRAM(AC);
OCM4X8C_WriteData(0x20);
OCM4X8C_WriteData(0x20);

}
void WholeShiftLeft_Clear(void)
{
ShiftNumber%=8;

OCM4X8C_WriteInstruction(DISPLAY_STATUS+4);	//whole display on,index off,index position off

if(ShiftNumber<=0)
{
	ClearCChar(-ShiftNumber);
	ClearCChar(0x10-ShiftNumber);
	ClearCChar(0x8-ShiftNumber);
	ClearCChar(0x18-ShiftNumber);
}
else
{
	ClearCChar(0x10-ShiftNumber);
	ClearCChar(0x20-ShiftNumber);
	ClearCChar(0x8-ShiftNumber);
	ClearCChar(0x18-ShiftNumber);

}
ShiftNumber--;
WholeShiftLeft();
}

void Change(byte AC1,byte AC2)
//对换行滚动进行校正,add on 2004/07/02
{
byte temp1,temp2,temp3,temp4;

SetDDRAM(AC1);
temp1=OCM4X8C_ReadData();		//预读,必不可少
temp1=OCM4X8C_ReadData();
temp2=OCM4X8C_ReadData();

SetDDRAM(AC2);
temp3=OCM4X8C_ReadData();
temp3=OCM4X8C_ReadData();
temp4=OCM4X8C_ReadData();

SetDDRAM(AC2);
OCM4X8C_WriteData(temp1);
OCM4X8C_WriteData(temp2);

SetDDRAM(AC1);
OCM4X8C_WriteData(temp3);
OCM4X8C_WriteData(temp4);

}

void WholeShiftLeft_Roll(void)
{
ShiftNumber%=8;			//每行8个汉字,实际为16个,分两行。

if(ShiftNumber<=0)
{
	Change(-ShiftNumber,0x8-ShiftNumber);
	Change(0x10-ShiftNumber,0x18-ShiftNumber);
}
else
{
	Change(0x8-ShiftNumber,0x10-ShiftNumber);
	Change(0x18-ShiftNumber,0x20-ShiftNumber);
}
ShiftNumber--;
WholeShiftLeft();

}

void WholeShiftRight_Clear(void)
{
ShiftNumber%=8;

OCM4X8C_WriteInstruction(DISPLAY_STATUS+4);	//whole display on,index off,index position off

if(ShiftNumber>=0)
{
	ClearCChar(0x7-ShiftNumber);
	ClearCChar(0x17-ShiftNumber);
	ClearCChar(0xf-ShiftNumber);
	ClearCChar(0x1f-ShiftNumber);
}
else
{
	ClearCChar(0x7-ShiftNumber);
	ClearCChar(0x17-ShiftNumber);
	ClearCChar(-ShiftNumber-1);
	ClearCChar(0x9-ShiftNumber);
}

ShiftNumber++;
WholeShiftRight();
}

void WholeShiftRight_Roll(void)
{
ShiftNumber%=8;

if(ShiftNumber>=0)
{
	Change(0x7-ShiftNumber,0xf-ShiftNumber);
	Change(0x17-ShiftNumber,0x1f-ShiftNumber);
}
else
{
	Change(0x7-ShiftNumber,-ShiftNumber-1);
	Change(0x17-ShiftNumber,0x9-ShiftNumber);
}

ShiftNumber++;
WholeShiftRight();

}



void BackWhite(byte line)		//扩展指令集动作,line=1--4
{
OCM4X8C_WriteInstruction(BACK_WHITE+line-1);
}

void DrawOn(void)			//扩展指令集动作,绘图显示开
{
OCM4X8C_WriteInstruction(DRAW_ON);
}

void DrawOff(void)
{
OCM4X8C_WriteInstruction(DRAW_OFF);
}

void DisplayCGRAM(byte index)
//display 4 16*16 self define character
{
//index should be valued in 00h to 03h
	OCM4X8C_WriteData(0);
	OCM4X8C_WriteData(2*index);
}

void SetStartPoisition(byte line,byte x)
{
extern void  DisplayEChar(byte);
byte line_real;
if(CheckOdd) DisplayEChar(' ');  //add on 2004/06/01

switch(line)
	{
	case 1:line_real=0;break;
	case 2:line_real=0x10;break;
	case 3:line_real=8;break;
	case 4:line_real=0x18;break;
	}
SetDDRAM(line_real+x-1);

CheckOdd=0;				//add on 2004/06/29
}
void NextLine(void)
{
	while(CheckBusy());
	switch(ReadAC())
	{
	case 0x08:SetDDRAM(0x10);break;
	case 0x18:SetDDRAM(0x08);break;
	case 0x10:SetDDRAM(0x18);break;
	case 0x20:Delay100uS(5000);WaitMode();
				break;
    }

}
/*************** upper functions ********************************/
void DisplayChar(byte Char)
{
	OCM4X8C_WriteData(Char);
	CheckOdd^=1;

	if(!CheckOdd) NextLine();

}
void DisplayEChar(byte EChar)
{
//8*16 dot matrix
//EChar should be valued in 01h to 7fh
if((EChar>0)&&(EChar<0x80))
	{

	OCM4X8C_WriteData(EChar);
	CheckOdd^=1;

	if(!CheckOdd) NextLine();

	}
}

void DisplayCChar(word CChar)
{
//16*16 dot matrix
//CChar should be valued in 0xa1a1 to 0xf7fe,
//in which ,0xa1a0 to 0xa9ff is special characters,
//0xb0a1 to 0xd7fe is the class 1 chinese characters,
//0xd8a1 to 0xf7fe is the class 2 chinese characters.
byte high,low;
high=CChar>>8;
low=CChar;
if((high>0xa0)&&(high<0xf8)&&(low>0xa0)&&(low<0xff))
	{

	OCM4X8C_WriteData(high);	//higer 8bit,should be bigger than or equal to 0xa0
	OCM4X8C_WriteData(low);	//lower 8bit,should be bigger than or equal to 0xa0

	NextLine();
	}

}

void DisplayString(byte *string)
{
byte i=0;
while(*(string+i)!=LCD_STRING_END)
	{
	DisplayChar(*(string+i));
	i++;
	}
}

void DeleteNumber(void)
//删除刚输出的半角字符,2004/06/30
{
byte temp;

if(!CheckOdd)//delete right half
	{
	 IndexShiftLeft();
	 temp=OCM4X8C_ReadData();
	 temp=OCM4X8C_ReadData();
	 IndexShiftLeft();
	 DisplayEChar(' ');
	 DisplayEChar(' ');
	 IndexShiftLeft();
	 DisplayEChar(temp);
	}
else	//delete left half
	{
	 DisplayEChar(' ');
	 IndexShiftLeft();
	 DisplayEChar(' ');DisplayEChar(' ');
	 IndexShiftLeft();
	}
}

void DisplayNumber(word number)
{
byte NumDisplay[5];
byte i,*string;
bit rtn=0;

	NumDisplay[0]=number/10000;			//最高位
	number-=NumDisplay[0]*10000;

	NumDisplay[1]=number/1000;
	number-=NumDisplay[1]*1000;

	NumDisplay[2]=number/100;
	number-=NumDisplay[2]*100;

	NumDisplay[3]=number/10;
	number-=NumDisplay[3]*10;

	NumDisplay[4]=number;

	string=NumDisplay;
	
for(i=0;(i<5)&&(rtn==0);i++)			//寻找第一个不为0的数字位置//保证至少输出一个数字
	{
	 if(*(string+i)!=0) rtn=1;
	}
//if(i%2!=0)DisplayEChar(0x20);		  //保证输出偶数个字符
for(i-=1;i<5;i++) DisplayEChar(*(string+i)+0x30);

}

void DisplayDoubleNumber(bit left,bit space,word number)
//left=1,left align
//left=0,right align
//space=1,space;space=0,'0'
{
byte NumDisplay[5];
byte i,*string;
bit rtn=0;

	NumDisplay[0]=number/10000;			//最高位
	number-=NumDisplay[0]*10000;

	NumDisplay[1]=number/1000;
	number-=NumDisplay[1]*1000;

	NumDisplay[2]=number/100;
	number-=NumDisplay[2]*100;

	NumDisplay[3]=number/10;
	number-=NumDisplay[3]*10;

	NumDisplay[4]=number;

	string=NumDisplay;
	
for(i=0;(i<5)&&(rtn==0);i++)			//寻找第一个不为0的数字位置//保证至少输出一个数字
	{
	 if(*(string+i)!=0) rtn=1;
	}
if((i%2!=0)&&(left==0))space?DisplayEChar(0x20):DisplayEChar('0');		  //保证输出偶数个字符
DisplayNumber(number);
if((i%2!=0)&&(left==1))space?DisplayEChar(0x20):DisplayEChar('0');		  //保证输出偶数个字符

}

void SlideShow(byte time,byte line,byte *string)	//add on 2004/07/02
//time设定滑动速度,单位为10毫秒。
//line设置字符出现的行数,string为显示的字符,长度限制为小于8个汉字或16个半轿字符。
//字符从右边出现,至左边停止。string必须为偶数字节。
{
byte i,j=0;
word *p=string;

OCM4X8C_WriteInstruction(DISPLAY_STATUS+4);	//whole display on,index off,index position off

do
{
	SetStartPoisition(line,8-j);
	for(i=0;i<=j;i++)	DisplayCChar(*(p+i));
	Delay100uS(time*100);
	j++;
	
}
while (((*(string+2*j)!=LCD_STRING_END))&&(j<=8));

while(j<8)
{
	ClearLine(line);
	SetStartPoisition(line,8-j);
	DisplayString(string);
	Delay100uS(time*100);
	j++;
}

}

void SlideString(byte time,byte line,byte *string)	//add on 2004/07/02
//time设定滑动速度,line设置字符出现的行数,string为显示的字符,长度不限
//字符从右边出现, 一直向左滚动直到字符全部消失。string必须为偶数字节。
{
byte i,j=0;
byte length=0;	//字符串长度。
word *p=string;

OCM4X8C_WriteInstruction(DISPLAY_STATUS+4);	//whole display on,index off,index position off

do{length++;}
while(*(string+length)!=LCD_STRING_END);

if(length<=16)
{
	for(j=0;j<length/2;j++)
	{
	SetStartPoisition(line,8-j);
	for(i=0;i<=j;i++)	DisplayCChar(*(p+i));
	Delay100uS(time*100);
	}

	for(;j<8;j++)
	{
	 ClearLine(line);
	 SetStartPoisition(line,8-j);
	 for(i=0;i<length/2;i++) DisplayCChar(*(p+i));
	 Delay100uS(time*100);
	}

	for(j=1;j<=length/2;j++)
	{
	 ClearLine(line);
	 SetStartPoisition(line,1);
	 for(i=j;i<length/2;i++) DisplayCChar(*(p+i));
	 Delay100uS(time*100);

	} 

}
else
{
	for(j=0;j<8;j++)
	{
	SetStartPoisition(line,8-j);
	for(i=0;i<=j;i++)	DisplayCChar(*(p+i));
	Delay100uS(time*100);
	}
	for(j=1;j<=length/2-8;j++)
	{
	 SetStartPoisition(line,1);
	 for(i=j;i<j+8;i++) DisplayCChar(*(p+i));
	 Delay100uS(time*100);
	}
	for(;j<=length/2;j++)
	{
	 ClearLine(line);
	 SetStartPoisition(line,1);
	 for(i=j;i<length/2;i++) DisplayCChar(*(p+i));
	 Delay100uS(time*100);
	}
}

}
void DrawPicture(byte *bmpPicture)
//display 128*64 bmp
//横向取模 高位在左
//位图大小128*64 
//点阵由牧马字模输出
{
byte X,Y;

WaitMode();
OCM4X8C_WriteInstruction(DISPLAY_STATUS+4);	//whole display on,index off,index position off

SetToExtendOperation();
DrawOff();

 for(Y=0;Y<32;Y++)				
   {
	OCM4X8C_WriteInstruction(SET_GDRAM+Y);
	OCM4X8C_WriteInstruction(SET_GDRAM+0);	//X=0

   		for(X=0;X<8*2;X++)	//display the upper half
	     {
	 	  OCM4X8C_WriteData(*(bmpPicture+Y*0x10+X));
         }
        for(X=0;X<16;X++)	//display the lower half
	     {
	 	  OCM4X8C_WriteData(*(bmpPicture+0x1f0+Y*0x10+X));	
         }
  }

DrawOn();
SetToBasicOperation();
}

/*
void CA12864K_DrawPicture(byte *bmpPicture)
//display 128*64 bmp
//横向取模 高位在左
//位图大小128*64 
//点阵由牧马字模输出
{
byte X,Y;

WaitMode();
while(CheckBusy());
XBYTE[OCM4X8C_WRITE_INSTRUCTION]=DISPLAY_STATUS+4;	//whole display on,index off,index position off

SetToExtendOperation();
DrawOff();


 for(Y=0;Y<64;Y++)				
   {
	while(CheckBusy());
	XBYTE[OCM4X8C_WRITE_INSTRUCTION]=SET_GDRAM+Y;	//Y=0	
	while(CheckBusy());
	XBYTE[OCM4X8C_WRITE_INSTRUCTION]=SET_GDRAM+0;	//X=0

   		for(X=0;X<8*2;X++)	
	     {
	 	while(CheckBusy());
		XBYTE[OCM4X8C_WRITE_DATA]=*(bmpPicture+Y*0x10+X);
         }
  }

DrawOn();
SetToBasicOperation();
}
*/

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -