Linux下使用LCD5110显示中文(ASCII+GB2312字库)

51 篇文章 15 订阅
41 篇文章 1 订阅

 关于如何在Linux下使用LCD5110参见另一篇blog:http://blog.csdn.net/tq384998430/article/details/53214273。在这篇博客的基础上需要添加屏幕绘点的函数:

void LCD_DrawDot(int x,int y,int onoff)
{
	int a = y / 8,b = y % 8;
	if(onoff)
	{
		LCD_Buffer[a * 84 + x] |= (0x01 << b);
	}
	else
	{
		LCD_Buffer[a * 84 + x] &= ~(0x01 << b);
	}
	WriteByte(0x80 | x,0);
	WriteByte(0x40 | a,0);
	WriteByte(LCD_Buffer[a * 84 + x],1);
}

使用的缓冲区是84*6的,所以这里的LCD_DrawDot函数是在84*6的数组中进行绘制点,绘点不会影响与该像素点在同一个字节中的其他7个像素,使用的是或操作和与操作。有了这个绘点的基础函数就可以进行画线、画圆等函数,同样的也可以进行绘制汉字和ASCII码。

在绘制汉字和ASCII码之前需要了解一下GB2312和ASCII码表的编码规范,首先ASCII码比较简单,我制作的ASCII码字库是从‘ ’到‘~’的,全部字符如下: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~,使用的是8*16点阵,有点浪费空间其实6*12就够了貌似,但是为了配合汉字的16*16还是使用了8*16点阵。ASCII字库一共使用了1520字节的空间,存储在字库文件的前1520字节,后面的空间用于存储GB2312字库空间。GB2312的内容 太多了,网上一大把的就不贴出来了,但是这里要说说GB2312的编码规则。

ASCII码规定每个字符使用一个字节表示,并且该字节的范围为0x00到0x7F,所以当一个字符在0x00到0x7f之间的时候标志这个字符是一个ASCII字符,要从ASCII码库中提取对应的点阵数据显示。当一个字符的编码大于0xA0时则表示这个字符不是ASCII码字符了,是GB2312或者其他编码的字符例如UTF8等。程序中的汉字可能是GB2312编码也可能是其他编码格式,需要手动调节编辑器的编码方式,例如使用Notepad++时选择格式-》中文-》GB2312,这样才能保证程序中的中文是以GB2312的编码格式存储在字符串中的。GB2312编码规定一个字符是有两个字节组成的,两个字节的范围都是A1A1-FEFE,所以可以通过范围来判断是否是GB2312字符。GB2312的编码标准中有区码和位码,前者用于表示汉字所在的区,后者用于表示汉字所在区中的偏移量, 具体的编码规范可以参考:http://tools.jb51.net/table/gb2312 和 http://www.qqxiuzi.cn/zh/hanzi-gb2312-bianma.php两篇文章。

程序上有三个关于绘制字符的函数,第一个是绘制ASCII字符函数,第二个是绘制GB2312字符函数,最后一用于整合前面两个函数。

void LCD_DrawAscii(int x,int y,unsigned short offset)
{
	unsigned int i,j;
	for(i=0;i<16;i++)
	{
		for(j=0;j<8;j++)
		{
			if(FontData[offset*16 + i] & (0x80 >> j))
				LCD_DrawDot(x + j, y + i,1);
			else
				LCD_DrawDot(x + j,y + i,0);
		}
	}
}

void LCD_DrawHanzi(int x,int y,unsigned short offset)
{
	unsigned int i,j;
	for(i=0;i<16;i++)
	{
		for(j=0;j<16;j++)
		{
			if(FontData[offset*32 + 0x5f0 + i*2 + j/8] & (0x80 >> j%8))
				LCD_DrawDot(x + j, y + i,1);
			else
				LCD_DrawDot(x + j,y + i,0);
		}
	}
}

void LCD_DrawText(int x,int y,char *text)
{
	unsigned int i,j;
	for(i=0;text[i]!='\0';i++)
	{
		if(text[i] < 0xA0)	//ASCII
		{
			LCD_DrawAscii(x,y,text[i] - ' ');
			x += 8;
		}
		else	//chinese
		{
			LCD_DrawHanzi(x,y,(text[i]-0xA1)*94 + (text[++i] - 0xA1));	//这里i要自加1个因为汉子占用两个字节
			x += 16;
		}
	}
}
LCD_DrawText函数的具体功能是在x、y像素位置绘制一个字符串text,这个函数会根据字符的类型调用LCD_DrawAscii和LCD_DrawHanzi函数实现字符绘制功能,主函数测试程序如下:

	int fd;
	struct stat file_stat;
	if((fd = open("ASCII+GB2312.bin",O_RDWR)) < 0)
	{
		printf("open gb2312 failed\r\n");
		goto close;
	}
	if(stat("ASCII+GB2312.bin",&file_stat) < 0)
	{
		printf("stat failed\r\n");
		goto close;
	}
	
	printf("filesize:%d\r\n",file_stat.st_size);
	FontData = (unsigned char *)malloc(file_stat.st_size);
	
	if(FontData == NULL)
	{
		printf("malloc failed\r\n");
		goto close;
	}
	read(fd,FontData,file_stat.st_size);
	

	
	LCD_DrawText(0,0,"汤权1994");
	LCD_DrawText(0,16,"123我是谁");
	LCD_DrawText(0,32,"中华人民");
程序的执行效果如下:




需要字库制作的朋友可以联系我QQ:384998430,由于博客无法上传附件,(我不知道怎么上传),所以不附加我的字库了。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值