U8g2 应用笔记
1 本文目录与结构
1.1 本文的目的与背景
因DT609项目开发,接触到1602
和12864
两款单色液晶模块的驱动开发。其中1602
是带字库版本,而12864
则不是。带字库的液晶模组一大优势是内置CGRAM,支持GB2312
字体,因而软件设计时只需要将代码文件设定成GB2312
格式,通过printf
就可以处理。而对于无字库模组,则需要软件取模,制定数组后进行调用,增加了很多工作量。为提高研发效率,同时便于后期维护。在网上搜索了诸多开源的字库软件并对比后,最终选择U8g2
字库进行移植。
1.2 本文的结构
本文主要分为三个部分,首先介绍U8g2
字库,其次介绍移植流程,最后介绍移植过程中的注意事项。
2 U8g2字库移植
U8g2
是用于嵌入式设备的单色图形库。U8g2
支持基于控制器(例如SSD1306
)的单色OLED和LCD(有关支持的显示控制器的完整列表,请参阅U8g2
/ U8x8
设置指南)。
2.1 驱动层移植
参照GitHub上Porting to new MCU platform指导,本平台控制器为7565,选择FULL BUFF模式。因此驱动移植需要实现u8g2_Setup_st7565_64128n_f
函数
void u8g2_Setup_st7565_64128n_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb)
函数入参 | 含义 | 可选项 |
---|---|---|
u8g2 | 字库数据结构指针 | |
rotation | 显示方向 | 0度,90度,180度,270度 |
byte_cb* | 硬件通信方式选择 | 4线SPI,硬件SPI。。。 |
gpio_and_delay_cb** | 管脚配置及延时 |
[*]硬件平台通信方式选则4线模拟SPI连接,byte_cb
直接调用字库函数u8x8_byte_4wire_sw_spi
。
[**]gpio_and_delay_cb
实现如下:
uint8_t RegisterGPIOAndDelayFunc(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
switch (msg)
{
case U8X8_MSG_GPIO_AND_DELAY_INIT:
{
break;
}
case U8X8_MSG_DELAY_100NANO:
{
__NOP();
break;
}
case U8X8_MSG_DELAY_10MICRO:
{
LcdWaitUs(10);
break;
}
case U8X8_MSG_DELAY_MILLI:
{
LcdWaitMs(arg_int);
break;
}
case U8X8_MSG_GPIO_CS:
{
if (arg_int > 0)
{
LPC_GPIO0->SET = LCDCS;
}
else
{
LPC_GPIO0->CLR = LCDCS;
}
break;
}
case U8X8_MSG_GPIO_RESET:
{
if (arg_int > 0)
{
LPC_GPIO1->SET = LCDRST;
}
else
{
LPC_GPIO1->CLR = LCDRST;
}
break;
}
case U8X8_MSG_GPIO_SPI_DATA:
{
if (arg_int > 0)
{
LPC_GPIO1->SET = LCDSID;
}
else
{
LPC_GPIO1->CLR = LCDSID;
}
break;
}
case U8X8_MSG_GPIO_DC:
{
if (arg_int > 0)
{
LPC_GPIO2->SET = LCDA0;
}
else
{
LPC_GPIO2->CLR = LCDA0;
}
break;
}
case U8X8_MSG_GPIO_SPI_CLOCK:
{
if (arg_int > 0)
{
LPC_GPIO1->SET = LCDCLK;
}
else
{
LPC_GPIO1->CLR = LCDCLK;
}
break;
}
default:
{
return 0;
}
}
return 1;
}
完整字库初始化流程为:
2.2 应用层接口封装
U8g2
字库提供了完善的应用层接口函数,包括线、块、圆、椭圆、三角形等等,我们在其基础上又进行了一层封装,用以适配原有的菜单设计。详细函数接口有:
函数接口 | 含义 |
---|---|
ApiSetFont | 字库设定 |
LCD_EnableShow | 刷新字库buf内容,显示于屏幕 |
ApiWriteStr | 写入字符到数据结构中,不立即刷新显示 |
LcdOutText | 输出单行文本到显存,并立即刷新 |
LCD_ClearBuffer | 清空buf |
ApiSetHLine | 设置水平线 |
FlashHLine | 闪烁水平线,光标效果 |
ApiCleanHLine | 擦除水平线,清除光标 |
3 提醒
3.1 自定义中文字库制作方法
实际应用中并不需要GB2312
全部中文字符,为节约代码空间,选择建立一个自定义字库,并进行维护。
- 收集字符串文件
新建utf-8格式txt文件,将用到的中文写到其中,可以有回车换行,但是不能有ASCII字符。
- 使用下方bash命令将txt转换成map文件
echo '32-128,' > myfont.map
cat str.txt | iconv -f utf-8 -t c99 | sed 's/\\u\([0-9a-f]\{4\}\)/\$\1,\n/g' | sort | uniq | sed '/^$/d' | tr '/a-f/' '/A-F/' >> myfont.map
- 新增
buildmyfont.bat
脚本,添加下方内容后双击生成C代码后增加到u8g2_fonts.c
中。
bdfconv.exe -v -b 0 -f 1 -M ../myfont.map -n u8g2_font_myfont -o u8g2_font_myfont.c ../bdf/wenquanyi_10pt.bdf
注意: 参考文档3中的说明有误,bdfconv代码已无需修改。
3.2 精简字库代码的技巧
u8g2_fonts.c
包含字库支持的所有字体数组,可只留一个自用的字体,其余删除。u8g2_d_setup.c
包含所有的驱动函数接口,可只留至工程用到的,其余删除。