【平头哥RVB2601创意应用开发】实践2-移植U8g2图形库
[复制链接]
RVB2601板子自带了一块128x64的OLED单色屏幕,可以用来进行图形和文字的显示。RVB2601的例程中,有使用LVGL库进行OLED显示的例程,LVGL也是一个十分优秀的图形库,支持彩色界面的设计。由于前段时间刚好在用另一个支持单色显示的图形库——U8g2,所以就想着尝试将U8g2库移植到RVB2601板子中。
U8g2简介
U8g2 是一个用于嵌入式设备的单色图形库。U8g2支持单色OLED和LCD,并支持如SSD1306等多种类型的OLED驱动。
U8g2源码的开源库地址:
移植步骤
首先下载U8g2的源码,因为RVB2601板子主要是使用C语言编程,所以只需关注源码中的C源码部分,即csrc文件夹下的文件。
精简c源码
U8g2支持多种显示驱动的屏幕,因为源码中也包含了各个驱动对应的文件,为了减小整个工程的代码体积,在移植U8g2时,可以删除一些无用的文件。
去掉无用的驱动文件
这些驱动文件通常是u8x8_d_xxx.c,xxx包括驱动的型号和屏幕分辨率。RVB2601板子的OLED,可以使用u8x8_ssd1306_128x64_noname.c这个文件,其它的屏幕驱动文件可以删掉。
精简u8g2_d_setup.c
只留一个本次要用到的u8g2_Setup_ssd1306_128x64_noname_f就好,其它的可以删掉或注释掉
- #include "u8g2.h"
-
-
- void u8g2_Setup_ssd1306_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
- {
- uint8_t tile_buf_height;
- uint8_t *buf;
- u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_001, byte_cb, gpio_and_delay_cb);
- buf = u8g2_m_16_8_f(&tile_buf_height);
- u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
- }
精简u8g2_d_memory.c
只留一个本次要用到的u8g2_m_16_8_1就好,其它的可以删掉或注释掉
- #include "u8g2.h"
-
- uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt)
- {
- #ifdef U8G2_USE_DYNAMIC_ALLOC
- *page_cnt = 8;
- return 0;
- #else
- static uint8_t buf[1024];
- *page_cnt = 8;
- return buf;
- #endif
- }
编写移植函数
精简源码之后,还需要编写如下的配置函数。
因为RVB2601板子上的OLED是SPI接口,因此需要在函数中,调用对应引脚的高低电平设置函数,以实现U8g2对OLED的SPI引脚的控制。另外还要赋予U8g2一个oled的初始化函数,可以使用CDK中hello_world程序中的oled_init函数。最后还要赋予U8g2一个延时函数,可以使用CDK中hello_world程序中的Delay函数。
u8x8_gpio_and_delay
- uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
- {
- switch (msg)
- {
- case U8X8_MSG_GPIO_SPI_DATA:
- lcd_sdin((uint8_t)arg_int);
- break;
- case U8X8_MSG_GPIO_SPI_CLOCK:
- lcd_sclk(arg_int);
- break;
- case U8X8_MSG_GPIO_AND_DELAY_INIT:
- oled_init();
- Delay(1);
- break;
- case U8X8_MSG_DELAY_MILLI:
- Delay(arg_int);
- break;
- case U8X8_MSG_GPIO_CS:
- lcd_cs((uint8_t)arg_int);
- case U8X8_MSG_GPIO_DC:
- lcd_dc((uint8_t)arg_int);
- break;
- case U8X8_MSG_GPIO_RESET:
- break;
- }
- return 1;
- }
u8g2Init
U8g2的初始化,可以调用下面这个u8g2_Setup_ssd1306_128x64_noname_1函数(最后的1代表128字节页大小),该函数的4个参数含义:
- u8g2:传入的U8g2结构体
- U8G2_R0:默认使用U8G2_R0即可(用于配置屏幕是否要旋转)
- u8x8_byte_4wire_sw_spi:使用4线的软件SPI驱动,该函数由U8g2源码提供
- u8x8_gpio_and_delay:就是上面我们写的配置函数
- void u8g2Init(u8g2_t *u8g2)
- {
- u8g2_Setup_ssd1306_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, u8x8_gpio_and_delay);
- u8g2_InitDisplay(u8g2);
- u8g2_SetPowerSave(u8g2, 0);
- }
注:以上函数可以放到hello_world例程的oled.c文件中。
显示测试函数
使用U8g2提供的测试函数,用于查看显示效果
- void draw(u8g2_t *u8g2)
- {
- u8g2_SetFontMode(u8g2, 1);
- u8g2_SetFontDirection(u8g2, 0);
- u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(u8g2, 0, 20, "U");
-
- u8g2_SetFontDirection(u8g2, 1);
- u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
- u8g2_DrawStr(u8g2, 21,8,"8");
-
- u8g2_SetFontDirection(u8g2, 0);
- u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
- u8g2_DrawStr(u8g2, 51,30,"g");
- u8g2_DrawStr(u8g2, 67,30,"\xb2");
-
- u8g2_DrawHLine(u8g2, 2, 35, 47);
- u8g2_DrawHLine(u8g2, 3, 36, 47);
- u8g2_DrawVLine(u8g2, 45, 32, 12);
- u8g2_DrawVLine(u8g2, 46, 33, 12);
-
- u8g2_SetFont(u8g2, u8g2_font_4x6_tr);
- u8g2_DrawStr(u8g2, 1,54,"github.com/olikraus/u8g2");
- }
源码加入到CDK编译
在CDK的hello_world例程的基础上进行修改。
添加u8g2源码到工程
左侧工程目录添加U8g2源码,然后工程上右键,第一个Options for xxx,继续进行工程的配置,主要是添加U8g2的头文件搜寻目录,如下:
主函数
在hello_world例程的基础上,修改主函数,主要就是去掉原来的oled_init,改用u8g2Init,while(1)中调用U8g2的测试函数
- #include <stdlib.h>
- #include <string.h>
- #include <aos/aos.h>
- #include "aos/cli.h"
- #include "main.h"
- #include "app_init.h"
- #include "oled.h"
-
- #define TAG "app"
-
- int main(void)
- {
- board_yoc_init();
- LOGD(TAG, "%s\n", aos_get_app_version());
-
-
- u8g2_t u8g2;
- u8g2Init(&u8g2);
-
- while (1)
- {
-
-
- u8g2_FirstPage(&u8g2);
- do
- {
- draw(&u8g2);
- } while (u8g2_NextPage(&u8g2));
-
-
- }
- return 0;
- }
测试效果
CDK中编译程序,下载运行,效果如下:
利用U8g2库,可以方便的进行图形的和字符的显示,测试视频:
总结
本篇介绍了如何将U8g2图形库移植到RVB2601板子中,通过CDK开发环境进行编译测试。
|