ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

单片机LCD少量汉字显示

2020-02-02 21:43:16  阅读:477  来源: 互联网

标签:16 0x00 unsigned 汉字 0x40 单片机 LCD


单片机LCD少量汉字取模显示(不需要字库)

最近在做一个小项目的时候需要用到LCD显示中文汉字,用到的字数不多,如果使用字库占的内存大,而且本人不太熟悉。上网看了一下别人的方法,移植了一下,觉得这个方法不错。后期还可以移植到OLED的显示上,直接可以像显示英文字符串的方法一样显示中文,非常方便:

		show_Hz32(60,160,"武汉加油",BLACK,WHITE);
		Show_Hz16(60,200,"武汉",BLACK,WHITE);
		LCD_ShowString(20,90,100,40,16,"China come on!");

下面以正点原子的mini开发板和2.8寸液晶LCD为例,记录一下这种显示方法的实现。

我们知道LCD上显示汉字一般都需要加上字库,因为编码方式与英文的方式不同,汉字或者说GBK各种国标码一般都是采用两个字节进行编码。暂且叫做汉字内码吧,详细的编码方式可以百度一下。

关键点:

一个汉字占的空间是2个字节(Byte),也就是说"哈"这样一个汉字占用两个字节的内存空间。

我们封装一种结构体类型typFNT_GB16

typedef struct 
{
	unsigned char Index[2];
	unsigned short Msk[16];
}typFNT_GB16;

Index用作汉字占用的2Byte,后面我会说到为什么。Msk则是这个汉字取出的字模占用的空间。16*16的汉字就是32个字节:
162Byte=32Byte 16*2Byte=32Byte 16∗2Byte=32Byte
接下来是对汉字取模,使用下面这款软件的话:

​ LCD字体大小跟取模的关系是:

LCD32x32字体对应软件24号字体(宋体)也是小一

LCD16x16字体对应软件12号字体(宋体)也是小四

在这里插入图片描述

16x16字体取模设置如下:

在这里插入图片描述

在这里插入图片描述

32x32字体的设置类似,但是使用24号字体取出来回多出四个字节的数据,一般都是0,我们删除即可:

在这里插入图片描述

然后在字库头文件中,创建结构体typFNT_GB16类型的数组:GB16_Code[],把我们刚刚取得的字模数据放入数组,同时在每个汉字的字模数据前面 加上一个"x",这里的x就是对应的汉字,当然还有逗号。

const typFNT_GB16 GB16_Code[] = 
{
/*--  文字:  武  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
"武",
0x00,0x40,0x00,0x50,0x3F,0x48,0x00,0x48,0x00,0x40,0xFF,0xFE,0x00,0x40,0x04,0x40,
0x04,0x40,0x27,0x40,0x24,0x20,0x24,0x22,0x24,0x12,0x27,0x8A,0xF8,0x06,0x40,0x02,

/*--  文字:  汉  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
"汉",
0x00,0x00,0x27,0xF8,0x12,0x08,0x12,0x08,0x82,0x08,0x41,0x10,0x49,0x10,0x09,0x10,
0x10,0xA0,0x10,0xA0,0xE0,0x40,0x20,0x40,0x20,0xA0,0x21,0x10,0x22,0x08,0x0C,0x06,
};

这样的话,刚刚我们封装结构体类型中Index就会对应到我们的汉字的两个字节空间。

然后我们就可以通过判断字符串中汉字占用的两个字节来判断是哪个汉字,并且把点阵数据写入LCD,最后就可以显示了。16x16汉字显示的函数如下,32x32的函数也是类似的:

/*显示16*16汉字*/
void Show_Hz16(unsigned int x,unsigned int y,unsigned char *p,unsigned int WordColor,unsigned int BackColor)
{
	unsigned int i=0,j=0,k=0;
	//unsigned short word=0;

	while(*p != '\0')//当前索引汉字不为空时
	{
		LCD_Set_Window(x,y,16,16);//设置16*16大小窗口
		LCD_SetCursor(x,y);//设置坐标
		LCD_WriteRAM_Prepare();//开始写GRAM
		for(i=0;i<2;i++)//在所有的汉字结构体数组中查找,i最大为结构体数组成员的个数
		{
			if((*p==GB16_Code[i].Index[0]) && (*(p+1)==GB16_Code[i].Index[1]))//索引汉字成功
			{ //i=i+34;
				for(j=0;j<32;j++)//写入数据
				{
					unsigned short word=GB16_Code[i].Msk[j];
					for(k=0;k<8;k++)//循环8次移位
					{
						if((word&0x80)==0x80)
						{
							LCD_WR_DATA(WordColor);//写入字体颜色
						}else {
							LCD_WR_DATA(BackColor);//写入字体背景色
						}
						word<<=1;//往前移位
					}		
				}
			}
		}
		p+=2;
		x+=16;
	}
}

显示效果:
在这里插入图片描述

总结:

巧妙的地方就在汉字的2Byte的内码上,通过这个方式来判断汉字后再写入数据就ok了。

参考博客:
https://blog.csdn.net/weilexuexi12/article/details/69890328
https://blog.csdn.net/qq_40987215/article/details/89391441
https://blog.csdn.net/nana1108/article/details/5645958

文件下载

NameisBoy 发布了5 篇原创文章 · 获赞 1 · 访问量 205 私信 关注

标签:16,0x00,unsigned,汉字,0x40,单片机,LCD
来源: https://blog.csdn.net/qq_41790078/article/details/104149381

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有