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
如果有什么问题,欢迎交流
标签:u8g2,DELAY,U8X8,int,STM32,arg,图形库,u8x8 From: https://blog.csdn.net/2301_80298525/article/details/143827741