首先是最底层驱动:
在这里插入代码片
void delay(u16 count)
{
while(count--)
{
}
}
void lcd_load_1byte(u8 data,u8 mode)
{
u8 i=0;
u8 buf;
if(mode==0)//命令
{
for(i=0;i<8;i++)
{
buf=data&0x01;
switch(i)
{
case 0:
if(buf==1)
DB0_H;
else
DB0_L;
break;
case 1:
if(buf==1)
DB1_H;
else
DB1_L;
break;
case 2:
if(buf==1)
DB2_H;
else
DB2_L;
break;
case 3:
if(buf==1)
DB3_H;
else
DB3_L;
break;
case 4:
if(buf==1)
DB4_H;
else
DB4_L;
break;
case 5:
if(buf==1)
DB5_H;
else
DB5_L;
break;
case 6:
if(buf==1)
DB6_H;
else
DB6_L;
break;
case 7:
if(buf==1)
DB7_H;
else
DB7_L;
break;
default:break;
}
data>>=1;
}
}
if(mode==1)//数据
{
for(i=0;i<8;i++)
{
buf=data&0x01;
switch(i)
{
case 7:
if(buf==1)
DB0_H;
else
DB0_L;
break;
case 6:
if(buf==1)
DB1_H;
else
DB1_L;
break;
case 5:
if(buf==1)
DB2_H;
else
DB2_L;
break;
case 4:
if(buf==1)
DB3_H;
else
DB3_L;
break;
case 3:
if(buf==1)
DB4_H;
else
DB4_L;
break;
case 2:
if(buf==1)
DB5_H;
else
DB5_L;
break;
case 1:
if(buf==1)
DB6_H;
else
DB6_L;
break;
case 0:
if(buf==1)
DB7_H;
else
DB7_L;
break;
default:break;
}
data>>=1;
}
}
}
//发送命令
void lcd_Cmd(u8 cmd)
{
//Lcd_E_L;
lcd_load_1byte(cmd,0);
Lcd_Mode_Cmd;
delay(LcdBaseDelay);
Lcd_E_H;
delay(LcdBaseDelay);
Lcd_E_L;
delay(LcdBaseDelay);
}
//发送数据
void lcd_Data(u8 data)
{
//Lcd_E_L;
Lcd_Mode_Data;
lcd_load_1byte(data,1);
delay(LcdBaseDelay);
Lcd_E_H;
delay(LcdBaseDelay);
Lcd_E_L;
delay(LcdBaseDelay);
}
//屏幕关
void lcd_Off()
{
lcd_Cmd(62);
}
//屏幕开
void lcd_On()
{
lcd_Cmd(63);
}
//设置起始行
void lcd_Set_FirstLine(u8 hang)
{
u8 data=0;
if(hang>63)
return;
data=hang+192;
lcd_Cmd(data);
}
//设置页地址,8行为一页
void lcd_Set_X(u8 x)
{
u8 data=0;
if(x>7)
return;
data=x+184;
lcd_Cmd(data);
}
//设置列
void lcd_Set_Y(u8 y)
{
u8 data=0;
if(y>127)
return;
if(y>=64)
{
lcd_Left_En;
y-=64;
}
else
{
lcd_Right_En;
}
data=y+64;
lcd_Cmd(data);
}```
然后是 应用驱动:
u16 FindWord8(char *data)
{
for(u8 i = 0;i<Word8num;i++)
{
if((*data)==Word8Ascii[i][0])
{
return i;
}
}
return 0xffff;
}
u16 FindWord16(char *data)
{
for(u8 i = 0;i<Word16num;i++)
{
if(((*data)==Word16Ascii[i][0])&&((*(data+1))==Word16Ascii[i][1]))
{
return i;
}
}
return 0xffff;
}
void lcd_8x16(u8 x,u8 y,u16 num)
{
u8 xdebug=0;
xdebug=x;
if(y==64)
{
switch(x)
{
case 0:xdebug=2;break;
case 2:xdebug=4;break;
case 4:xdebug=6;break;
case 6:xdebug=0;break;
default:break;
}
}
lcd_Set_X(xdebug);
lcd_Set_Y(y);
for(u8 i=0;i<8;i++)
{
if(lcd_Invert(1,x,0,y+i,0)==1)
{
lcd_Data(~Word8[num][i]);
}
else
{
lcd_Data(Word8[num][i]);
}
}
lcd_Set_X(x+1);
lcd_Set_Y(y);
for(u8 i=0;i<8;i++)
{
if(lcd_Invert(1,x,0,y+i,0)==1)
{
lcd_Data(~Word8[num][i+8]);
}
else
{
lcd_Data(Word8[num][i+8]);
}
}
}
void lcd_16x16(u8 x,u8 y,u16 num)
{
u8 xdebug=0;
xdebug=x;
if(y==64)
{
switch(x)
{
case 0:xdebug=2;break;
case 2:xdebug=4;break;
case 4:xdebug=6;break;
case 6:xdebug=0;break;
default:break;
}
}
lcd_Set_X(xdebug);
lcd_Set_Y(y);
for(u8 i=0;i<16;i++)
{
if(lcd_Invert(1,x,0,y+i,0)==1)
{
lcd_Data(~Word16[num][i]);
}
else
{
lcd_Data(Word16[num][i]);
}
}
lcd_Set_X(x+1);
lcd_Set_Y(y);
for(u8 i=0;i<16;i++)
{
if(lcd_Invert(1,x,0,y+i,0)==1)
{
lcd_Data(~Word16[num][i+15]);//字库少了2个字节的0,所以这里不是16
}
else
{
lcd_Data(Word16[num][i+15]);
}
}
}
//x 0-7 y 0-3 str为字符串
void lcd_Write(u8 y,u8 x,char *str)
{
u8 len=0;
u16 side=0;
u8 WordType=0;
u8 Y=0;
Y=8*y;
char *p;
p=str;
if(x>3||y>7)
return;
x=x+x;
again:
side=FindWord8(p);
if(side==0xffff)
{
side=FindWord16(p);
if(side==0xffff)
{
return;
}
else
{
WordType=16;
}
}
else
{
WordType=8;
}
if(WordType==8)
{
p++; len++;
lcd_8x16(x,Y,side);
if(Y<=119)
{
Y+=8;
}
}
else if(WordType==16)
{
p+=2; len+=2;
lcd_16x16(x,Y,side);
if(Y<=111)
{
Y+=16;
}
}
else
{
return;
}
if(len<16)
{
if(*p=='\0')
{
p-=1;
*p=' ';
}
goto again;
}
}
//清空屏幕
void lcd_clear()
{
lcd_Write(0,0," ");
lcd_Write(0,1," ");
lcd_Write(0,2," ");
lcd_Write(0,3," ");
}
//初始化屏幕
void lcd_init()
{
// Lcd_RST_H;
// delay(60000);
Lcd_E_H;
Lcd_RST_L;
delay(LcdBaseDelay*25);
Lcd_RST_H;
delay(LcdBaseDelay*25);
Lcd_CS1_H;
Lcd_CS2_H
Lcd_Mode_Cmd;
lcd_Cmd(63);
lcd_Set_FirstLine(0);
lcd_clear();
Lcd_BCAKLIGHT_OPEN;
lcd_SetInvertLine(5);
//Lcd_BCAKLIGHT_CLOSE
// lcd_Data(0xff);
}
//cmd=0,设置反显区域 cmd=1,查询是否处于反显区域,cmd=2 清除设置的区域
//返回1 查询成功
u8 lcd_Invert(u8 cmd,u8 x1,u8 x2,u8 y1,u8 y2)
{
static u8 X1,X2,Y1,Y2=0;
static u8 InvertEnable=0;
if(cmd==2)
{
InvertEnable=0;
return 0;
}
if(cmd==0)
{
X1=x1;
X2=x2;
Y1=y1;
Y2=y2;
InvertEnable=1;
}
if(cmd==1&&InvertEnable==1)
{
if(x1>=X1&&x1<=X2&&y1>=Y1&&y1<=Y2)
{
return 1;
}
}
else
{
return 0;
}
return 0;
}
//设置某行反显 x<4
void lcd_SetInvertLine(u8 x)
{
switch(x)
{
case 0:lcd_Invert(0,0,1,0,127);break;
case 1:lcd_Invert(0,1,2,0,127);break;
case 2:lcd_Invert(0,3,4,0,127);break;
case 3:lcd_Invert(0,5,6,0,127);break;
default:lcd_Invert(2,0,0,0,0);break;
}
}
//主菜单设置反显
void lcd_MainMenuSetInvert(u8 x)
{
switch(x)
{
case 0:lcd_Invert(0,3,4,0,63);break;
case 1:lcd_Invert(0,3,4,64,127);break;
case 2:lcd_Invert(0,5,6,0,63);break;
case 3:lcd_Invert(0,5,6,64,127);break;
default:lcd_Invert(2,0,0,0,0);break;
}
}
然后是字库的格式
#define Word16num 2//文字个数
#define Word8num 18 //文字个数
const char Word16Ascii[Word16num][2]={"系","统"};
const char Word8Ascii[Word8num][1]=
{
"0","1","2","3","4","5","6","7","8","9"," ","A","B","C","N",":","V","W",
};
const unsigned char Word16[Word16num][32]=
{
/*-- 文字: 系 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=15x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=15x16 --*/{
0x00,0x00,0x40,0x44,0x4D,0x55,0x66,0x44,0x84,0x88,0x92,0x81,0x00,0x00,0x00,0x00,
0x00,0x88,0x90,0xA0,0x84,0x84,0xFC,0x80,0x80,0xA0,0x90,0xC8,0x00,0x00,},
/*-- 文字: 统 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=15x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=15x16 --*/{
0x00,0x19,0x2A,0xCC,0x18,0x00,0x11,0x13,0x9D,0x51,0x11,0x15,0x13,0x10,0x00,0x00,
0x88,0x88,0x90,0x90,0x04,0x08,0x30,0xC0,0x00,0xF8,0x04,0x84,0x1C,0x00,}
}
const unsigned char Word8[Word8num][16]=
{
/*-- 文字: 0 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x07,0x08,0x10,0x10,0x08,0x07,0x00,0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,},
/*-- 文字: 1 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x08,0x08,0x1F,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,},
/*-- 文字: 2 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x0C,0x10,0x10,0x10,0x11,0x0E,0x00,0x00,0x18,0x28,0x48,0x88,0x08,0x18,0x00,},
/*-- 文字: 3 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x0C,0x10,0x11,0x11,0x12,0x0C,0x00,0x00,0x30,0x08,0x08,0x08,0x88,0x70,0x00,},
/*-- 文字: 4 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x01,0x02,0x04,0x1F,0x00,0x00,0x00,0x00,0xC0,0x40,0x48,0xF8,0x48,0x48,0x00,},
/*-- 文字: 5 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x1F,0x11,0x12,0x12,0x12,0x11,0x00,0x00,0x30,0x08,0x08,0x08,0x08,0xF0,0x00,},
/*-- 文字: 6 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x07,0x08,0x11,0x11,0x19,0x00,0x00,0x00,0xF0,0x88,0x08,0x08,0x08,0xF0,0x00,},
/*-- 文字: 7 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x1C,0x10,0x10,0x13,0x1C,0x10,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,},
/*-- 文字: 8 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x0E,0x11,0x11,0x11,0x11,0x0E,0x00,0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,},
/*-- 文字: 9 --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x0F,0x10,0x10,0x10,0x09,0x07,0x00,0x00,0x00,0x98,0x88,0x88,0x10,0xE0,0x00,},
/*-- 文字: --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
/*-- 文字: A --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x00,0x07,0x18,0x07,0x00,0x00,0x00,0x08,0x78,0xC8,0x40,0xC8,0x78,0x08,0x00,},
/*-- 文字: B --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x10,0x1F,0x11,0x11,0x11,0x12,0x0C,0x00,0x08,0xF8,0x08,0x08,0x08,0x88,0x70,0x00,},
/*-- 文字: C --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x07,0x08,0x10,0x10,0x10,0x10,0x1C,0x00,0xE0,0x10,0x08,0x08,0x08,0x10,0x20,0x00,},
/*-- 文字: N --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x10,0x1F,0x1C,0x03,0x10,0x1F,0x10,0x00,0x08,0xF8,0x08,0x80,0x70,0xF8,0x00,0x00,},
/*-- 文字: : --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,},
/*-- 文字: V --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x10,0x1E,0x11,0x00,0x11,0x1E,0x10,0x00,0x00,0x00,0xE0,0x18,0xE0,0x00,0x00,0x00,},
/*-- 文字: W --*/
/*-- 宋体9; 此字体下对应的点阵为:宽x高=8x15 --*/
/*-- 高度不是8的倍数,现调整为:宽度x高度=8x16 --*/{
0x10,0x1F,0x00,0x1F,0x00,0x1F,0x10,0x00,0x00,0x80,0xF8,0x00,0xF8,0x80,0x00,0x00,},
};
未完待续