📄 lcddrv.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 + -