在做LCD屏幕中文显示的时候,我发现中文并不能正常显示出来,根据我的排查总结出了下面的文章。

我使用的LCD显示屏的驱动是ST7789V,Paint_DrawString_CN()是官方的中英文显示的库函数。由于该函数支持的是GB2312中文编码,所以当编码环境不一致的时候会发生转码错误。比如在函数调用的时候使用的是UTF-8的编码,那么在实参传递的时候会将中文UTF-8的转码当作GB2312的来用。

GB2312编码中每个中文字符通常占用两个字节,而UTF-8编码每个中文字符通常占用三个字节。举一个例子:对于中文字“好”,GB2312的转码是:0xBA 0xC3,而UTF-8的转码是:0xE5 0xA5 0xBD。

void Paint_DrawString_CN(UWORD Xstart, UWORD Ystart, const char *pString, cFONT *font, UWORD Color_Background, UWORD Color_Foreground)

使用VScode + Keil5做嵌入式开发时,由于Keil5编译器使用的是GB2312,但是VScode默认使用的是UTF-8,所以要修改必要文件的字符编码。

在修改文件编码方式之前,可以测试一下是不是官方打印函数错误的原因。下面的代码是测试直接使用中文“你好”的GB2312十六进制编码作为参数传递,避免了转码解析错误的问题。如何LCD屏幕能正确输出“你好”,就证明官方的打印函数没有问题,所以之后应该重点排查字库Font12CN.c和源码LCD_Test.c是否出现问题。

Paint_DrawString_CN(0, 0, "\xC4\xE3\xBA\xC3", &Font12CN, BLACK, WHITE);  // "你好"

函数调用的源文件(如LCD_Test.c)和字库文件(如Font12CN.c)的编码必须统一,且必须与函数Paint_DrawString_CN()要求的GB2312编码一致。

为什么需要统一编码?

函数Paint_DrawString_CN()的工作原理:该函数直接按GB2312编码解析字符串(例如"你好"的GB2312编码是:\xC4\xE3\xBA\xC3)。如果源文件LCD_Test.c是UTF-8编码,"你好"会被存为:\xE4\xBD\xA0\xE5\xA5\xBD,导致函数解析错误,显示乱码或编译报错。

所以就要修改LCD_Test.c文件的编码类型为GB2312。

字库文件Font12CN.c的匹配问题:字库中的字符(如"你")通过index字段(如{0xC4,0xE3})匹配输入字符串的GB2312编码。找到后,提取对应的点阵数据(如"你"的16x21点阵),之后按位解析点阵数据,逐像素绘制。

如果输入字符串的编码不一致(如 UTF-8),字库会找不到对应字符,导致显示乱码。

总结一句话就是:将字库文件和调用该函数的文件的字符编码格式改为函数支持的GB2312模式

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐