【U8G2库移植到STM32F103C8T6上】

您所在的位置:网站首页 stm32f103c8t6移植到stm32f103c6t6 【U8G2库移植到STM32F103C8T6上】

【U8G2库移植到STM32F103C8T6上】

2023-06-10 16:55| 来源: 网络整理| 查看: 265

文章目录 前言一、U8G2是什么?二、移植步骤1.软件i2c移植(1).U8G2库的下载(2).新建一个工程STM32工程(3).修改U8G2库(4).编写配置函数(5).测试代码(6).主函数代码 2.实验现象(1)proteus中查看实验现象

前言

最近在B站上刷到了一位up主设计的oled丝滑界面WouoUI,一个优雅得比较像话的UI框架,128 * 64 经过询问,得知up用的是U8G2库,U8G2多用于arduino编译器上,但是我们学校常用的是stm32。 所以经过一段时间的研究,我将U8G2库移植到了stm32f103c8t6上进行使用。

一、U8G2是什么?

关于U8G2的使用,可以参考一下这个博主的文章:深入学习Arduino u8g2 OLED库,一篇就够,写的非常详细。但是他介绍的是arduino平台的使用,stm32用法也差不多。

二、移植步骤 1.软件i2c移植

移植参考了以下两篇文章:U8G2库移植到STM32平台上 U8g2图形库与STM32移植(I2C,软件与硬件)

(1).U8G2库的下载

U8G2库是一个开源的github项目,通过github可以直接下载 。U8G2下载地址

(2).新建一个工程STM32工程

新建一个工程,并且初始化一个IIC。 建立oled.h和oled.c文件

oled.c

#include "sys.h" #include "oled.h" //初始化IIC void IIC_Init(void) { RCC->APB2ENR|=1CRL|=0X33000000; }

oled.h

#ifndef __OLED_H #define __OLED_H #include "sys.h" void IIC_Init(void); #endif (3).修改U8G2库

打开下载的u8g2库,我们用到的只有crsc这个文件夹。 打开csrc文件夹,可以看到里面有许多.c文件。有许多U8x8_d_*****类型的c文件,这是针对不同的驱动芯片所写的驱动程序,我们只需要选择我们需要的就行了,其他的在移植到自己的工程的时候可以都删除。我们此次使用的是ssd1306,因此在移植的时候,只保留U8x8_d_ssd1306_128x64_noname.c相关的驱动程序就可以了。 在这里插入图片描述

然后将csrc文件夹下面的文件都复制到stm32的工程中,建立好的工程如下图。 在这里插入图片描述

修改u8g2_d_setup.c中的函数,这里只保留u8g2_Setup_ssd1306_i2c_128x64_noname_f()这个函数,其他的可以注释或者删除。

/* ssd1306 f */ void u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2_t *u8g2, const u8g2_cb_t *rotation, u8x8_msg_cb byte_cb, u8x8_msg_cb gpio_and_delay_cb) { uint8_t tile_buf_height; uint8_t *buf; u8g2_SetupDisplay(u8g2, u8x8_d_ssd1306_128x64_noname, u8x8_cad_ssd13xx_fast_i2c, byte_cb, gpio_and_delay_cb); buf = u8g2_m_16_8_f(&tile_buf_height); u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation); }

注意,与这个函数看起来十分相似的函数的有:

u8g2_Setup_ssd1306_128x64_noname_1 u8g2_Setup_ssd1306_128x64_noname_2 u8g2_Setup_ssd1306_128x64_noname_f u8g2_Setup_ssd1306_i2c_128x64_noname_1 u8g2_Setup_ssd1306_i2c_128x64_noname_2 u8g2_Setup_ssd1306_i2c_128x64_noname_f 其中,前面3个,是给SPI接口的OLED用的,函数最后的数字或字母,代表显示时的buf大小: 1:128字节 2:256字节 f:1024字节

再修改u8g2_d_memory.c中的函数,由于用到的u8g2_Setup_ssd1306_i2c_128x64_noname_f()函数中,只调用了u8g2_m_16_8_f()这个函数,所以留下这个函数,其它的函数一定要删掉或注释掉,否则编译时很可能会提示内存不足。

uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt) { #ifdef U8G2_USE_DYNAMIC_ALLOC *page_cnt = 8; return 0; #else static uint8_t buf[1024]; *page_cnt = 8; return buf; #endif }

接下来修改字库u8g2_fonts.c,选择要使用的字库,否则会提示内存不足。这里我们保留 uint8_t u8g2_font_inb30_mn[807] uint8_t u8g2_font_inb24_mf[8821] uint8_t u8g2_font_4x6_tr[723] 这三个字库。

(4).编写配置函数

U8g2 已经包含了 SSD1306 的驱动,只需要添加一个函数u8x8_gpio_and_delay() 用于模拟时序即可。官方文件给出了一个函数的编写模板为:

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: // called once during init phase of u8g2/u8x8 break; // can be used to setup pins case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second break; case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds break; /* and many other cases */ case U8X8_MSG_GPIO_MENU_HOME: u8x8_SetGPIOResult(u8x8, /* get menu home pin state */ 0); break; default: u8x8_SetGPIOResult(u8x8, 1); // default return value break; } return 1; }

以下是一个写法案例:

uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { switch (msg) { case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds __NOP(); break; case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds for (uint16_t n = 0; n BSRR=1 RCC->APB2ENR|=1CRL|=0X33000000; } uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) { switch (msg) { case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds __NOP(); break; case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds for (uint16_t n = 0; n BSRR=1 u8g2_ClearBuffer(u8g2); u8g2_SetFontMode(u8g2, 1); u8g2_SetFontDirection(u8g2, 0); 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"); 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, 1,54,"github.com/olikraus/u8g2"); u8g2_SendBuffer(u8g2); delay_ms(1000); } (6).主函数代码

main.c

#include "sys.h" #include "delay.h" #include "oled.h" int main(void) { u8g2_t u8g2; Stm32_Clock_Init(9); delay_init(72); IIC_Init(); u8g2Init(&u8g2); draw(&u8g2); while(1) { } }

或者:

#include "delay.h" #include "sys.h" #include "u8g2.h" int main(void) { delay_init(); IIC_Init(); u8g2_t u8g2; u8g2Init(&u8g2); while(1) { u8g2_FirstPage(&u8g2); do { draw(&u8g2); } while (u8g2_NextPage(&u8g2)); } } 2.实验现象 (1)proteus中查看实验现象

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3