I.简介
littlevgl 6.0 显示中文,从查找的资料来看,一种利用内部flash,通过官方工具或网友制作的工具,生成.C文件放到内部编译,在声明下,就可以显示中文。这种方法只是用少量字体,毕竟这种做法很占用内部flash。
另外两种是放到SD卡或外部spiflash。放到SD卡的网上的实例大多是基于7.0的,暂时没有去实现,我这里实现的是从SD卡拷贝到spiflash中(利用工具生成.bin 和.c )。还有看到网上有从SD卡上电拷贝到外部SDRAM中,用法和第一种相似,这种做法从理论上来看速度应该更快。
II实现过程
I. 第一种实现方式
使用工具生成,注意选择XBF字体,内部大数组,点击保存生成china_test的文件,添加工程中,注意声明下,就可以使用了。
代码如下:
#include "lvgl/lvgl.h"
LV_FONT_DECLARE(china_test);
void lv_chinest_test(void)
{
static lv_style_t style;
lv_obj_t * label;
label =lv_label_create( lv_scr_act(), NULL);
lv_obj_set_size( label, 100, 100);
lv_style_copy(&style, &lv_style_plain);
style.body.main_color = LV_COLOR_BLACK;
style.body.grad_color = LV_COLOR_BLACK;
style.text.font = &china_test;
lv_obj_set_style(label, &style);
lv_label_set_text(label, "中文测试");
printf("1234");
}
显示结果如下
II. 字库放到spiflash显示汉字
首先制作字库文件,可以添加常用汉字,字号和字体样式自主选择 ,如下图,加入常用汉字
会生成HZ.bin 和 HZ.c 两个文件,把HZ.bin 放大SD卡,一定要记得路径例如“/HZ.bin”,利用文件系统打开这个文件,让后拷贝到spiflash 某个固定地址,一定要记得起始地址(这个非常重要),我是利用正点原子汉字显示实验历程修改的,主要修改你要写入的文件(字库)路径,其他不做修改。这里只做测试,替换掉UNIGBK_PATH路径
//字库存放在磁盘中的路径
u8const GBK24_PATH="/SYSTEM/FONT/GBK24.FON"; //GBK24的存放位置
u8const GBK16_PATH="/SYSTEM/FONT/GBK16.FON"; //GBK16的存放位置
u8const GBK12_PATH="/SYSTEM/FONT/GBK12.FON"; //GBK12的存放位置
//u8const UNIGBK_PATH="/SYSTEM/FONT/UNIGBK.BIN"; //UNIGBK.BIN的存放位置
u8const UNIGBK_PATH="/HZ.bin";
正点原子默认代码按KEY0自动升级上述四个字库,有个函数可以单独升级某个字库,这里没做测试,直接修改u8 update_font(u16 x,u16 y,u8 size,u8 src),屏蔽掉其他三个文件的读写即可。
修改代码如下:添加两处#if 0 #end注释其他即可
//先查找文件是否正常
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)UNIGBK_PATH);
res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
if(res)rval|=1<<4;//打开文件失败
#if 0
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)GBK12_PATH);
res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
if(res)rval|=1<<5;//打开文件失败
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)GBK16_PATH);
res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
if(res)rval|=1<<6;//打开文件失败
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)GBK24_PATH);
res=f_open(fftemp,(const TCHAR*)pname,FA_READ);
if(res)rval|=1<<7;//打开文件失败
#endif
myfree(SRAMIN,fftemp);//释放内存
if(rval==0)//字库文件都存在.
{
LCD_ShowString(x,y,240,320,size,"Erasing sectors... ");//提示正在擦除扇区
for(i=0;i<FONTSECSIZE;i++) //先擦除字库区域,提高写入速度
{
fupd_prog(x+20*size/2,y,size,FONTSECSIZE,i);//进度显示
W25QXX_Read((u8*)buf,((FONTINFOADDR/4096)+i)*4096,4096);//读出整个扇区的内容
for(j=0;j<1024;j++)//校验数据
{
if(buf[j]!=0XFFFFFFFF)break;//需要擦除
}
if(j!=1024)W25QXX_Erase_Sector((FONTINFOADDR/4096)+i); //需要擦除的扇区
}
//printf("\r\n 0x02%x",buf)
myfree(SRAMIN,buf);
LCD_ShowString(x,y,240,320,size,"Updating UNIGBK.BIN");
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)UNIGBK_PATH);
res=updata_fontx(x+20*size/2,y,size,pname,0); //更新UNIGBK.BIN
if(res){myfree(SRAMIN,pname);return 1;}
LCD_ShowString(x,y,240,320,size,"Updating GBK12.BIN ");
#if 0
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)GBK12_PATH);
res=updata_fontx(x+20*size/2,y,size,pname,1); //更新GBK12.FON
if(res){myfree(SRAMIN,pname);return 2;}
LCD_ShowString(x,y,240,320,size,"Updating GBK16.BIN ");
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)GBK16_PATH);
res=updata_fontx(x+20*size/2,y,size,pname,2); //更新GBK16.FON
if(res){myfree(SRAMIN,pname);return 3;}
LCD_ShowString(x,y,240,320,size,"Updating GBK24.BIN ");
strcpy((char*)pname,(char*)src); //copy src内容到pname
strcat((char*)pname,(char*)GBK24_PATH);
res=updata_fontx(x+20*size/2,y,size,pname,3); //更新GBK24.FON
if(res){myfree(SRAMIN,pname);return 4;}
#endif
//全部更新好了
ftinfo.fontok=0XAA;
W25QXX_Write((u8*)&ftinfo,FONTINFOADDR,sizeof(ftinfo)); //保存字库信息
代码
__packed typedef struct
{
u8 fontok; //字库存在标志,0XAA,字库正常;其他,字库不存在
u32 ugbkaddr; //unigbk的地址
u32 ugbksize; //unigbk的大小
u32 f12addr; //gbk12地址
u32 gbk12size; //gbk12的大小
u32 f16addr; //gbk16地址
u32 gbk16size; //gbk16的大小
u32 f24addr; //gbk24地址
u32 gkb24size; //gbk24的大小
}_font_info;
这个正点原子字库存储位置大小相关的结构体,ugbkaddr 此时的地址为1210241024+33(上述结构体大小),ugbksize为3,222,888 打印出的数据刚好和HZ.bin 大小对应
复制完成后最从12M + 33 的地方读取若干字节和源文件对比,已确定文件正确性
修改HZ.c
开启__g_font_buf,添加W25QXX_Read(__g_font_buf, 12582945+offset, size);
12582945 = 1210241024+33;为什么加33 前面已经解释过了
static uint8_t __g_font_buf[48];//如bin文件存在SPI FLASH可使用此buff
static uint8_t __user_font_getdata(int offset, int size){
//如字模保存在SPI FLASH, SPIFLASH_Read(__g_font_buf,offset,size);
//如字模已加载到SDRAM,直接返回偏移地址即可如:return (uint8_t)(sdram_fontddr+offset);
W25QXX_Read(__g_font_buf, 12582945+offset, size);
return __g_font_buf;
}
程序源码如下
#include "lvgl/lvgl.h"
//LV_FONT_DECLARE(china_test);
LV_FONT_DECLARE(HZ);
void lv_chinest_test(void)
{
static lv_style_t style;
lv_obj_t * label;
label =lv_label_create( lv_scr_act(), NULL);
lv_obj_set_size( label, 100, 100);
lv_style_copy(&style, &lv_style_plain);
style.body.main_color = LV_COLOR_BLACK;
style.body.grad_color = LV_COLOR_BLACK;
//style.text.font = &china_test;
style.text.font = &HZ;
lv_obj_set_style(label, &style);
//lv_label_set_text(label, "中文测试");
lv_label_set_text(label, "世界那么大我想去看看");
lv_label_ins_text(label, LV_LABEL_POS_LAST, "我思故我在");
printf("1234");
}
显示结果
总结
上述只是添加一种字库,实际项目中可能添加多种字库,根据实际需求添加需要的字体。如果板子没有SD卡设备,就用通过其他方式把文件(字库)拷贝到spiflash中,比如串口接收,利用平台中转,最终写到对用的spiflash中,实际量产的时候,有一片烧录好spiflash,直接拷贝即可。
这里只做了一个简单的调试记录,如有不正确的地方,请指正。