www.pudn.com > GKC-DProteus.rar > T6963.c, change:2008-09-11,size:13073b


 
/************************************************************************************/ 
/* LCM 240128 显示程序 */ 
/* MCU 型号: Winbond W78E58-24 */ 
/* 时钟频率: 22.1184 MHz */ 
/* 接口方式: 直接接口(挂总线) */ 
/* 开发环境: Keil C51 V6.14 */ 
/* 开发日期: 2001.06.12- */ 
/* 程序编写: Youth */ 
/************************************************************************************/ 
 
#include <stdarg.h> 
#include <stdio.h> 
#include <math.h> 
#include <intrins.h> 
#include <absacc.h> 
#include <string.h> 
#include <T6963.h> 
#include <zk16.h> 
 
code uchar const uPowArr[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; 
 
// ASCII 字模宽度及高度定义 
#define ASC_CHR_WIDTH 8 
#define ASC_CHR_HEIGHT 16 
#define HZ_CHR_HEIGHT 16 
#define HZ_CHR_WIDTH 16 
 
char code MSK1[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; 
char code MSK2[]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; 
 
uchar gCurRow,gCurCol; // 图形当前行、列存储,行高16点,列宽8点 
uchar tCurRow,tCurCol; // 文本当前行、列存储,行高8点 ,列宽8点 
uchar ShowModeSW; // 当前显示模式 
uint txthome,grhome; 
 
/******************************************************************************/ 
uchar lcdGetRow(); 
uchar lcdGetCol(); 
uchar lcdST01(); // 状态位STA1,STA0判断(读写指令和读写数据) 
uchar lcdST2(); // 状态位ST2判断(数据自动读状态) 
uchar lcdST3(); // 状态位ST3判断(数据自动写状态) 
uchar lcdST6(); // 状态位ST6判断(屏读/屏拷贝状态) 
uchar lcdPR1(uchar uCmd,uchar uPar1,uchar uPar2); // 写双参数的指令 
uchar lcdPR11(uchar uCmd,uchar uPar1); // 写单参数的指令 
uchar lcdPR12(uchar uCmd); // 写无参数的指令 
uchar lcdPR13(uchar uData); // 写数据 
uchar lcdPR2(); // 读数据 
void lcdSetPos(uchar urow, uchar ucol);	// 设置当前地址 
void cursor(uchar uRow, uchar uCol); 	//设置当前显示行、列 
void lcd_at(unsigned char x,unsigned char y);/*设定文本x,y值*/ 
void lcd_clear();	 // 清屏 
char lcd_init(); // LCM 初始化 
void charout(uchar *str); //ASCII(8*8) 显示函数 
uchar lcd_strdisp(uchar x,uchar y,char *fmt);// ASCII(8*16) 及 汉字(16*16) 显示函数 
void OutToLCD(uchar Dat,uchar x,uchar y);//显示辅助函数  
 
void SetShowMode(uchar newShowModeSW);	 
void lcd_line( unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, bit Mode); 
void Pixel(unsigned char PointX,unsigned char PointY, bit Mode); 
 
uchar lcdGetRow(void) 
{ 
	return gCurRow; 
} 
 
uchar lcdGetCol(void) 
{ 
	return gCurCol; 
} 
 
uchar lcdST01(void) // 状态位STA1,STA0判断(读写指令和读写数据) 
{ 
	uchar i; 
	 
	for(i=10;i>0;i--) 
	{ 
		if((LCMCW & 0x03) == 0x03) 
		break; 
	} 
	return i; // 若返回零,说明错误 
} 
 
uchar lcdST2(void) // 状态位ST2判断(数据自动读状态) 
{ 
	uchar i; 
	 
	for(i=10;i>0;i--) 
	{ 
		if((LCMCW & 0x04) == 0x04) 
		break; 
	} 
	return i; // 若返回零,说明错误 
} 
 
uchar lcdST3(void) // 状态位ST3判断(数据自动写状态) 
{ 
	uchar i; 
	 
	for(i=10;i>0;i--) 
	{ 
		if((LCMCW & 0x08) == 0x08) 
		break; 
	} 
	return i; // 若返回零,说明错误 
} 
 
uchar lcdST6(void) // 状态位ST6判断(屏读/屏拷贝状态) 
{ 
	uchar i; 
	 
	for(i=10;i>0;i--) 
	{ 
		if((LCMCW & 0x40) == 0x40) 
		break; 
	} 
	return i; // 若返回零,说明错误 
} 
 
uchar lcdPR1(uchar uCmd,uchar uPar1,uchar uPar2) // 写双参数的指令 
{ 
	if(lcdST01() == 0) 
	return 1; 
	LCMDW = uPar1; 
	if(lcdST01() == 0) 
	return 2; 
	LCMDW = uPar2; 
	if(lcdST01() == 0) 
	return 3; 
	LCMCW = uCmd; 
	return 0; // 返回0成功 
} 
 
uchar lcdPR11(uchar uCmd,uchar uPar1) // 写单参数的指令 
{ 
	if(lcdST01() == 0) 
	return 1; 
	LCMDW = uPar1; 
	if(lcdST01() == 0) 
	return 2; 
	LCMCW = uCmd; 
	return 0; // 返回0成功 
} 
 
uchar lcdPR12(uchar uCmd) // 写无参数的指令 
{ 
	if(lcdST01() == 0) 
	return 1; 
	LCMCW = uCmd; 
	return 0; // 返回0成功 
} 
 
uchar lcdPR13(uchar uData) // 写数据 
{ 
	if(lcdST3() == 0) 
	return 1; 
	LCMDW = uData; 
	return 0; // 返回0成功 
} 
 
uchar lcdPR2(void) // 读数据 
{ 
	if(lcdST01() == 0) 
	return 1; 
	return LCMDW; 
} 
 
 
void lcdSetPos(uchar urow, uchar ucol)	//设置当前地址 
{ 
	uint iPos; 
	 
	iPos = urow * 20 + ucol; 
	lcdPR1(LC_ADD_POS,iPos & 0xFF,iPos / 256); 
	gCurRow = urow; 
	gCurCol = ucol; 
} 
 
void cursor(uchar uRow, uchar uCol) 	//设置当前显示行、列 
{ 
	lcdSetPos(uRow * 16, uCol); 
} 
void lcd_at(unsigned char x,unsigned char y)/*设定文本x,y值*/ 
{	 
	uint iPos; //地址 
	 
	iPos = x  + y* 20; 
	lcdPR1(LC_ADD_POS,iPos&0xff,iPos/256); 
	tCurRow = x; 
	tCurCol = y; 
} 
 
// 清屏 
void lcd_clear(void) 
{ 
	uint i; 
	 
	lcdPR1(LC_ADD_POS,0x00,0x00); // 置地址指针 
	lcdPR12(LC_AUT_WR); // 自动写 
	for(i=0;i<0x2000;i++) 
	{ 
		lcdST3(); 
		lcdPR13(0x00); // 写数据 
	} 
	lcdPR12(LC_AUT_OVR); // 自动写结束 
	lcdPR1(LC_ADD_POS,0x00,0x00); // 重置地址指针 
	gCurRow = 0; // 置地址指针存储变量 
	gCurCol = 0; 
} 
// 清屏 
void lcd_poson(uchar npos) 
{ 
/*	uint i; 
 
	lcdPR1(LC_ADD_POS,0x00,0x00); // 置地址指针 
	lcdPR12(LC_AUT_WR); // 自动写 
	for(i=0;i<0x2000;i++) 
	{ 
		lcdST3(); 
		lcdPR13(0x00); // 写数据 
	} 
	lcdPR12(LC_AUT_OVR); // 自动写结束 
	lcdPR1(LC_ADD_POS,0x00,0x00); // 重置地址指针 
	gCurRow = 0; // 置地址指针存储变量 
	gCurCol = 0; 
	*/ 
	lcdPR1(0x21,npos,3); 
	lcdPR12(0x9B); 
} 
 
 // 清屏 
void lcd_posoff(uchar npos) 
{ 
 
	lcdPR12(0x98); 
} 
// LCM 初始化 
char lcd_init(void) 
{ 
	//RST=0; 
	//RST=1; 
	lcdPR1(LC_TXT_STP,0x00,0x00); // 文本显示区首地址 
	lcdPR1(LC_TXT_WID,0x14,0x00); // 文本显示区宽度 
	lcdPR1(LC_GRH_STP,0x00,0x00); // 图形显示区首地址 
	lcdPR1(LC_GRH_WID,0x14,0x00); // 图形显示区宽度 
	lcdPR11(LC_CGR_POS,CGRAMSTART >> 11); 
	lcdPR12(LC_CUR_SHP | 0x01); // 光标形状 
	lcdPR12(LC_MOD_OR); // 显示方式设置 
	lcdPR12(LC_DIS_SW |0x08); 
	grhome = GRSTART; 
    txthome = TXTSTART; 
 
	return 0; 
} 
void charout(uchar *str) 
{ 
    uchar ch,len,i,uRow,uCol ; 
    len=strlen(str); 
    i=0; 
    uRow = tCurRow; 
    uCol = tCurRow; 
    lcd_at(uCol,uRow); 
    while(i<len) 
    { 
        ch=str[i]-0x20; 
        lcdPR11(LC_INC_WR,ch); 
        i++; 
    } 
}  
void lcd_chardisp(uchar x,uchar y,char  ndat) 
{ 
  uchar j,cData; 
  lcdSetPos(y,x/8); 
		if(ndat >= 0) 
		{ 
		 for(j=0;j<ASC_CHR_HEIGHT;j++) 
		    { 
		         
		        if(ndat >= 0x00) 
		        { 
				   	cData= ASC_MSK[(ndat-0x1f)*ASC_CHR_HEIGHT+j]; 
					lcdSetPos(y+j,x/8); 
					if((x%8)==0) 
					{ 
						lcdPR12(LC_AUT_WR); // 写数据 
			           	lcdPR13(cData);	 
			        	lcdPR12(LC_AUT_OVR); 
					} 
					else 
						OutToLCD(cData,x,y+j); 
		        } 
		        lcdSetPos(y+j,x/8); 
		    } 
		    if(ndat != BS) // 非退格 
		    x+=ASC_CHR_WIDTH; 
		} 
} 
// ASCII及汉字显示函数 
 
uchar lcd_strdisp(uchar x,uchar y,char *fmt) 
{ 
	char c1,c2,cData; 
	uchar i=0,j,uLen; 
	uchar k; 
	 
	uLen=strlen(fmt); 
 
	while(i<uLen) 
	{ 
		c1 = fmt[i]; 
		c2 = fmt[i+1]; 
		 
		lcdSetPos(y,x/8); 
		if(c1 >= 0) 
		{ 
		 // ASCII 
		    if(c1 < 0x20) 
		    { 
		        switch(c1) 
		        { 
		            case CR: 
		            case LF: // 回车或换行 
		                i++; 
						x=0; 
		                if(y < 112)y+=HZ_CHR_HEIGHT; 
		                continue; 
		            case BS: // 退格 
						i++; 
		                if(y>ASC_CHR_WIDTH)y-=ASC_CHR_WIDTH; 
		                cData = 0x00; 
		                break; 
				   //default:break; 
 
		        } 
		    }  
		    for(j=0;j<ASC_CHR_HEIGHT;j++) 
		    { 
		         
		        if(c1 >= 0x20) 
		        { 
				   	cData= ASC_MSK[(c1-0x1f)*ASC_CHR_HEIGHT+j]; 
					lcdSetPos(y+j,x/8); 
					if((x%8)==0) 
					{ 
						lcdPR12(LC_AUT_WR); // 写数据 
			           	lcdPR13(cData);	 
			        	lcdPR12(LC_AUT_OVR); 
					} 
					else 
						OutToLCD(cData,x,y+j); 
		        } 
		        lcdSetPos(y+j,x/8); 
		    } 
		    if(c1 != BS) // 非退格 
		    x+=ASC_CHR_WIDTH; 
		} 
		else 
		{ // 中文 
			 
		    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<HZ_CHR_HEIGHT;k++) 
		    { 
				 
		        lcdSetPos(y+k,x/8); 
		        if(j < sizeof(GB_16)/sizeof(GB_16[0])) 
		        { 
					c1=GB_16[j].Msk[k*2]; 
					c2=GB_16[j].Msk[k*2+1]; 
				} 
				else	    
					c1=c2=0; 
				if((x%8)==0) 
				{ 
					lcdPR12(LC_AUT_WR); 
					lcdPR13(c1); 
			        lcdPR12(LC_AUT_OVR); 
		        } 
				else 
					OutToLCD(c1,x,y+k); 
				 
				if(((x+2+HZ_CHR_WIDTH/2)%8)==0) 
				{ 
					lcdPR12(LC_AUT_WR); 
					lcdPR13(c2); 
					lcdPR12(LC_AUT_OVR); 
		        } 
				else 
					OutToLCD(c2,x+HZ_CHR_WIDTH/2,y+k); 
		    } 
		    x+=HZ_CHR_WIDTH; 
		    i++; 
		}   
		i++; 
	} 
	return uLen; 
} 
void OutToLCD(uchar Dat,uchar x,uchar y)  
{ 
	uchar uData1,uData2,ux,a,b; 
 
	a=8-(x%8);b=x%8; 
	lcdSetPos(y,x/8); 
	lcdPR12(LC_AUT_RD); // 读数据 
	uData1=lcdPR2(); 
	uData2=lcdPR2(); 
	lcdPR12(LC_AUT_OVR); 
	lcdSetPos(y,x/8); 
	uData1&=~MSK1[a]; 
	ux=Dat&MSK2[a]; 
	ux>>=b; 
	uData1=uData1|ux; 
	ux=~MSK2[b]; 
	uData2&=ux; 
	ux=MSK1[b]; 
	ux=Dat&ux; 
	ux<<=a; 
	uData2=uData2|ux; 
	lcdPR12(LC_AUT_WR); // 写数据 
   	lcdPR13(uData1);	 
	lcdPR13(uData2); 
	lcdPR12(LC_AUT_OVR); 
 
} 
void SetShowMode(uchar newShowModeSW)	 //设置为显示模式 
{ 
	ShowModeSW=newShowModeSW; 
	lcdPR12(LC_DIS_SW | newShowModeSW); 
} 
 
/********************************** 
//= 函数原型: Pixel(unsigned char PointX,unsigned char PointY, bit Mode) 
//= 功    能: 在指定坐标位置显示一个点 
//= 参    数: 坐标,显示点或清除点 
//= 返 回 值: 
//= 函数性质:私有函数 
//= 如果显示屏超过了256*256,请修改这个函数 PointX,PointY的类型 
//= Mode 1:显示 0:清除该点 
**********************************/ 
void Pixel(unsigned char PointX,unsigned char PointY, bit Mode) 
{ 
    unsigned char StartAddr; 
    unsigned char dat; 
    StartAddr=7-(PointX%8); 
    dat=LC_BIT_OP|StartAddr; //生产位操作命令画点的数据 
    if(Mode) dat=dat|0x08; 
	lcdSetPos(PointY,PointX/8); 
	lcdPR12(LC_BIT_OP|dat); // 写数据 
} 
 
 
/********************************** 
//= 函数原型: void lcd_line( unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, bit Mode) 
//= 功    能: 划线函数 
//= 参    数: 坐标1,坐标2,显示点或清除点 
//= 返 回 值: 
//= 函数性质:私有函数 
//= 其它:显示点阵不超过255*255 
/**********************************/ 
 
void showmenu(uchar *pmenu) 
{ uchar *p; 
  p=pmenu; 
  lcd_clear(); 
  lcd_strdisp(8,0, p); 
  lcd_strdisp(8,16,p+0x10); 
  lcd_strdisp(8,32,p+0x20); 
  lcd_strdisp(8,48,p+0x30); 
} 
//**********清除光标子程序*********************  
void lcd_curclr(uchar nlcd_line)  
{ 
	switch(nlcd_line) 
	{ 
	  case 1: lcd_strdisp(0,0," "); break; 
	  case 2: lcd_strdisp(0,16," "); break; 
	  case 3: lcd_strdisp(0,32," "); break; 
	  case 4: lcd_strdisp(0,48," "); break; 
	} 
//	lcd_dataw(0x20); 
} 
//**********显示光标子程序*********************  
void lcd_curset(uchar nlcd_line)  
{ 
	switch(nlcd_line) 
	{ 
	  case 1: lcd_strdisp(0,0,">"); break; 
	  case 2: lcd_strdisp(0,16,">"); break; 
	  case 3: lcd_strdisp(0,32,">"); break; 
	  case 4: lcd_strdisp(0,48,">"); break; 
	} 
	 
	//lcd_dataw(0x10); 
} 
//**********光标下移子程序*********************  
uchar lcd_curdown(uchar nlcd_line)  
{ 
  lcd_curclr(nlcd_line);nlcd_line++; 
  if(nlcd_line>4) nlcd_line=1; 
  lcd_curset(nlcd_line); 
   return nlcd_line; 
}				  	  
//**********光标上移子程序*********************  
uchar lcd_curup(uchar nlcd_line)  
{ 
  lcd_curclr(nlcd_line);nlcd_line--; 
  if(nlcd_line<1) nlcd_line=4; 
  lcd_curset(nlcd_line); 
  return nlcd_line; 
 }				  	  
 //**********显示位置子程序*********************  
//void lcd_poson(uchar npos)  
//{ 
	//lcd_comdw(npos|0x80); 
	//lcd_comdw(0x0f); 
//} 
//**********显示位置子程序*********************  
//void lcd_posoff()  
//{ 
	//lcd_comdw(npos|0x80); 
	//lcd_comdw(0x0c); 
//} 
void lcd_bmpdisp(uchar XSIZE,uchar YSIZE,const  uchar  * nbmp) 
{ 
  uchar k,i,j; 
  k=0; 
 	for(i=0;i<YSIZE;i++) 
    { 
      lcdSetPos(k,0);k++; 
      lcdPR12(LC_AUT_WR); // 写数据 
      for(j=0;j<XSIZE/8;j++) 
      lcdPR13(nbmp[i*(XSIZE/8)+j+2]); 
      lcdPR12(LC_AUT_OVR); 
    } 
				 
 } 
void lcd_line( unsigned char x1,unsigned char y1, unsigned char x2,unsigned char y2,  bit Mode) 
{ 
    unsigned char x,y; 
    float k,b; 
	//y2=(y2>y1?y2:y1); 
	//y1=(y1<y2?y1:y2); 
    if( abs(y1-y2) <= abs(x1-x2) ) // |k|<=1 
    { 
        k=((float)y2-y1) / ((float)x2-x1) ; 
        b=y1-k*x1; 
        if( x1 <= x2 ) 
        { 
            for(x=x1;x<=x2;x++) 
            { 
                y=(uchar)(k*x+b); 
                Pixel(x, y, Mode); 
            } 
        } 
        else 
        { 
            for(x=x2;x<=x1;x++) 
            { 
                y=(uchar)(k*x+b); 
                Pixel(x, y, Mode); 
            } 
        } 
    } 
    else // abs(y1-y2) > abs(x1-x2) |K|>1 
    { 
        k=((float)x2-x1) / ((float)y2-y1) ; 
        b=x1-k*y1; 
        if( y1 <= y2 ) 
        { 
            for(y=y1;y<=y2;y++) 
            { 
                x=(uchar)(k*y+b); 
                Pixel( x , y,Mode ); 
            } 
        } 
        else 
        { 
            for(y=y2;y<=y1;y++) 
            { 
                x=(uchar)(k*y+b); 
                Pixel( x , y,Mode ); 
            } 
        } 
    } 
}