12864液晶屏驱动源码分享

首先是最底层驱动:

在这里插入代码片
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,},


};


未完待续


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值