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

📄 lcddrv.c

📁 各种器件的驱动程序
💻 C
字号:
/*	LCD128x64显示接口函数
	魏东 2004-11-22 10:08'
*/
#include "def_port.h"
#define __SRC
#include "lcddrv.h"
#undef	__SRC
#if lcd_put_en8x8_en
#include "en8x8.h"
#endif
#if lcd_put_ch12x12_en
#include "ch12x12.h"	/* 12x12点阵汉字库,如果不使用,至少保留1个作空显示 */
#endif
#if lcd_put_ch16x16_en
#include "ch16x16.h"	/* 16x16点阵汉字库,如果不使用,至少保留1个作空显示 */
#endif
#if lcd_put_ch24x24_en
#include "ch24x24.h"	/* 24x24点阵汉字库,如果不使用,至少保留1个作空显示 */
#endif
/***********************************************************************************/

/* LCD复位 */
#if lcd_reset_en
void lcd_reset(void)
{	unsigned int ui;

	L_RST = 0;				/* 复位 */
	for(ui=0;ui<LCD_RST_DELAY;ui++) ;	/* 等待25mS */
	L_RST = 1;				/* 工作 */
	for(ui=0;ui<LCD_RST_DELAY;ui++) ;	/* 等待25mS */
	lcd_fill(0);				/* 清除显示数据 */
	lcd_x=0;
	lcd_y=0;
	_ch_id=0;
}
#endif

/* LCD开显示 */
#if lcd_on_en
void lcd_on(void)
{
	LCD_STA_SET2CS12;
	*LCD_STA=0x3f;
}
#endif

/* LCD关显示 */
#if lcd_off_en
void lcd_off(void)
{
	LCD_STA_SET2CS12;
	*LCD_STA=0x3e;
}
#endif

/* LCD显示滚卷 */
#if lcd_roll_en
void lcd_roll(unsigned char uc)
{
	LCD_STA_SET2CS12;
	*LCD_STA=(uc&0x3f)|0xc0;
}
#endif

/* 填充全屏LCD数据 */
#if lcd_fill_en
void lcd_fill(unsigned char cdt)
{	unsigned char ccy,cci;

	LCD_STA_SET2CS12;
	LCD_DAT_SET2CS12;
	for(ccy=0;ccy<8;ccy++)
	{	*LCD_STA=ccy|0xb8;	/* Y坐标(x地址) */
		*LCD_STA=0x40;	/* X坐标(y地址) */
		for(cci=0;cci<64;cci++)
		{	*LCD_DAT=cdt;	/* 数据 */
		}
	}
	lcd_on();	/* LCD开显示 */
	lcd_x=0;
	lcd_y&=0xe0;
	_ch_id=0;
	return;
}
#endif

/* 填充LCD数据(x坐标列,y低4位是坐标行(4点为1行)|高4位是填充数据,i填充列数) */
#if lcd_fill_xy_en
void lcd_fill_xy(unsigned char ccx,unsigned char ccy,unsigned char cci)
{	unsigned char ccc;
	
	if((ccx+cci)>128) cci=128-ccx;
	cci=ccx+cci;
	for(;ccx<cci;ccx++)
	{	if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
		{	LCD_STA_SET2CS2;
			LCD_DAT_SET2CS2;
		}
		else
		{	LCD_STA_SET2CS1;
			LCD_DAT_SET2CS1;
		}
		/* 将原屏幕数据读出 */
		LCD_STA = (ccx&0x3f)|0x40;		/* X坐标(y地址) */
		LCD_STA = ((ccy>>1)&0x07)|0xb8;		/* Y坐标(x地址) */
		ccc = * LCD_DAT;			/* 读数据 */
		LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址)(读完了y地址要自动加因此将y地址设回原来的值) */
		if(ccy&1) LCD_DAT = (ccc&0x0f)|(ccy&0xf0);	/* 奇数行(下半整行) */
		else LCD_DAT = (ccc&0xf0)|((ccy>>4)&0x0f);	/* 偶数行(上半整行) */
	}
}
#endif

/* 选择LCD显示行高(最高位设置是否翻黑显示,其他位0:8;1:12;2:16;3:24) */
#if lcd_set_chlib_en
void lcd_set_chlib(unsigned char cch)
{
	lcd_y = (lcd_y&0x0f)|((cch<<5)&0x60)|(cch&0x80);
}
#endif

/* 设置当前LCD显示位置 */
#if lcd_moveto_en
void lcd_moveto(unsigned char ccx,unsigned char ccy)
{
	lcd_x = ccx;
	lcd_y = (lcd_y&0xe0) | (ccy&0x1f);
	_ch_id=0;
}
#endif

/* LCD显示/清除一个点 */
#if lcd_dot_en
void lcd_dot(unsigned char ccx,unsigned char ccy,unsigned char dot)
{	unsigned char ccc;

	if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
	{	LCD_STA_SET2CS2;
		LCD_DAT_SET2CS2;
	}
	else
	{	LCD_STA_SET2CS1;
		LCD_DAT_SET2CS1;
	}
	/* 将原屏幕数据读出 */
	*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址) */
	*LCD_STA = ((ccy>>3)&0x07)|0xb8;	/* Y坐标(x地址) */
	ccc = *LCD_DAT;		/* 读数据 */
	ccc = *LCD_DAT;		/* 读数据 */
	*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址)(读完了y地址要自动加因此将y地址设回原来的值) */
	if(dot) *LCD_DAT = ccc|(1<<(ccy&7));		/* 数据(显示) */
	else *LCD_DAT = ccc&((1<<(ccy&7))^0xff);	/* 数据(清除) */
}
#endif

/* LCD显示发送一字符 */
#if lcd_putchar_en
char lcd_putchar (unsigned char c)
{	unsigned char uc;

	lcd_y &= 0xef;	/* lcd_y最大0f(4*16=64点) */
	if(_ch_code)	/* 已有汉字第1字节,加第2字节后显示 */
	{	_ch_id=1;
		_ch_code = _ch_code + c;
		if((lcd_y&0x60)==0x60)		/* 24点阵汉字 */
		{	if(lcd_x > 104)
			{	lcd_x = 0;
				lcd_y +=6 ;
			}
#if lcd_put_ch24x24_en
			lcd_put_ch24x24(lcd_x,lcd_y,_ch_code);
#endif
			lcd_x += 24;
		}
		else if((lcd_y&0x60)==0x40)	/* 16点阵汉字 */
		{	if(lcd_x > 112)
			{	lcd_x = 0;
				lcd_y += 4;
			}
#if lcd_put_ch16x16_en
			lcd_put_ch16x16(lcd_x,lcd_y,_ch_code);
#endif
			lcd_x += 16;
		}
		else				/* 12点阵汉字 */
		{	if(lcd_x > 116)
			{	lcd_x = 0;
				lcd_y += 3;
			}
#if lcd_put_ch12x12_en
			lcd_put_ch12x12(lcd_x,lcd_y,_ch_code);
#endif
			lcd_x += 12;
		}
		_ch_code=0;
		return 2;
	}
	else		/* 这是第1字节 */
	{	if(c&0x80)
		{	_ch_code = c*256;	/* 汉字第1字节 */
			return 0;
		}
		else			/* 8点阵字母 */
		{	if((lcd_x>120)||(c=='\n'))
			{	if((lcd_y&0x60)==0x60) lcd_y += 6;		/* 24点一行 */
				else if((lcd_y&0x60)==0x40) lcd_y += 4;		/* 16点一行 */
				else if((lcd_y&0x60)==0x20) lcd_y += 3;		/* 12点一行 */
				else if(_ch_id) lcd_y += 3;			/* 本来是8点一行显了汉字按12点一行 */
				else lcd_y += 2;				/* 8点一行 */
				lcd_x = 0;
				_ch_id=0;					/* 换行后清有汉字标志 */
				if(c=='\n') return 1;
			}
			if(c=='\r')
			{	lcd_x=0;
				return 1;
			}
#if lcd_put_en8x8_en
			if(lcd_y&0x80) uc=0xf0;		/* 空的填黑 */
			else uc=0x00;			/* 空的填白 */
			if((lcd_y&0x60)==0x60)
			{	lcd_fill_xy(lcd_x,(lcd_y&0x0f)|uc,8);		/* 空的填充 */
				lcd_fill_xy(lcd_x,((lcd_y+1)&0x0f)|uc,8);	/* 空的填充 */
				lcd_put_en8x8(lcd_x,lcd_y+2,c);			/* 24点阵中下移2行(8点) */
				lcd_fill_xy(lcd_x,((lcd_y+4)&0x0f)|uc,8);	/* 空的填充 */
				lcd_fill_xy(lcd_x,((lcd_y+5)&0x0f)|uc,8);	/* 空的填充 */
			}
			else if(lcd_y&0x60)
			{	lcd_fill_xy(lcd_x,(lcd_y&0x0f)|uc,8);		/* 空的填充 */
				lcd_put_en8x8(lcd_x,lcd_y+1,c);			/* 16/12点阵中下移1行(4点) */
				if((lcd_y&0x60)==0x40) lcd_fill_xy(lcd_x,((lcd_y+3)&0x0f)|uc,8);	/* 空的填充 */
			}
			else lcd_put_en8x8(lcd_x,lcd_y,c);			/* 8点阵 */
#endif
			lcd_x+=8;
			return 1;
		}
	}
}
#endif

/* 显示一个8x8英文字符 */
#if lcd_put_en8x8_en
void lcd_put_en8x8(unsigned char x,unsigned char y,unsigned char en)
{	
	en&=0x7f;
	if(en<0x20) en=0x20;
	en -= 0x20;
	if(y&0x01)	/* 一半的地方开始的 100低半作低半 101低半作高半 110高半作低半 111高半作高半 */
	{	lcd_put(x,(y/2)|(y&0x80),&enlib_dat[en][0],8|0xa0);		/* 使用数据的低半作高半显示 */
		lcd_put(x,(y/2+1)|(y&0x80),&enlib_dat[en][0],8|0xc0);	/* 使用数据的高半作低半显示 */
	}
	else	lcd_put(x,(y/2)|(y&0x80),&enlib_dat[en][0],8);
}
#endif

/* 显示一个12x12点阵汉字 */
#if lcd_put_ch12x12_en
void lcd_put_ch12x12(unsigned char x,unsigned char y,unsigned int ch)
{	unsigned char ci;
					/* 在字库中查找汉字 */
	for(ci=0;ci<ch12x12_num;ci++) if(ch12x12_code[ci]==ch) break;
	if(ci>=ch12x12_num) ci=0;	/* 没有找到0总是全空 */
	if(y&0x01)	/* 一半的地方开始的 100低半作低半 101低半作高半 110高半作低半 111高半作高半 */
	{	lcd_put(x,(y/2)|(y&0x80),&ch12x12_dat[ci][0],12|0xa0);		/* 使用数据的低半作高半显示 */
		lcd_put(x,(y/2+1)|(y&0x80),&ch12x12_dat[ci][0],12|0xc0);		/* 使用数据的高半作低半显示 */
		lcd_put(x,(y/2+1)|(y&0x80),&ch12x12_dat[ci][12],6|0xa0);		/* 使用数据的低半作高半显示 */
		lcd_put(x+6,(y/2+1)|(y&0x80),&ch12x12_dat[ci][12],6|0xe0);	/* 使用数据的高半作高半显示 */
	}
	else
	{	lcd_put(x,(y/2)|(y&0x80),&ch12x12_dat[ci][0],12);
		lcd_put(x,(y/2+1)|(y&0x80),&ch12x12_dat[ci][12],6|0x80);		/* 使用数据的低半作低半显示 */
		lcd_put(x+6,(y/2+1)|(y&0x80),&ch12x12_dat[ci][12],6|0xc0);	/* 使用数据的高半作低半显示 */
	}
}
#endif

/* 显示一个24x24点阵汉字 */
#if lcd_put_ch24x24_en
void lcd_put_ch24x24(unsigned char x,unsigned char y,unsigned int ch)
{	unsigned char ci;
					/* 在字库中查找汉字 */
	for(ci=0;ci<ch24x24_num;ci++) if(ch24x24_code[ci]==ch) break;
	if(ci>=ch24x24_num) ci=0;	/* 没有找到0总是全空 */
	if(y&0x01)	/* 一半的地方开始的 100低半作低半 101低半作高半 110高半作低半 111高半作高半 */
	{	lcd_put(x,(y/2)|(y&0x80),&ch24x24_dat[ci][0],24|0xa0);	/* 使用数据的低半作高半显示 */
		lcd_put(x,(y/2+1)|(y&0x80),&ch24x24_dat[ci][0],24|0xc0);	/* 使用数据的高半作低半显示 */
		lcd_put(x,(y/2+1)|(y&0x80),&ch24x24_dat[ci][24],24|0xa0);	/* 使用数据的低半作高半显示 */
		lcd_put(x,(y/2+2)|(y&0x80),&ch24x24_dat[ci][24],24|0xc0);	/* 使用数据的高半作低半显示 */
		lcd_put(x,(y/2+2)|(y&0x80),&ch24x24_dat[ci][48],24|0xa0);	/* 使用数据的低半作高半显示 */
		lcd_put(x,(y/2+3)|(y&0x80),&ch24x24_dat[ci][48],24|0xc0);	/* 使用数据的高半作低半显示 */
	}
	else
	{	lcd_put(x,(y/2)|(y&0x80),&ch24x24_dat[ci][0],24);
		lcd_put(x,(y/2+1)|(y&0x80),&ch24x24_dat[ci][24],24);
		lcd_put(x,(y/2+2)|(y&0x80),&ch24x24_dat[ci][48],24);
	}
}
#endif

/* 显示一个16x16点阵汉字 */
#if lcd_put_ch16x16_en
void lcd_put_ch16x16(unsigned char x,unsigned char y,unsigned int ch)
{	unsigned char ci;
					/* 在字库中查找汉字 */
	for(ci=0;ci<ch16x16_num;ci++) if(ch16x16_code[ci]==ch) break;
	if(ci>=ch16x16_num) ci=0;	/* 没有找到0总是全空 */
	else	/* 16点阵汉字 */
	{	if(y&0x01)	/* 一半的地方开始的 100低半作低半 101低半作高半 110高半作低半 111高半作高半 */
		{	lcd_put(x,(y/2)|(y&0x80),&ch16x16_dat[ci][0],16|0xa0);	/* 使用数据的低半作高半显示 */
			lcd_put(x,(y/2+1)|(y&0x80),&ch16x16_dat[ci][0],16|0xc0);	/* 使用数据的高半作低半显示 */
			lcd_put(x,(y/2+1)|(y&0x80),&ch16x16_dat[ci][16],16|0xa0);	/* 使用数据的低半作高半显示 */
			lcd_put(x,(y/2+2)|(y&0x80),&ch16x16_dat[ci][16],16|0xc0);	/* 使用数据的高半作低半显示 */
		}
		else
		{	lcd_put(x,(y/2)|(y&0x80),&ch16x16_dat[ci][0],16);
			lcd_put(x,(y/2+1)|(y&0x80),&ch16x16_dat[ci][16],16);
		}
	}
}
#endif

/* 写LCD显示 */
#if lcd_put_en
void lcd_put(unsigned char ccx,unsigned char ccy,unsigned char *cdt,unsigned char cclen)
{	unsigned char cci,ccc;

	if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
	{	LCD_STA_SET2CS2;
		LCD_DAT_SET2CS2;
	}
	else
	{	LCD_STA_SET2CS1;
		LCD_DAT_SET2CS1;
	}
	*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址) */
	*LCD_STA = (ccy&0x07)|0xb8;	/* Y坐标(x地址) */
	for(cci=0;cci<(cclen&0x1f);cci++)
	{	if(cclen&0x80)	/* 只使用数据的半字节,需要将原屏幕数据读出 */
		{	*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址) */
			ccc = *LCD_DAT;		/* 读数据 */
			ccc = *LCD_DAT;		/* 读数据 */
			*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址)(读完了y地址要自动加因此将y地址设回原来的值) */
			if(ccy&0x80) ccc=ccc^0xff;	/* 要反显,读出数据先非 */
			if((cclen&0xe0)==0x80)		/* 100低半作低半 */
				ccc = (ccc&0xf0)|(cdt[cci]&0x0f);
			else if((cclen&0xe0)==0xa0)	/* 101低半作高半 */
				ccc = (ccc&0x0f)|((cdt[cci]&0x0f)<<4);
			else if((cclen&0xe0)==0xc0)	/* 110高半作低半 */
				ccc = (ccc&0xf0)|((cdt[cci]&0xf0)>>4);
			else				/* 111高半作高半 */
				ccc = (ccc&0x0f)|(cdt[cci]&0xf0);
		}
		else ccc=cdt[cci];
		if(ccy&0x80) *LCD_DAT = ccc^0xff;	/* P0口发数据 */
		else *LCD_DAT = ccc;
		ccx++;
		if((ccx&0x3f)==0)	/* 换左右半 */
		{	if((ccx&0x7f)==0) ccx=0x7f;	/* 超过不换行 */
			if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
			{	LCD_STA_SET2CS2;
				LCD_DAT_SET2CS2;
			}
			else
			{	LCD_STA_SET2CS1;
				LCD_DAT_SET2CS1;
			}
			*LCD_STA = (ccx&0x3f)|0x40;	/* x地址 */
			*LCD_STA = (ccy&0x07)|0xb8;	/* y地址 */
		}
	}
}
#endif

/* 写LCD数据 */
#if lcd_write_en
void lcd_write(unsigned char ccx,unsigned char ccy,unsigned char *cdt,unsigned char cclen)
{	unsigned char cci;

	if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
	{	LCD_STA_SET2CS2;
		LCD_DAT_SET2CS2;
	}
	else
	{	LCD_STA_SET2CS1;
		LCD_DAT_SET2CS1;
	}
	if(ccy&0x80)		/* 根据Y坐标bit7决定是写数据还是状态 */
	{	if(cdt[0]&0x80)
			*LCD_STA = (cdt[0]&0x01)|0x3e;	/* 开关显示 */
		else
			*LCD_STA = cdt[0]|0xc0;		/* 数据卷滚 */
	}
	else
	{	*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址) */
		*LCD_STA = (ccy&0x07)|0xb8;	/* Y坐标(x地址) */
		for(cci=0;cci<cclen;cci++)
		{	*LCD_DAT = cdt[cci];	/* P0口发数据 */
			ccx++;
			if((ccx&0x3f)==0)	/* 换左右半 */
			{	if((ccx&0x7f)==0)	/* 换行 */
				{	ccy++;		/* Y坐标加1 */
					ccx=0;		/* X坐标回0 */
				}
				if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
				{	LCD_STA_SET2CS2;
					LCD_DAT_SET2CS2;
				}
				else
				{	LCD_STA_SET2CS1;
					LCD_DAT_SET2CS1;
				}
				*LCD_STA = 0x40;	/* X坐标(y地址) */
				*LCD_STA = (ccy&0x07)|0xb8;	/* Y坐标(x地址) */
			}
		}
	}
}
#endif

/* 读LCD数据 */
#if lcd_read_en
void lcd_read(unsigned char ccx,unsigned char ccy,unsigned char *cdt,unsigned char cclen)
{	unsigned char cci;

	if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
	{	LCD_STA_SET2CS2;
		LCD_DAT_SET2CS2;
	}
	else
	{	LCD_STA_SET2CS1;
		LCD_DAT_SET2CS1;
	}
	if(ccy&0x80)		/* 根据Y坐标bit7决定是写数据还是状态 */
	{	cdt[0] = *LCD_STA;	/* 状态数据 */
	}
	else
	{	*LCD_STA = (ccx&0x3f)|0x40;	/* X坐标(y地址) */
		*LCD_STA = (ccy&0x07)|0xb8;	/* Y坐标(x地址) */
		for(cci=0;cci<cclen;cci++)
		{	cdt[cci] = *LCD_DAT;	/* 数据 */
			ccx++;
			if((ccx&0x3f)==0)	/* 换左右半 */
			{	if((ccx&0x7f)==0)	/* 换行 */
				{	ccy++;		/* Y坐标加1 */
					ccx=0;		/* X坐标回0 */
				}
				if(ccx&0x40)	/* 根据X地址bit6选择左右半 */
				{	LCD_STA_SET2CS2;
					LCD_DAT_SET2CS2;
				}
				else
				{	LCD_STA_SET2CS1;
					LCD_DAT_SET2CS1;
				}
				*LCD_DAT = 0x40;	/* X坐标(y地址) */
				*LCD_DAT = (ccy&0x07)|0xb8;	/* Y坐标(x地址) */
			}
		}
	}
}
#endif

⌨️ 快捷键说明

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