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

📄 lcddrv.c

📁 LPC213x系列微处理器操作T6963液晶显示屏的驱动程序
💻 C
字号:
#include  "config.h"
#include "RD_LPC2100.h"
#include <stdarg.h>
#include <stdio.h>


#include "ASCII.h"
#include "LCDDRV.h"
#include "bmp1.h"


uchar gCurRow,gCurCol,gCurMode = 0;	// 当前行、列存储,行高16点,列宽8点
uchar const *MenuIndex[5]={Bmp001,Bmp002,Bmp003,Bmp004};
const uchar uPowArr[]  = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
uchar FBpos[] = {6,54,102,150,198};

typedef struct typFNT_GB16	// 汉字字模显示数据结构
{
	uchar Index[2];
	uchar Msk[32];
};
const struct typFNT_GB16  GB_16[] = {	// 显示为16*16
"中",0x01,0x00,0x01,0x00,0x21,0x08,0x3F,0xFC,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,0x21,0x08,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,
"文",0x02,0x00,0x01,0x00,0x01,0x00,0xFF,0xFE,0x08,0x20,0x08,0x20,0x08,0x20,0x04,0x40,0x04,0x40,0x02,0x80,0x01,0x00,0x02,0x80,0x04,0x60,0x18,0x1E,0xE0,0x08,0x00,0x00,
"测",0x40,0x02,0x27,0xC2,0x24,0x42,0x84,0x52,0x45,0x52,0x55,0x52,0x15,0x52,0x25,0x52,0x25,0x52,0x25,0x52,0xC5,0x52,0x41,0x02,0x42,0x82,0x42,0x42,0x44,0x4A,0x48,0x04,
"试",0x00,0x20,0x40,0x28,0x20,0x24,0x30,0x24,0x27,0xFE,0x00,0x20,0xE0,0x20,0x27,0xE0,0x21,0x20,0x21,0x10,0x21,0x10,0x21,0x0A,0x29,0xCA,0x36,0x06,0x20,0x02,0x00,0x00,
};


uchar fnGetRow(void)
{
	return gCurRow;
}

uchar fnGetCol(void)
{
	return gCurCol;
}

uchar fnST01(void)		// 状态位STA1,STA0判断(读写指令和读写数据)
{
	uchar i,status;
	
	for(i=10;i>0;i--)
	{
		ReadStatus;
		status = LCMCW;
		ReadOK;
		if((status & 0x03) == 0x03)
			break;
	}
	return i;	// 若返回零,说明错误
}

uchar fnST2(void)		// 状态位ST2判断(数据自动读状态)
{
	uchar i,status;
	
	for(i=10;i>0;i--)
	{
		ReadStatus;
		status = LCMCW;
		ReadOK;
		if((status & 0x04) == 0x04)
			break;
	}
	return i;	// 若返回零,说明错误
}

uchar fnST3(void)		// 状态位ST3判断(数据自动写状态)
{
	uchar i,status;
	
	for(i=10;i>0;i--)
	{
		ReadStatus;
		status = LCMCW;
		ReadOK;
		if((status & 0x08) == 0x08)
			break;
	}
	return i;	// 若返回零,说明错误
}

uchar fnST6(void)		// 状态位ST6判断(屏读/屏拷贝状态)
{
	uchar i,status;
		
	for(i=10;i>0;i--)
	{
		ReadStatus;
		status = LCMCW;
		ReadOK;
		if((status & 0x40) == 0x40)
			break;
	}
	return i;	// 若返回零,说明错误
}

uchar fnPR1(uchar uCmd,uchar uPar1,uchar uPar2)	// 写双参数的指令
{
	if(fnST01() == 0)
		return 1;
	WriteData;	
	LCMDW = uPar1;
	WriteOK;
	if(fnST01() == 0)
		return 2;
	WriteData;
	LCMDW = uPar2;
	WriteOK;
	if(fnST01() == 0)
		return 3;
	WriteCmd;
	LCMCW = uCmd;
	WriteOK;
	return 0;	// 返回0成功
}

uchar fnPR11(uchar uCmd,uchar uPar1)	// 写单参数的指令
{
	if(fnST01() == 0)
		return 1;
	WriteData;
	LCMDW = uPar1;
	WriteOK;
	if(fnST01() == 0)
		return 2;
	WriteCmd;
	LCMCW = uCmd;
	WriteOK;
	return 0;	// 返回0成功
}

uchar fnPR12(uchar uCmd)		// 写无参数的指令
{
	if(fnST01() == 0)
		return 1;
	WriteCmd;
	LCMCW = uCmd;
	WriteOK;
	return 0;	// 返回0成功
}

uchar fnPR13(uchar uData)		// 写数据
{
	if(fnST3() == 0)
		return 1;
	WriteData;
	LCMDW = uData;
	WriteOK;
	return 0;	// 返回0成功
}

uchar fnPR14(uchar uData)		// 写数据
{
	if(fnST01() == 0)
		return 1;
	WriteData;
	LCMDW = uData;
	WriteOK;
	return 0;	// 返回0成功
}

uchar fnPR2(void)				// 读数据
{
	uchar data;
	
	if(fnST01() == 0)
		return 1;
	ReadData;
	data = LCMDW;
	ReadOK;
	return data;
}

// 设置当前地址

void fnSetPos(uchar urow, uchar ucol)
{
	uint  iPos;
    
    if (gCurMode == 0)  //for graph
    {
	    iPos = urow * 30 + ucol + GH_Addr;
	}
	else            //for text
	{
	    iPos = urow * 30 + ucol;
	}
	fnPR1(LC_ADD_POS,iPos & 0xFF,iPos / 256);
	gCurRow = urow;
	gCurCol = ucol;
}

// 设置当前显示行、列
void cursor(uchar uRow, uchar uCol)
{
	fnSetPos(uRow * 16, uCol);
}

// 清屏
void cls(void)
{
	uint  i;

	if (gCurMode == 1)
	{
	    fnPR1(LC_ADD_POS,0x00,0x00);	// 置地址指针
    	fnPR12(LC_AUT_WR);				// 自动写
    	for(i=0;i<16*30;i++)
    	{
    		fnST3();
    		fnPR13(0x00);				// 写数据
    	}
    	fnPR12(LC_AUT_OVR);				// 自动写结束
	    fnPR1(LC_ADD_POS,0x00,0x00);	// 置地址指针
	}
	else
	{
	    fnPR1(LC_ADD_POS,(GH_Addr & 0xFF),(GH_Addr / 256));	// 置地址指针
	    fnPR12(LC_AUT_WR);				// 自动写
	    for(i=0;i<240*30;i++)
	    {
		    fnST3();
		    fnPR13(0x00);				// 写数据
	    }
	    fnPR12(LC_AUT_OVR);				// 自动写结束
	    fnPR1(LC_ADD_POS,(GH_Addr & 0xFF),(GH_Addr / 256));	// 置地址指针
	}

	//fnPR1(LC_ADD_POS,0x00,0x00);	// 重置地址指针
	gCurRow = 0;					// 置地址指针存储变量
	gCurCol = 0;
}

//LCM text mode


//LCM graph mode

// LCM 初始化
char fnLCMInit(void)
{
	if(fnPR1(LC_TXT_STP,0x00,0x00) != 0)	// 文本显示区首地址
		return -1;
	fnPR1(LC_TXT_WID,0x1E,0x00);	// 文本显示区宽度
	fnPR1(LC_GRH_STP,(GH_Addr&0xff),(GH_Addr>>8));	// 图形显示区首地址
	fnPR1(LC_GRH_WID,0x1E,0x00);	// 图形显示区宽度
	fnPR12(LC_CUR_SHP | 0x01);		// 光标形状
	fnPR12(LC_MOD_OR);				// 显示方式设置
	//fnPR12(LC_MOD_XOR);				// 显示方式设置
	fnPR12(LC_DIS_SW | 0x08);		// 显示开关设置
	//fnPR12(LC_DIS_SW | 0x0f);		// 显示开关设置
	return 0;
}



/*
//在指定位置显示反白的块
void FunBlock(uchar X,uchar Y,uchar width,uchar height)
{

   	uchar j,k,uLen,uRow,uCol,data;
   	
	//uRow = fnGetRow();
	//uCol = fnGetCol();
	
	X = X>>3;
	width = width>>3;
	uCol = X;
	uRow = Y;

    for(k=0;k<height;k++)
	{
		for (j=0;j<width;j++)
		{
			fnSetPos(uRow+k,uCol+j);
			fnPR12(LC_AUT_RD);			// 写数据
			data = fnPR2();
		    fnPR12(LC_AUT_OVR);
		    //SendByte(data);
		    fnSetPos(uRow+k,uCol+j);
			fnPR12(LC_AUT_WR);			// 写数据
			fnPR13(~data);
		    fnPR12(LC_AUT_OVR);
		}
	}
	fnPR1(LC_ADD_POS,0x00,0x00);	// 重置地址指针
	gCurRow = 0;					// 置地址指针存储变量
	gCurCol = 0;
	

}
*/

//在指定位置显示反白的块
void FunBlock(uchar X,uchar Y,uchar width,uchar height)
{

   	volatile uchar j,k,uLen,uRow,uCol,data,xmax,xm;
	//uRow = fnGetRow();
	//uCol = fnGetCol();
	xmax = X+width;
	xm = (xmax>>3)<<3;
	//X = X>>3;
	width = width>>3;
	uCol = 0;
	uRow = Y;

    //LCM_GRAPH;
    for(k=0;k<height;k++)
	{
		for (j=X;j<xm;j+=8)
		{
			fnSetPos(uRow+k,uCol+j/8);
			fnPR12(LC_AUT_RD);			// 写数据
			data = fnPR2();
		    fnPR12(LC_AUT_OVR);
		    //SendByte(data);
		    fnSetPos(uRow+k,uCol+j/8);
			fnPR12(LC_AUT_WR);			// 写数据
			data ^= (0xff>>(j%8));
			fnPR13(data);
		    fnPR12(LC_AUT_OVR);
		    if(j==X)
		        j=(j>>3)<<3;
		}
		
		
		if (xmax>=xm)
		{
			fnSetPos(uRow+k,uCol+j/8);
			fnPR12(LC_AUT_RD);			// 写数据
			data = fnPR2();
		    fnPR12(LC_AUT_OVR);
		    //SendByte(data);
		    fnSetPos(uRow+k,uCol+j/8);
			fnPR12(LC_AUT_WR);			// 写数据
			if (xmax>xm)
			    data ^= (0xff<<(8-(xmax%8)));
			else
			    data ^= (0xff>>(8-(xmax%8)));

			//data &= (0xff>>(xmax%8));
			//data |= (xmax2>>(xmax%8));
			fnPR13(data);
		    fnPR12(LC_AUT_OVR);
		}
	}
	fnPR1(LC_ADD_POS,0x00,0x00);	// 重置地址指针
	gCurRow = 0;					// 置地址指针存储变量
	gCurCol = 0;
	

}


// ASCII(8*16) 及 汉字(16*16) 显示函数
uchar dprintf(char *fmt, ...)
{
	va_list arg_ptr;
	uchar  c1,c2,cData;
	char tmpBuf[64];				// LCD显示数据缓冲区
	uchar i=0,j,uLen,uRow,uCol;
	uint  k;
	
	//LCM_GRAPH;
	va_start(arg_ptr, fmt);
	uLen = (uchar)vsprintf(tmpBuf, fmt, arg_ptr);
//    uLen = 512;
	va_end(arg_ptr);

	while(i<uLen)
	{
		c1 = tmpBuf[i];
		c2 = tmpBuf[i+1];
		uRow = fnGetRow();
		uCol = fnGetCol();
		if((c1 >= 0) && (c1 <0xa0))
		{	// ASCII
			if(c1 < 0x20)
			{
				switch(c1)
				{
					case CR:
					case LF:		// 回车或换行
						i++;
						if(uRow < 112)
							fnSetPos(uRow+16,0);
						else
							fnSetPos(0,0);
						continue;
					case BS:		// 退格
						if(uCol > 0)
							uCol--;
						fnSetPos(uRow,uCol);
						cData = 0x00;
						break;
					default:		// 其他
						c1 = 0x1f;
				}
			}
			for(j=0;j<16;j++)
			{
				fnPR12(LC_AUT_WR);		// 写数据
				if(c1 >= 0x1f)
				{
					if(j < (16-ASC_CHR_HEIGHT))
						fnPR13(0x00);
					else
						fnPR13(ASC_MSK[(c1-0x1f)*ASC_CHR_HEIGHT+j-(16-ASC_CHR_HEIGHT)]);
				}
				else
					fnPR13(cData);
				fnPR12(LC_AUT_OVR);
				fnSetPos(uRow+j+1,uCol);
			}
			if(c1 != BS)		// 非退格
				uCol++;
		}
		else if(c1 >= 0xa0)
		{	// 中文
			for(j=0;j<sizeof(GB_16)/sizeof(GB_16[0]);j++)
			{
				if((c1 == GB_16[j].Index[0]) && (c2 == GB_16[j].Index[1]))
					break;
			}
			for(k=0;k<sizeof(GB_16[0].Msk)/2;k++)
			{
				fnSetPos(uRow+k,uCol);
				fnPR12(LC_AUT_WR);			// 写数据
				if(j < sizeof(GB_16)/sizeof(GB_16[0]))
				{
					//fnSetPos(uRow+k,uCol);
					fnPR13(GB_16[j].Msk[k*2]);
					//fnSetPos(uRow+k,(uCol+1));
					fnPR13(GB_16[j].Msk[k*2+1]);
				}
				else						// 未找到该字
				{
					if(k < sizeof(GB_16[0].Msk)/4)
					{
						fnPR13(0x00);
						fnPR13(0x00);
					}
					else
					{
						fnPR13(0xff);
						fnPR13(0xff);
					}
				}
				fnPR12(LC_AUT_OVR);
			}
			uCol += 2;
			i++;
		}
		if(uCol >= 30)			// 光标后移
		{
			uRow += 16;
			if(uRow < 0x80)
				uCol -= 30;
			else
			{
				uRow = 0;
				uCol = 0;
			}
		}
		fnSetPos(uRow,uCol);
		i++;
	}
	return uLen;
}

void ReadLcd(void)
{
   	uchar j,k,uLen,uRow,uCol,data;
	//uRow = fnGetRow();
	//uCol = fnGetCol();
	uCol = 0;
	uRow = 0;

    //LCM_GRAPH;
    for(k=0;k<128;k++)
	{
		//fnSetPos(uRow+k,uCol);
		//BMPdata = BMPdata + k*Xw; 
		//fnPR12(LC_AUT_RD);			// 写数据
		for (j=0;j<30;j++)
		{
			fnSetPos(uRow+k,uCol+j);
			fnPR12(LC_AUT_RD);			// 写数据
			data = fnPR2();
		    fnPR12(LC_AUT_OVR);
		    //SendByte(data);
		    fnSetPos(uRow+k,uCol+j);
			fnPR12(LC_AUT_WR);			// 写数据
			fnPR13(~data);
		    fnPR12(LC_AUT_OVR);
			
		    
		}
		//fnPR12(LC_AUT_OVR);
	}
	fnPR1(LC_ADD_POS,0x00,0x00);	// 重置地址指针
	gCurRow = 0;					// 置地址指针存储变量
	gCurCol = 0;

}
void DispBMP(uchar Xs, uchar Ys, uchar Xw, uchar Yh,const uchar *BMPdata)
{
   	uchar j,k,uLen,uRow,uCol;
	//uRow = fnGetRow();
	//uCol = fnGetCol();
	Xs = Xs>>3;
	Xw = Xw>>3;
	uCol = Xs;
	uRow = Ys;

    //LCM_GRAPH;
    for(k=0;k<Yh;k++)
	{
		fnSetPos(uRow+k,uCol);
		//BMPdata = BMPdata + k*Xw; 
		fnPR12(LC_AUT_WR);			// 写数据
		for (j=0;j<Xw;j++)
		{
			fnST3();
			fnPR13(*(BMPdata+j+k*Xw));
		}
		fnPR12(LC_AUT_OVR);
	}
	fnPR1(LC_ADD_POS,0x00,0x00);	// 重置地址指针
	gCurRow = 0;					// 置地址指针存储变量
	gCurCol = 0;

}

// ASCII(8*16)显示函数
uchar cprintf(uchar *fmt)
{
	uchar  c1,c2,cData;
	//char tmpBuf[64];				// LCD显示数据缓冲区
	uchar j,uLen,uRow,uCol;
	uchar i=0;
	uint  k;
	
	//LCM_GRAPH;
	while(*fmt != 0)
	{
		//c1 = tmpBuf[i];
		//c2 = tmpBuf[i+1];
		c1 = *fmt;
		uRow = fnGetRow();
		uCol = fnGetCol();
			if(c1 < 0x20)
			{
				switch(c1)
				{
					case CR:
						i++;
						fmt++;
						if(uRow < 112)
							fnSetPos(uRow+16,0);
						else
							fnSetPos(0,0);
						continue;
					case LF:		// 回车或换行
						i++;
						fmt++;
						if(uRow < 112)
							fnSetPos(uRow+16,0);
						else
							fnSetPos(0,0);
						continue;
						////break;
					case BS:		// 退格
						if(uCol > 0)
							uCol--;
						fnSetPos(uRow,uCol);
						cData = 0x00;
						break;
					default:		// 其他
						c1 = 0x1f;
				}
			}
			for(j=0;j<16;j++)
			{
				fnSetPos(uRow+j,uCol);
				fnPR12(LC_AUT_WR);		// 写数据
				if(c1 >= 0x1f)
				{
					if(j < (16-ASC_CHR_HEIGHT))
						fnPR13(0x00);
					else
						fnPR13(ASC_MSK[(c1-0x1f)*ASC_CHR_HEIGHT+j-(16-ASC_CHR_HEIGHT)]);
				}
				else
					fnPR13(cData);
				fnPR12(LC_AUT_OVR);
				
			}
			if(c1 != BS)		// 非退格
				uCol++;
		

		if(uCol >= 30)			// 光标后移
		{
			uRow += 16;
			if(uRow < 0x80)
				uCol -= 30;
			else
			{
				uRow = 0;
				uCol = 0;
			}
		}
		fnSetPos(uRow,uCol);
		i++;
		fmt++;
	}
	return i;
}

// text mode ASCII(8*16)显示函数
uchar tcprintf(uchar *fmt)
{
	uchar  c1,c2,cData;
	//char tmpBuf[64];				// LCD显示数据缓冲区
	uchar j,uLen,uRow,uCol;
	uchar i=0;
	uint  k;
	
	//LCM_GRAPH;
	while(*fmt != 0)
	{
		//c1 = tmpBuf[i];
		//c2 = tmpBuf[i+1];
		c1 = *fmt;
		uRow = fnGetRow();
		uCol = fnGetCol();
			if(c1 < 0x20)
			{
				switch(c1)
				{
					case CR:
						i++;
						fmt++;
						if(uRow < 112)
							fnSetPos(uRow+16,0);
						else
							fnSetPos(0,0);
						continue;
					case LF:		// 回车或换行
						i++;
						fmt++;
						if(uRow < 112)
							fnSetPos(uRow+16,0);
						else
							fnSetPos(0,0);
						continue;
						////break;
					case BS:		// 退格
						if(uCol > 0)
							uCol--;
						fnSetPos(uRow,uCol);
						cData = 0x00;
						break;
					default:		// 其他
						c1 = 0x1f;
				}
			}
			
			//for(j=0;j<16;j++)
			{
				fnSetPos(uRow+j,uCol);
				fnPR12(LC_AUT_WR);		// 写数据
				if(c1 >= 0x1f)
				{
					if(j < (16-ASC_CHR_HEIGHT))
						fnPR13(0x00);
					else
						fnPR13(ASC_MSK[(c1-0x1f)*ASC_CHR_HEIGHT+j-(16-ASC_CHR_HEIGHT)]);
				}
				else
					fnPR13(cData);
				fnPR12(LC_AUT_OVR);
				
			}
			if(c1 != BS)		// 非退格
				uCol++;
		

		if(uCol >= 30)			// 光标后移
		{
			uRow += 16;
			if(uRow < 0x80)
				uCol -= 30;
			else
			{
				uRow = 0;
				uCol = 0;
			}
		}
		fnSetPos(uRow,uCol);
		i++;
		fmt++;
	}
	return i;
}

⌨️ 快捷键说明

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