u8g2库的使用及驱动LCD显示中文

u8g2库

1、准备工作

Env 工具包含了 RT-Thread 源代码开发编译环境和软件包管理系统。

  • 从 RT-Thread 官网下载 Env 工具。https://www.rt-thread.org/download.html。
  • 在电脑上装好 git,软件包管理功能需要 git 的支持。git 的下载地址为https://git-scm.com/downloads,根据向导正确安装 git,并将 git 添加到系统环境变量。
  • 注意在工作环境中,所有的路径都不可以有中文字符或者空格。

2、学习ENV开发文档

Env 用户手册 (rt-thread.org)

仔细学习用户手册,了解在线软件包的安装方法。

3、将u8g2库添加到工程中

第一步:在工程中右键打开ENV,输入menuconfig,进入配置。
使用menuconfig
所有的在线包
回车进入后,面对一堆分类,不用急。之后在RT-Thread官网的软件包界面搜索u8g2,软件包 - RT-Thread物联网操作系统,进入后查看软件包的分类,记住这个分类,在ENV中选择对应的分类并回车进入。
搜索u8g2包
软件包的分类
所有在线包
进入后可以看到分类下的各种在线软件包,选择u8g2,回车后可以看到官方库和老版本库。最好使用官方库,最新的bug少。

直接空格选中,save即可。之后退出等待自动安装,如果没有设置自动安装,就需要根据用户手册重新设置。

之后打开工程,可以看到工程文件中包含了很多驱动文件,这是官方针对不同的屏幕写的驱动。选中自己屏幕需要的驱动即可,其他的文件可以删除,避免文件过大。
在这里插入图片描述
注意:上面介绍的安装库方法是基于ENV,但是很多芯片不需要这么麻烦。这里提供一个简单的办法:1、https://github.com/olikraus/u8g2直接下载库,之后在工程中添加下载文件中csrc文件夹中所有的文件。也是一样的实现。

u8g2包
u8g2库的安装就结束了,到这一步并不会有什么显示结果,之后就是驱动LCD或OLED进行显示了。

驱动LCD

安装u8g2库之后,就要让屏幕亮起来。但是要怎么把驱动库和屏幕驱动联系起来,怎么显示,都是问题。但不用急,首先需要了解u8g2库的使用原理。显示分为三步:1、绑定IO。2、选择对应的构造器、驱动方式。3、准备显示。

1、绑定IO

驱动任一屏幕的时候,都需要使用IO,首先需要将u8g2库中定义的IO宏和自己屏幕实际使用的IO绑定。

其中u8g2的IO宏都在u8x8.h中,包含了IIC、SPI、8080、6800等。
所有io宏
之后通过u8x8_SetPin函数将两者的IO绑定起来。以下是三种驱动方式的绑定,IIC的最简单。

//    // SPI的IO绑定
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_SPI_CLOCK, OLED_SPI_PIN_CLK);
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_SPI_DATA, OLED_SPI_PIN_MOSI);
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_CS, OLED_SPI_PIN_CS);
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_DC, OLED_SPI_PIN_DC);
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_RESET, OLED_SPI_PIN_RES);

//    // IIC的IO绑定
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_CLOCK, OLED_IIC_PIN_SCL);
//    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_I2C_DATA, OLED_IIC_PIN_SDA);

    // 8080的IO绑定
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D0, ST7586_PIN_D0);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D1, ST7586_PIN_D1);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D2, ST7586_PIN_D2);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D3, ST7586_PIN_D3);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D4, ST7586_PIN_D4);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D5, ST7586_PIN_D5);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D6, ST7586_PIN_D6);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_D7, ST7586_PIN_D7);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_E,  ST7586_PIN_E);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_CS, ST7586_PIN_CS);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_DC, ST7586_PIN_DC);
    u8x8_SetPin(u8g2_GetU8x8(&u8g2), U8X8_PIN_RESET, ST7586_PIN_RESET);
    LCDBACK_SET_OUTPUT;
    LCDBACK_SET_ON;

2、选择对应的构造器、驱动方式

u8g2库都是通过一个构造器来选择对应的芯片驱动,记住一定要选择正确对应的构造器,构造器在u8g2_d_setup.c文件中,如果觉得查看起来很麻烦,可以直接在u8g2.h中查看函数的声明。

构造器和屏幕的驱动芯片、分辨率、驱动方式有关,比如说0.96OLED大多数使用SSD1306驱动芯片,因此构造器可选用:u8g2_Setup_ssd1306_128x64_vcomh0_f、u8g2_Setup_ssd1306_i2c_128x64_noname_f等,前面是SPI驱动,后面是IIC驱动,最后的f表示整页设置,虽然方便,但速度慢一点,对内存空间要求大一点,只是学习的话直接使用即可。

构造器有四个形参,分别为u8g2_t的结构体、显示旋转角度、驱动方式、IO的写和时序的延时。

结构体声明一个即可,显示方式一般都是U8G2_R0不旋转、自己屏幕的驱动方式:SPI、IIC、8080等、最后一个形参在RTT中都是u8x8_gpio_and_delay_rtthread。

以下是三种构造器及驱动方式的选择。

//    // ssd1306驱动芯片、软件SPI、128x64分辨率、显示8page的构造器
//    u8g2_Setup_ssd1306_128x64_vcomh0_f(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay_rtthread);

//    // ssd1306驱动芯片、软件IIC、128x64分辨率、显示8page的构造器
//    u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_rtthread);

    // st7586驱动芯片,8080时序、240x160分辨率、显示8page的构造器
    u8g2_Setup_st7586s_erc240160_f(&u8g2, U8G2_R0, u8x8_byte_8bit_8080mode, u8x8_gpio_and_delay_rtthread);

3、准备显示

在调用任何显示函数之前,为防止数据溢出,都需要先动态分配一块内存给u8g2这个结构体。

具体的分配如下:

// 调用任何显示函数之前,都需要先申请一块区域,不然会出现堆栈溢出的情况
len = u8g2_GetBufferSize(&u8g2);
uint8_t * buffer = rt_malloc(len);
u8g2_SetBufferPtr(&u8g2, buffer);

之后就要准备显示,首先需要初始化显示器以及需要将显示的内容设置为显性,即显示出来。

至于要调用什么函数,就要在u8x8.h或在u8x8_display.c文件中查看。如下所示

u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);  // 形参为0表示显示,1表示不显示

初始完后就可以显示需要显示的字或图像。

关键函数有几个:u8g2_ClearDisplay、u8g2_ClearBuffer、u8g2_SendBuffer、u8g2_SetFont、u8g2_DrawStr。分别是清屏函数、清除显示内容、将内容显示函数、设置字体函数以及显示字符串函数。注意:u8g2库的显示方式都是将需要显示的内容赋值给u8g2结构体,之后再刷新一次屏幕,因此显示前需要先清除buff,再将内容发送给结构体。

显示程序如下:

// 全屏以及清屏显示
u8g2_ClearDisplay(&u8g2);
rt_thread_mdelay(1000);
memset(buffer, 0xff, len);
u8g2_SendBuffer(&u8g2);
rt_thread_mdelay(1000);

u8g2_ClearBuffer(&u8g2);
u8g2_SendBuffer(&u8g2);
u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);
u8g2_DrawStr(&u8g2, 1, 8, "U8g2 on RT-Thread");
u8g2_SendBuffer(&u8g2);
rt_thread_mdelay(1000);

这样LCD即可显示出U8g2 on RT-Thread这样一串字符串了。

有个问题需要注意:如果使用的是st7586驱动芯片且型号是erc240160,此处有个坑,需要手动改动驱动函数,原因就是三像素显示,导致会出现空白点。具体就是将u8x8_d_st7586s_erc240160的驱动里面的单字节改成和u8x8_d_st7586s_ymc240160一样的驱动,即采用三字节组合成一个8数组发送。

u8g2库显示中文

u8g2的库中支持中文显示,但是不可能包含所有的中文,因此当需要显示中文的时候,最好自己做一个。制作主要分成4步:1、将中文转换成Unicode编码。2、选择字体。3、将bdf文件转换成.c文件。4、显示中文。

1、将中文转换成Unicode编码

首先u8g2都是UTF-8显示,因此需要将中文转换成可识别的UTF-8的数据。需要一系列的转换,首先就是讲中文转换成Unicode编码。转换方式一般都是在网页中在线转换或自己写脚本转换。在线网站:Unicode编码转换 - 站长工具 (chinaz.com)

将转换的Unicode编码复制出来,在一个记事本打开。并将“\u”全用“,$”替换,将最开头的“,”删掉。且在开头添加32-128,表示32-128的ASCII字符。
在这里插入图片描述
在这里插入图片描述
将txt文件更名为test_chinese.map,名字任意都行。

2、选择字体

显示的内容选好后,需要设置显示的大小以及字体。打开GUItool软件。

可以选择windows自带的字体或其他字体,电脑上的字体文件在c盘的window->fonts文件夹下,将选择的字体复制出来,可以在GUItool软件点击其他字体并选择路径,编码方式选择Unicode、像素根据自己选择即可,软件中最小为16,模式默认Ttf,字符集选择简体中文,输出为Bdf,点击生成字库。会弹出一个文件夹,就是生成的字库。
在这里插入图片描述

3、将bdf文件转换成.c文件

找到u8g2库所在的文件夹,在最开始无论这么添加库,都能找到,点开文件夹后。选择tools->font,需要用到的文件夹有三个:bdf、bdfconv、build。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将1中map文件复制到build文件夹中,将2中的bdf文件复制到bdf文件夹中。点开bdfconv。主要是通过exe文件将bdf转换成.c文件,为了方便操作,在这准备添加一个bat文件来方便操作,bat内容为:
bdfconv.exe -v -b 0 -f 1 C:\xxx\xxx\xxx\xxx\tools\font\bdf\Deng_U16.bdf -M C:\xxx\xxx\xxx\xxx\tools\font\build\language_entry_table.map -n u8g2_font_test_chinese -o u8g2_font_test_chinese.c -d C:\xxx\xxx\xxx\xxx\tools\font\bdf\Deng_U16.bdf

其中xxx表示绝对路径,根据自己文件所在的路径选择即可。 Deng_U16.bdf就是选择的第2步生成的字库。u8g2_font_test_chinese 就是第1步中文件的命名。u8g2_font_test_chinese.c就是需要生成的.c文件,都需要根据名称具体改变。点击bat文件后,就会出现.c文件。
在这里插入图片描述
在这里插入图片描述

4、显示中文

做好.c文件后,打开.c文件,全部内容复制到工程文件u8g2_fonts.c文件中最后,并在u8g2.h文件中添加声明。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

之后就能通过函数u8g2_SetFont设置中文字体。如下所示。

// 显示中文
u8g2_ClearBuffer(&u8g2);
u8g2_SendBuffer(&u8g2);
u8g2_SetFont(&u8g2, u8g2_font_test_chinese);
u8g2_DrawStr(&u8g2, 1, 10, "test");
u8g2_DrawUTF8(&u8g2, 1, 24, "测试:28");
u8g2_SendBuffer(&u8g2);
rt_thread_mdelay(1000);

就能正常显示中文。

注意只要包含字符串的文件,都需要使用UTF-8编码。

本文重点感谢gitee开源代码。链接:https://gitee.com/cazure/note

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值