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

📄 lcdbios.cpp

📁 液晶驱动显示例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	unsigned int j;
	while(i--)
	{
		for(j=0;j<15;j++) //j<50
			asm("nop;");
	}
	
}

CLcd::CLcd()
{
}


void CLcd::Init()
{
	short i,j;
	InitAMC();
	
	PLcdCtl=(unsigned short *)LCDCTLBUSADD;
	PLcdData=(unsigned short *)LCDDATABUSADD;
	*PLcdData=0x00;
	ctl|=EN;
	*PLcdCtl = ctl;
	xpos=ypos=0;
	xp=yp=0;
	reset();
	ctrstNumber = 25;
}

void CLcd::PushCriticalRegion(void)
{
	#ifdef VDK_H_
	VDK::PushCriticalRegion();
	#endif
}

void CLcd::PopCriticalRegion(void)
{
	#ifdef VDK_H_
	VDK::PopCriticalRegion();
	#endif  
}


//int ReadItemEx(1, 0, 0x2023, BYTE* pbBuf)  	//0x2023 1 对比度 
//int WriteItemEx(1, 0, 0x2023, BYTE* pbBuf)  //0x2023 1 对比度 
//#define SDAIN();		{*pFIO_INEN&= ~SDA;*pFIO_INEN|= SDA;*pFIO_DIR &=~SDA;*pFIO_INEN|= SDA;}
//#define SDAOUT();		{*pFIO_INEN&= ~SDA;*pFIO_DIR |=SDA;}//*pFIO_INEN&=~ SDA;}

void CLcd::reset(bool Reset)
{
	unsigned char i,j;
	ctl &=~RST;
	*PLcdCtl=ctl;
	lcddelay(20);//lcddelay(50);
	ctl |=RST;
	*PLcdCtl=ctl;
	*pFIO_INEN&=~UPDOWNCTL;
	*pFIO_INEN&=~INC;
	*pFIO_DIR |=UPDOWNCTL;
	*pFIO_DIR |=INC;
	
	open();
	if(Reset)
	{
		int tt = ReadItemEx(1, 0, 0x2023, &ctrstNumber);
		for(i=0;i<33;i++)
	    {
	    	subCtrst();
	    }
	    for(i=0;i<ctrstNumber;i++)		//i<24
	    {	
	    	addCtrst();
	    }
	
		writecmd(START_LINE,1);
		writecmd(START_LINE,2);
	}	
}

void CLcd::SetStartLine(void)
{
	writecmd(START_LINE,1);
	writecmd(START_LINE,2);
}
	
//开关对比度调节
void CLcd::ctstenable(bool en)
{
	if(en==true)
	{
		ctl &=~CSTEN;
		*PLcdCtl=ctl;
	}
	else
	{
		ctl |= CSTEN;
		*PLcdCtl=ctl;
	}	
}

//往液晶写命令
void CLcd::writecmd(unsigned char cmd,char cs)
{	
	if(cs==1)
	{
		ctl &=~CS1;	//选中CS1
		ctl |= CS2;		
	}
	if(cs==2)
	{
		ctl &=~CS2; //选中CS2
		ctl |= CS1;
	}
	
	if(cs==3)
	{
		ctl &=~CS1;	//选中CS1
		ctl &=~CS2; //选中CS2
	}
			
	ctl &=~EN;
	*PLcdCtl=ctl;//先拉低EN
	
	ctl &=~RW;	//写
	ctl &=~DI;	//写指令
	*PLcdCtl=ctl;
	lcddelay(1);
	*PLcdData=cmd;
	//lcddelay(1);
	ctl |= EN;
	*PLcdCtl=ctl;
	lcddelay(2);
	ctl &=~EN;
	*PLcdCtl=ctl;
	lcddelay(3);
}

//往液晶写一个数据x是列地址从0~127,y是行地址0~7,对于超出屏幕范围的数据将不显示
//AG12864E液晶是纵向液晶,一个ram字节对应于屏幕上的一竖
bool CLcd::writedat(unsigned char dat,short x,short y)
{			
	if(x<0 || x>127 || y<0 || y>7)//数据有效性检查,超出屏幕范围的坐标直接返回
		return true;
	
	//////////////////////////////////////////////
	//写映像区
	lcdmap[x][y]=dat;
	
	//////////////////////////////////////////////
	if(x<64)
	{	
		writecmd(X0_ADD+(unsigned char)x,CS1);
		writecmd(Y0_ADD+(unsigned char)y,CS1);
		
		// 1.先拉低EN	
		ctl &=~EN;
		*PLcdCtl=ctl;

		ctl &=~RW;	//写	
		ctl |=DI;	//写数据

		*PLcdCtl=ctl;
		lcddelay(1);
		*PLcdData=dat;
		ctl |= EN;
		*PLcdCtl=ctl;	
		lcddelay(2);

		ctl &= ~EN;
		*PLcdCtl=ctl;	//先拉低EN
		lcddelay(1);
	}
	else if(x>63 && x<128)
	{
		writecmd(Y0_ADD+(unsigned char)y,CS2);
		writecmd(X0_ADD+(unsigned char)(x%64),CS2);
		
		// 1.先拉低EN	
		ctl &=~EN;
		*PLcdCtl=ctl;

		ctl &=~RW;	//写	
		ctl |=DI;	//写数据

		*PLcdCtl=ctl;
		lcddelay(1);
		*PLcdData=dat;
		
		ctl |= EN;
		*PLcdCtl=ctl;	
		lcddelay(2);

		ctl &= ~EN;
		*PLcdCtl=ctl;
		lcddelay(1);		
	}

	//xpos=x,ypos=y;
	lcddelay(3);
	return true;
}

void CLcd::refresh(void)
{
	unsigned char x,y;
	for(x=0;x<128;x++)
		for(y=0;y<8;y++)
			writedat(lcdmap[x][y],x,y);	
}

//往xy位置写一个英文字符
//x=0~15,y=0~3
void CLcd::writechr(unsigned char *dat,short x,short y,bool reverse)
{
	short i,j,k;
	unsigned char chbuf[2][16];
	char f=32;
	//char g=0;
	x *= 8;
	y *= 2;
	
	for(i=0;i<16;i++)
	{
		chbuf[0][i]=*(dat+i);
		chbuf[1][i]=0;
	}
	
	k=0;
	for(i=8;i>0;i--)
	{	
		f=16;
		for(j=0;j<8;j++)
		{
			f--;
			chbuf[1][k]	|= ((chbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
		//f=16;
		for(j=0;j<8;j++)
		{
			f--;
			chbuf[1][k]	|= ((chbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
	}	
	
	for(i=0;i<8;i++)
	{
		if(reverse)
			{
				
				writedat(~chbuf[1][i*2],x+i,y+1);
				writedat(~chbuf[1][i*2+1],x+i,y);
			}
		else
			{
				writedat(chbuf[1][i*2],x+i,y+1);
				writedat(chbuf[1][i*2+1],x+i,y);
			}
	}
}

//
//往xy位置写一个英文字符
//x=0~15,y=0~7
void CLcd::writechrs(char *ch,short x,short y,bool reverse)
{
	short i,j,k;
	unsigned char chbuf[2][16],*p;
	char f=32;
	//char g=0;
	x *= 8;
	//y *= 2;
	p =  chr;
	p += (*ch-32)*16; 	//得到字符在字库中的首地址
	
	for(i=0;i<16;i++)
	{
		chbuf[0][i]=*(p+i);
		chbuf[1][i]=0;
	}
	
	k=0;
	for(i=8;i>0;i--)
	{	
		f=16;
		for(j=0;j<8;j++)
		{
			f--;
			chbuf[1][k]	|= ((chbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
		//f=16;
		for(j=0;j<8;j++)
		{
			f--;
			chbuf[1][k]	|= ((chbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
	}
	
	
	for(i=0;i<8;i++)
	{
		if(reverse)
			{
				
				writedat(~chbuf[1][i*2],x+i,y+1);
				writedat(~chbuf[1][i*2+1],x+i,y);
			}
		else
			{
				writedat(chbuf[1][i*2],x+i,y+1);
				writedat(chbuf[1][i*2+1],x+i,y);
			}
	}
}


//往xy位置写一个汉字
//x=0~14,y=0~3
void CLcd::writechchr(unsigned char *dat,short x,short y,bool reverse)
{
	short i,j,k;
	unsigned char hzbuf[2][32];
	char f=32;
	//char g=0;
	x *= 8;
	y *= 2;
	//PushCriticalRegion();
	
	for(i=0;i<32;i++)
	{
		hzbuf[0][i]=*(dat+i);
		hzbuf[1][i]=0;
	}	
	
	//PopCriticalRegion();
	k=0;
	for(i=8;i>0;i--)	//开始将字符顺时针旋转90度
	{	
		f=32;
		for(j=0;j<8;j++)
		{
			f-=2;
			hzbuf[1][k]	|= ((hzbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
		//f=16;
		for(j=0;j<8;j++)
		{
			f-=2;
			hzbuf[1][k]	|= ((hzbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
	}
	
	for(i=8;i>0;i--)
	{	
		f=33;
		for(j=0;j<8;j++)
		{
			f-=2;
			hzbuf[1][k]	|= ((hzbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
		//f=16;
		for(j=0;j<8;j++)
		{
			f-=2;
			hzbuf[1][k]	|= ((hzbuf[0][f] & (0x01<<(i-1)))<<(8-i))>>j;
			
		}
		k++;
	}
	
	for(i=0;i<16;i++)
	{
		if(reverse)
			{
				writedat(~hzbuf[1][i*2],x+i,y+1);
				writedat(~hzbuf[1][i*2+1],x+i,y);
			}
		else
			{
				writedat(hzbuf[1][i*2],x+i,y+1);
				writedat(hzbuf[1][i*2+1],x+i,y);
			}
	}
}

//清屏函数
void CLcd::clear()
{
	short x,y;
	for(x=0;x<128;x++)
	{
		for(y=0;y<8;y++)
		{
			writedat(0x00,x,y);
			lcdmap[x][y]=0;
		}
	}
}

//关显示
void CLcd::close()		
{
	writecmd(LCD_OFF,3);
}

//开显示					
void CLcd::open()				
{
	writecmd(LCD_ON,3);
}

//此函数用于在液晶的指定位置打印字符
//由于汉字的内码与区位码有一定的关系,
//所以,只要通过内码就可以得到区位码,从而也就得到了汉字的字模。  
//设一个汉字的内码为ddff,则此汉字的区码为dd-161;位码为ff-161;
//该汉字字模的第一个字节在字库中的位置是(94×区码+位码)×32。
//这时只要连续的读出32个字节,就可以得到该汉字的字模。
//假定全字库的首地址为hzk[];
//x,y以英文字符计算位置,x=0~15,y=0~3
//可以使用\n来回车换行,使用\r来使这一行居中显示并用空格填充前面的空格
//可以使用\n\n来填充空格到行未并换行,可以使用\r\r来使一行居右显示并用空格填充前面的空白
//可以使用\t来填充行首
void CLcd::print(char *str,short x,short y,bool reverse)//缺省参数在当前位置打印
{
	char len,i,j;
	unsigned char *p,*ustr;
	len=strlen(str);

	ustr=(unsigned char *)str;

⌨️ 快捷键说明

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