移植U8g2单色图形库驱动OLED
本小节教你将 u8g2 单色图形库移植到 STM32 单片机上,用于驱动 0.96 OLED 液晶屏显示模块。
大型的 GUI 解决方案并不适合像 0.96 OLED(128x64 像素,基于 SSD1306)这种资源紧缺型的显示模组使用,而网络上随处可见的代码资源都只是简单地实现一个字符输出功能,达不到预期的目的。幸好,在一个月黑风高的晚上,我在查阅资料中无意中发现了 u8g2,通过学习后发现该显示库支持很多种字体 fonts(英文和数字),而且具有完整的驱动函数库(直线、圆形、斜线、字符旋转镜像反白、bitmap 一应俱全)和丰富的演示 Demo,特别适合应用在嵌入式 MCU 上面。于是,我把它移植到了 STM32 上面,并写下了本章节作为记录。
u8g2是什么
u8g2 是目前在 Arduino 平台上使用最广泛的单色屏驱动库,在 Github 上超过 1.3K Star,1800 Commit。
u8g2的优势
为什么要使用 u8g2 库?也就是说,u8g2 库能带给我们的开发带来什么便利:
u8g2 库支持市面上的大部分 OLED 液晶屏显示模块;
u8g2 库功能非常丰富,而且编写有完整的驱动函数库,直接调用即可。
u8g2 库移植简单,容易使用。
0.96 OLED

我们使用的 0.96 OLED 是由 SSD1306 OLED 驱动芯片进行驱动点亮,使用 SPI 接口进行通信。
0.96 OLED 与 STM32 的引脚连接原理图:

0.96 OLED 引脚
功能描述
对应 STM32 引脚
GND
电源地
GND
VCC
3.3V
3.3V
SCL
CLK时钟
PB15
SDA
MOSI数据
PB14
RST
复位
PB13
D/C
数据/命令
PC13
需要注意的是,STM32 跟 0.96 OLED 的通信是只需要 STM32 发送指令和数据到 OLED,OLED 并不需要反馈任何数据给 STM32。因此,你可以看到 OLED 模块是只有 MOSI(SDA)引脚,没有 MISO 引脚的。
坐标系
OLED 其实就是一个 M * N 的像素点阵,想显示什么就得把具体位置的像素点亮起来。
坐标系如下图所示,左上角是原点,向右是 X 轴,向下是 Y 轴。

0.96 OLED 的坐标系要牢记清楚。
移植步骤
这里没有使用 STM32 的硬件 SPI 接口,而是使用 GPIO 口 模拟 SPI 进行通信。
进入我们上一小节实验的 MiaowLabs-Demo 文件夹,找到 MiaowLabs-Demo.ioc 工程文件,双击,打开工程。

配置完毕,点击生成代码按钮,重新生成代码。
相关链接:u8g2
先从上面相关链接,打开 Github,下载 u8g2 的代码压缩包。你可以把压缩包保持到桌面。

对压缩包解压,可以看到 u8g2-master 文件夹里有好多文件和文件夹。

我们在移植过程总主要用的是 csrc 文件夹里面的文件,其他文件夹和文件可以等有空再去探究。
在 csrc 文件夹里,点击按类型排序,可以看到有两个 .h 头文件(u8g2.h 和 u8x8.h),其他的都是 .c 源文件。其中,u8x8_d_xxx.c 之类的文件是对应屏幕驱动的文件,我们在这里使用 u8x8_d_ssd1306_128x64_noname.c。 复制 csrc 文件夹里面的两个 .h 头文件到小车项目工程里的 Inc 文件夹,复制其他的所有文件到 Src 文件夹(注意, u8x8_d_xxx.c 这类文件只保留 u8x8_d_ssd1306_128x64_noname.c)。
其中 u8x8_d_ssd1306_128x64_noname.c 是随 oled 屏的驱动芯片来选择的(这里 OLED 的驱动芯片是 ssd1306 )


使用 MDK-ARM 打开工程,把复制到 Src 文件夹中的源文件都加入到工程的 Application/User 文件夹中去。

在 main.c 中添加两个 .h 头文件:

新建一个文件,保存到 Inc 文件夹,命名为 oled.h,敲入以下代码:
新建一个文件,保存到 Src 文件夹,命名为 oled.c。
然后在再加入以下代码,即创建一个回调函数(可根据相关的宏来知其意,比如U8X8_MSG_GPIO_SPI_DATA就是表示软件模拟spi的数据管脚,那个arg_int表示是将当前管脚置高还是复位,其中的OLED_Init()是OLED初始化函数):
裁剪 u8g2_d_setup.c u8g2_d_memory.c 文件中与 ssd1306 无关的代码,减小代码体积,ram用量。
u8g2_d_setup.c 只保留 u8g2_Setup_ssd1306_128x64_noname_f 函数,其他全部删掉。

u8g2_d_memory.c 只保留 *u8g2_m_16_8_f 函数,其他全部删掉。

在 main.h 头文件加入 oled.h 头文件。

在主函数中初始化 u8g2,先创建 u8g2 的句柄,并创建一个临时变量 nTemp:

修改 main() 函数,初始化 u8g2 显示库,增加显示代码。

在主循环中添加以下代码:

重新编译,下载,可以看到三个循环变化圆环不断地变化。
如果我们想显示数据,比如显示小车的实时角度,那该怎么办呢?
其实也并不困难。我们先在初始化部分对字体设置函数 u8g2_SetFont 进行初始化。
然后,声明一个数组 char cStr[3];。
再写好功能部分代码。
值得注意的是,我们要先使用标准库函数 sprintf() 对角度数据(原来的格式为浮点型)格式化输出为字符串,再使用函数 u8g2_DrawStr() 显示到 OLED 显示器上。
最后更新于
这有帮助吗?