STM32移植u8g2图形库

1.从GitHub上下载源代码,https://github.com/olikraus/u8g2

2.复制csrc文件夹(这是u8g2库在C语言环境下的源文件)到工程文件中,在所有的驱动文件(即u8x8_d_开头的文件)中只保留u8x8_d_ssd1306_128x64_noname.c(这是与以ssd1306为驱动芯片的0.96/1.3寸OLED屏幕进行通讯的实现函数),然后将其重命名为u8g2。

3.将文件加入到工程中,首先添加头文件路径,魔术棒--C++--Include Paths,然后添加组,取名为u8g2,再将u8g2文件夹下的所有以.c结尾的文件加进去。

4.打开u8g2下的u8g2_d_Setup.c和u8g2_d_memory.c文件,去掉其他无用的驱动函数,在u8g2_d_Setup.c文件中,保留u8g2_Setup_ssd1306_i2c_128x64_noname_f,在u8g2_d_memory.c文件中,保留*u8g2_m_16_8_f(保留这个的原因是在这个函数u8g2_Setup_ssd1306_i2c_128x64_noname_f中被用到了)

5.编写回调函数,将我们使用到的引脚和延时函数传递给u8g2,该怎么写呢,是什么样的一个形式呢,在u8g2_Setup_ssd1306_i2c_128x64_noname_f函数中找到最后一个参数u8x8_msg_cb gpio_and_delay_cb,右击跳转到定义处。其实官方早就写好了,我们打开源代码,找到sys文件夹,点开arm,在stm32l031x6文件夹中,打开i2c_test中的u8x8cb.c文件,将其全部复制过来就行,你会发现和我们右击跳转到定义处看到的形式是一样的。

6.修改回调函数,在第一种情况case U8X8_MSG_GPIO_AND_DELAY_INIT将其替换成自己OLED的引脚初始化函数,在其下方可以看见注释/* only support for software I2C*/,只支持软件I2C,然后在 case U8X8_MSG_DELAY_MILLI下,换成自己的毫秒延时函数,参数换成它给的参数arg_int,同理接着在case U8X8_MSG_DELAY_I2C下,换成自己的微妙延时函数,参数用它现成的,最后是编码高低电平,arg_int = 0,表示低电平,反之则为高电平 。其他部分可以删掉(软件i2c实现的话)

uint8_t u8x8_gpio_and_delay_stm32l0(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*/
		OLED_Init();
      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<=2?5:1);
      break;
    
    case U8X8_MSG_GPIO_I2C_CLOCK:
      
      if ( arg_int == 0 )
      {
		GPIO_ResetBits(GPIOA,GPIO_Pin_0);
      }
      else
      {
		GPIO_SetBits(GPIOA,GPIO_Pin_0);
	  }

      break;
    case U8X8_MSG_GPIO_I2C_DATA:
      
      if ( arg_int == 0 )
	  {
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);
      }
      else
	  {
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
      }
      break;

    default:
      u8x8_SetGPIOResult(u8x8, 1);
      break;
  }
  return 1;
}

7.初始化结构体,在使用u8g2时需要先进行初始化

void u8g2_Init(u8g2_t *u8g2)
{
	
  u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2,U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_stm32l0);
  u8g2_InitDisplay(u8g2);  //初始化了显示屏
  u8g2_ClearDisplay(u8g2);  //清除了显示屏的内容,将所有像素都设置为黑色
  u8g2_SetPowerSave(u8g2,0);  //关闭显示屏的省电模式,即打开显示屏
}

8.展示u8g2官方logo

u8g2_FirstPage(&u8g2);
        do{
            u8g2_SetFontMode(&u8g2,1); //设置字体模式,通常为透明模式(1)或实色模式(0)。
            u8g2_SetFontDirection(&u8g2,0);  //设置文本的书写方向,0 通常是水平,1 可能是垂直或其他方向,具体取决于显示器的特性和库的定义。
            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");  //绘制一个特殊字符-上标2
            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,3,54,"github.com/o1ikraus/u8g2");
    
        } while (u8g2_NextPage(&u8g2));

可能会遇到的问题:

代码没问题但是会出现很多报错,解决方案如下

将optimzation的优化等级拉高(因为字符库所占内存太大了),然后是勾选右下角的C99mode,其他的就没有什么问题了,只要按照以上教程一步一步来,一定要细心。最后附上源码

#include "stm32f10x.h"                  // Device header
#include "oled.h"
#include "delay.h"
#include "u8g2.h"

u8g2_t u8g2;

uint8_t u8x8_gpio_and_delay_stm32l0(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*/
		OLED_Init();
      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<=2?5:1);
      break;
    
    case U8X8_MSG_GPIO_I2C_CLOCK:
      
      if ( arg_int == 0 )
      {
		GPIO_ResetBits(GPIOA,GPIO_Pin_0);
      }
      else
      {
		GPIO_SetBits(GPIOA,GPIO_Pin_0);
	  }

      break;
    case U8X8_MSG_GPIO_I2C_DATA:
      
      if ( arg_int == 0 )
	  {
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);
      }
      else
	  {
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
      }
      break;

    default:
      u8x8_SetGPIOResult(u8x8, 1);
      break;
  }
  return 1;
}

void u8g2_Init(u8g2_t *u8g2)
{
	
  u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2,U8G2_R0, u8x8_byte_sw_i2c, u8x8_gpio_and_delay_stm32l0);
  u8g2_InitDisplay(u8g2);  //初始化了显示屏
  u8g2_ClearDisplay(u8g2);  //清除了显示屏的内容,将所有像素都设置为黑色
  u8g2_SetPowerSave(u8g2,0);  //关闭显示屏的省电模式,即打开显示屏
}

// 初始化函数
void init_system() {
    delay_init();
    OLED_Init();
	u8g2_Init(&u8g2);
    //OLED_ColorTurn(0);  // 反色显示
    //OLED_DisplayTurn(0); // 正常显示
}

int main()
{
	init_system();
	
	while(1)
	{
		u8g2_FirstPage(&u8g2);
		do{
			u8g2_SetFontMode(&u8g2,1); //设置字体模式,通常为透明模式(1)或实色模式(0)。
			u8g2_SetFontDirection(&u8g2,0);  //设置文本的书写方向,0 通常是水平,1 可能是垂直或其他方向,具体取决于显示器的特性和库的定义。
			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");  //绘制一个特殊字符-上标2
			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,3,54,"github.com/o1ikraus/u8g2");
	
		} while (u8g2_NextPage(&u8g2));
	}
}


现象:

如果看到了这个界面,那么恭喜你,u8g2库在stm32上就移植成功了,接下来你可以考虑考虑利用u8g2库制作一个喜欢的动画,或者编写一个丝滑有趣的多级菜单等等等等

总结:第一次写博客,记录一下移植过程,花费了不少时间,希望在此总结一下,节省一下大家的时间。分享一下我在B站上看的学习教程吧,接下来我要为我的stm32手表编写一个有旋转太空人动画的ui以及多级菜单啦

https://www.bilibili.com/video/BV1R8411y71t?vd_source=792680e349bbb2cec19f4514ab1472c7
https://www.bilibili.com/video/BV1ew411Y7FPvd_source=792680e349bbb2cec19f4514ab1472c7

如果有什么问题,欢迎交流

### STM32移植U8g2图形库教程 #### 准备工作 为了成功将U8g2图形库移植STM32平台,需先完成一系列准备工作。这包括但不限于安装必要的开发环境以及配置硬件连接。 - 安装Keil MDK或其他支持STM32的IDE。 - 使用STM32CubeMX创建新项目并设置好目标单片机型号及其外设参数,特别是要确保启用了I2C通信接口用于与OLED屏幕交互[^1]。 #### 移植步骤详解 ##### 修改源代码结构 针对特定应用需求调整原始U8g2库文件: - **精简不必要的部分**:移除`u8g2_d_setup.c` 和 `u8g2_d_memory.c` 中不适用于当前项目的功能模块,减少资源占用。 - **适配底层驱动程序**:依据具体使用的微控制器架构,在`u8x8_gpio_and_delay` 文件内定义适合于STM32 HAL库调用方式的GPIO操作和延时处理函数;同时实现`u8g2Init()` 来初始化显示屏设备。 ##### 编写自定义函数 按照官方文档指导编写几个关键性的辅助方法来满足实际应用场景的要求: - 实现一个能够正确发送命令给显示器的方法; - 构建读取状态寄存器返回值的功能; - 设计数据传输机制以便高效地向屏幕上绘制图像或文字内容[^4]。 ```cpp // 示例:初始化 OLED 显示屏 void init_OLED(void){ /* 初始化 I2C 接口 */ HAL_I2C_MspInit(&hi2c1); /* 调用 U8G2 库提供的初始化 API */ u8g2_Setup_ssd1306_i2c_128x64_noname_f( &u8g2, // 指针指向实例化对象 U8G2_R0, // 屏幕旋转方向 u8x8_byte_sw_i2c, // 数据传送模式 (软件模拟) u8x8_gpio_and_delay_stm32 // GPIO 控制及延迟处理回调 ); } ``` #### 测试验证阶段 最后一步是对整个系统的稳定性和性能进行全面评估。可以通过运行简单的演示例子来进行初步检验,比如显示固定的字符串或者图案等简单任务。如果一切正常,则说明移植工作已经顺利完成[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值