u8g2(一):移植u8g2
恬然澄静
2024年05月17日 13:34
收录于文集
共1篇

以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操作。

例:

代码块
text/x-csrc
自动换行
复制代码
#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函数例子如下:

代码块
text/x-csrc
自动换行
复制代码
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中进行声明。

结果演示

代码块
text/x-csrc
自动换行
复制代码
//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,就可以将其他字库删除,需要的时候再复制回来。