
以STM32F103为例
1. GitHub下载u8g2

u8g2
2. 删除不需要的文件
打开csrc文件夹,其中形如u8x8_d_xxxx.c的文件都是不同驱动的文件(不包括u8g2_d_memory.c 与 u8g2_d_setup.c)。本示例所使用的OLED屏幕驱动芯片为ssd1306,因此仅保留u8x8_d_1306_128x64_noname.c 。

仅保留需要的驱动文件
除了驱动文件外的其他文件全部保留,复制文件夹到自己的项目文件下。如果使用的是Keil,还需要在 “Options of Target...”(魔法棒)下将您的u8g2相对路径添加进去。

添加相对路径

管理项目文件
简而言之,这一步就是删除csrc下不需要的驱动文件,然后将文件夹复制到您自己的项目文件中。
3. 修改u8g2_d_setup.c
以使用ssd1306为例,仅保存该文件中的以下函数之一:
i2c
u8g2_Setup_ssd1306_i2c_128x64_noname_1
u8g2_Setup_ssd1306_i2c_128x64_noname_2
u8g2_Setup_ssd1306_i2c_128x64_noname_f
spi
u8g2_Setup_ssd1306_128x64_noname_1
u8g2_Setup_ssd1306_128x64_noname_2
u8g2_Setup_ssd1306_128x64_noname_f
不同后缀代表缓冲区大小不同, 1|128字节 2|256字节 f|1024字节
4. 修改u8g2_d_memory.c
初始化只用到u8g2_m_16_8_x
其中x根据u8g2_d_setup.c中的后缀选择。
其余函数可以删除。
5. 编写u8g2_Setup_ssd1306_i2c_128x64_noname_x的回调函数与u8g2_Init函数
该回调函数可以参考u8g2项目文件sys\arm\stm32|031x6\i2c_test\u8x8cb.c中的例子进行修改
具体修改内容包括:
U8X8_MSG_GPIO_AND_DELAY_INIT中内容替换为SDA与SCL的GPIO口配置程序U8X8_MSG_DELAY_MILLI与U8X8_MSG_DELAY_I2C替换为相应的ms与us延时函数U8X8_MSG_GPIO_I2C_CLOCK与U8X8_MSG_GPIO_I2C_DATA替换为SCL、SDA对应的SET与RESET操作。
例:
#include "u8g2.h"
#define IIC_SCL_GPIO_CLK_ENABLE() do{__HAL_RCC_GPIOB_CLK_ENABLE();}while(0)
#define IIC_SDA_GPIO_CLK_ENABLE() do{__HAL_RCC_GPIOB_CLK_ENABLE();}while(0)
#define IIC_SCL_GPIO_PORT GPIOB
#define IIC_SDA_GPIO_PORT GPIOB
#define IIC_SCL_GPIO_PIN GPIO_PIN_6
#define IIC_SDA_GPIO_PIN GPIO_PIN_7
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_AND_DELAY_INIT:
/* only support for software I2C*/
GPIO_InitTypeDef gpio_init_struct;
IIC_SCL_GPIO_CLK_ENABLE();
IIC_SDA_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = IIC_SCL_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
gpio_init_struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(IIC_SCL_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = IIC_SDA_GPIO_PIN;
gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
gpio_init_struct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(IIC_SDA_GPIO_PORT, &gpio_init_struct);
break;
case U8X8_MSG_DELAY_NANO:
/* not required for SW I2C */
break;
case U8X8_MSG_DELAY_10MICRO:
/* not used at the moment */
break;
case U8X8_MSG_DELAY_100NANO:
/* not used at the moment */
break;
case U8X8_MSG_DELAY_MILLI:
delay_ms(arg_int);
break;
case U8X8_MSG_DELAY_I2C:
/* arg_int is 1 or 4: 100KHz (5us) or 400KHz (1.25us) */
delay_us(arg_int u8g2_Init函数例子如下:
void u8g2_Init(u8g2_t *u8g2)
{
u8g2_Setup_ssd1306_i2c_128x64_noname_1(u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay);
u8g2_InitDisplay(u8g2);
u8g2_SetPowerSave(u8g2, 0);
u8g2_ClearBuffer(u8g2);
}
其中
u8g2_Setup_ssd1306_i2c_128x64_noname_1(u8g2, U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay) 这个函数用于设置u8g2结构体,准备初始化一个 SSD1306 型号的 OLED 显示屏,具有 128x64 的分辨率,并且使用的是 I2C 通信协议。u8g2_R0 表示初始化显示屏的默认颜色方案。u8x8_byte_sw_i2c 是一个软件实现的 I2C 通信函数,而u8x8_gpio_and_delay 就是前文所写的回调函数。
u8g2_InitDisplay(u8g2) 这个函数用于初始化显示屏。它会根据之前设置的参数来配置显示屏的硬件,如初始化通信接口、设置显示屏的初始状态等。
u8g2_SetPowerSave(u8g2, 0) 这个函数用于设置显示屏的电源模式。参数 0 表示关闭省电模式,即开启显示屏。如果传递 1,则会进入省电模式,关闭显示屏。
u8g2_ClearBuffer(u8g2) 用于清除显示屏的内部绘图缓冲区。
该回调函数与u8g2_Init函数可以放在您自己创建的oled.c之中。在oled.h中进行声明。

结果演示
//main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/OLED/oled.h"
#include "u8g2.h"
u8g2_t u8g2;
int main(void)
{
HAL_Init();
sys_stm32_clock_init(RCC_PLL_MUL9);
delay_init(72);
u8g2_Init(&u8g2);
while(1)
{
u8g2_FirstPage(&u8g2);
do{
u8g2_SetFontMode(&u8g2, 1);
u8g2_SetFontDirection(&u8g2, 0);
u8g2_SetFont(&u8g2, u8g2_font_8x13B_mr);
u8g2_DrawStr(&u8g2, 0,13, "hello world");
}while(u8g2_NextPage(&u8g2));
}
}

结果演示
问题及解决方法
链接阶段失败,报错空间不足
出现如下提示: Error: L6406E: No space in execution regions with .ANY selector matching 解决方案,删除不需要的字库文件,主要是u8g2_fonts.c与u8g8_fonts.c中的文件。 字库为大量const定义的常量,占用大量空间。
例如仅使用u8g2_font_8x13B_mr,就可以将其他字库删除,需要的时候再复制回来。