U8g2 软件i2c移植到stm32

文章目录

  • U8g2 软件i2c移植到stm32
    • 第一步:准备资料
    • 第二步写驱动:
    • 第三步:修改u8g2源文件
      • 1.修改`u8g2_d_setup.c`
      • 2.修改`u8g2_d_memory.c`
    • 第四步:开始写main.cpp
      • 1.C++引入C文件需要像这样,否则会报错提示找不到函数/信息丢失等
      • 2.主函数添加代码
      • 效果图片
    • !!!可能存在的报错(必看)
      • 1.C++类兼容错误(使用C忽略)
      • 2.报内存超出错误 No space in execution regions
        • keil版
        • EIDE版

使用stm32f407,软件i2c驱动oled屏幕
屏幕为 128*64,0.96寸 单色oled屏,驱动芯片ssd1306
开发环境: VSCODE+EIDE
开发语言: C/C++混编

第一步:准备资料

U8g2源码https://github.com/olikraus/u8g2下载
下载解压以后的目录

我们主要是要 csrc 文件夹中的内容
1.将该文件夹添加到你的工程目录中,随便改名,我这里改名叫U8g2_drv
2.不要忘了在将文件夹添加到包含目录

图片不完整,还有很多,有几点注意以下:
1.mui开头的文件不用添加
2.u8x8_d_*****.c等是驱动文件,选择我们要的,u8x8_d_ssd1306_128x64_noname.c,其它可以添加也可以不添加
3.除上述不添加的,添加其它.c文件
其中my_u8g2.c是用来存放我们自己写的代码,主要是驱动内容

第二步写驱动:

目标: PE0-SCL PE1-SDA 软件IIC


my_u8g2.c文件

#include "my_u8g2.h"//宏定义,方便改值
#define SCL_Pin GPIO_PIN_0
#define SDA_Pin GPIO_PIN_1
#define I2C_GPIO GPIOEvoid I2C_init(void)
{GPIO_RCC_ENABLE(I2C_GPIO);//其它地方定义的函数,具体作用是开启传进来的时钟,就不放出来了GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = SCL_Pin|SDA_Pin;//使能对应引脚GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(I2C_GPIO, &GPIO_InitStruct);
}//构建u8g2需要的回调函数
uint8_t STM32_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 secondsHAL_Delay(10);break;case U8X8_MSG_DELAY_MILLI:           // delay arg_int * 1 milli secondHAL_Delay(1);break;case U8X8_MSG_DELAY_I2C:            // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHzHAL_Delay_us(5);                        // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25uscase U8X8_MSG_GPIO_I2C_CLOCK:     // arg_int=0: Output low at I2C clock pinif(arg_int == 1) {HAL_GPIO_WritePin(I2C_GPIO, SCL_Pin, GPIO_PIN_SET);}else if(arg_int == 0){HAL_GPIO_WritePin(I2C_GPIO, SCL_Pin, GPIO_PIN_RESET);  }          break;                          // arg_int=1: Input dir with pullup high for I2C clock pincase U8X8_MSG_GPIO_I2C_DATA:     // arg_int=0: Output low at I2C data pinif(arg_int == 1) {HAL_GPIO_WritePin(I2C_GPIO, SDA_Pin, GPIO_PIN_SET);}else if(arg_int == 0){HAL_GPIO_WritePin(I2C_GPIO, SDA_Pin, GPIO_PIN_RESET);  }         break;                            // arg_int=1: Input dir with pullup high for I2C data pindefault:u8x8_SetGPIOResult(u8x8, 1);      // default return valuebreak;}return 1;
}

my_u8g2.h文件

#ifndef _MY_U8G2_H__
#define _MY_U8G2_H__#include "my_sys.h"
#include "u8g2.h"void I2C_init(void);
uint8_t STM32_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);#endif

第三步:修改u8g2源文件

1.修改u8g2_d_setup.c

注释所有函数,
保留以下两个函数,其它不需要做更改

/* ssd1306 */
/* ssd1306 1 *///GXT
void u8g2_Setup_ssd1306_i2c_128x64_noname_1(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_1(&tile_buf_height);u8g2_SetupBuffer(u8g2, buf, tile_buf_height, u8g2_ll_hvline_vertical_top_lsb, rotation);
}/* ssd1306 f *///GXT
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);
}

2.修改u8g2_d_memory.c

注释所有函数,然后编译,查找报错信息,看缺少什么函数,找到他并相应取消注释即可
当然现在对于我这个芯片已经是找到了,直接拿给你,如果你的屏幕不一样,就要用你自己缺的
同样也是两个函数

uint8_t *u8g2_m_16_8_1(uint8_t *page_cnt)
{#ifdef U8G2_USE_DYNAMIC_ALLOC*page_cnt = 1;return 0;#elsestatic uint8_t buf[128];*page_cnt = 1;return buf;#endif
}uint8_t *u8g2_m_16_8_f(uint8_t *page_cnt)
{#ifdef U8G2_USE_DYNAMIC_ALLOC*page_cnt = 8;return 0;#elsestatic uint8_t buf[1024];*page_cnt = 8;return buf;#endif
}

至此修改工作已经完成,已经完成一大半了,剩下就比较简单了

第四步:开始写main.cpp

为什么是main.cpp呢,因为我的环境是C/C++混编,对于你们就是main.c就行了,区别会讲明

1.C++引入C文件需要像这样,否则会报错提示找不到函数/信息丢失等

//C++版本这样写
extern "C" //C++文件调用c文件
{#include "u8g2.h"#include "my_u8g2.h"//这个文件就是我们自己写的文件
}//C版本这样写
#include "u8g2.h"
#include "my_u8g2.h"//这个文件就是我们自己写的文件

2.主函数添加代码

int main(void)
{.....//系统初始化I2C_init();//初始化I2C引脚,我们自己的函数u8g2_t u8g2;//定义结构体u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, STM32_gpio_and_delay);  // init u8g2 structure//注意上一句STM32_gpio_and_delay是我们自己定义的那个函数u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,u8g2_SetPowerSave(&u8g2, 0); // wake up display//********初始化完成***********////*******测试代码开始*******//u8g2_ClearBuffer(&u8g2);u8g2_SendBuffer(&u8g2);//清屏u8g2_SetFont(&u8g2,u8g2_font_DigitalDiscoThin_tf);u8g2_DrawStr(&u8g2,30,50,"Test_code");u8g2_SendBuffer(&u8g2);u8g2_DrawCircle(&u8g2,64,32,10,U8G2_DRAW_ALL);//在屏幕中间画个圆u8g2_SendBuffer(&u8g2);
}

接着就可以编译下载了


效果图片

!!!可能存在的报错(必看)

1.C++类兼容错误(使用C忽略)

1.可能是头文件引用等错误
2.可能是–cpp11 --c99 等错误
VSCODE中EIDE解决方法:

##########################################################################################
#                        Append Compiler Options For Source Files
#
# syntax:
#   <your matcher expr>: <your compiler command>
#
# examples:
#   'main.cpp':           --cpp11 -Og ...
#   'src/*.c':            -gnu -O2 ...
#   'src/lib/**/*.cpp':   --cpp11 -Os ...
#   '!Application/*.c':   -O0
#   '**/*.c':             -O2 -gnu ...
#
# For more syntax, please refer to: https://www.npmjs.com/package/micromatch
#
##########################################################################################version: '1.0'#
# for source files with filesystem paths
#
files:
#   './test/**/*.c': --c99'./MY-DRIVERS/**/*.c': --cpp11'./MY-DRIVERS/**/*.cpp': --cpp11'./Core/**/*.c': --cpp11'./Core/**/*.cpp': --cpp11
#
# for source files with virtual paths
#
virtualPathFiles:
#   'virtual_folder/**/*.c': --c99

2.报内存超出错误 No space in execution regions


先排查原因,首先注释上文main.c中的
u8g2_SetFont(&u8g2,u8g2_font_DigitalDiscoThin_tf);
u8g2_DrawStr(&u8g2,30,50,“Test_code”);
u8g2_SendBuffer(&u8g2);
等三句话,主要是u8g2_SetFont函数


如果还报错,需要更改代码优化等级

keil版

在keil中实测改到level 1就可以了
优化等级改高了可能会出现意料之外的优化结果,特别是使用系统等(非裸机)

EIDE版

1.打开构建器选项
2.选择C/C++编译器
选择更换代码优化级别,经实测可以改成level 1或者-Ospace(for code size)
我最终还是选择了-Ospace(for code size)

U8g2 软件i2c移植到stm32相关推荐

  1. U8G2库移植到STM32平台上

    U8G2库简介 U8g2是嵌入式设备的单色图形库,一句话简单明了.主要应用于嵌入式设备,包括我们常见的单片机: 建议先看这篇博客的介绍,写的比较好u8g2库的使用 这篇博客介绍了对于u8g2的使用,但 ...

  2. STM-32:I2C通信协议—软件I2C读写MPU6050

    目录 一.I2C通信 二.硬件电路 三.I2C时序基本单元 3.1起始和终止 3.1.1起始条件 3.1.2终止条件 3.2发送一个字节 3.3接收一个字节 3.4发送应答 3.5接收应答 四.I2C ...

  3. STM32 软件 I2C Source Files (No Clock Strech)

    STM32 软件 I2C Source Files (No Clock Strech) ** 验证程序:** const uint8_t ucPattern[8] = { 0x55, 0xAA, 0x ...

  4. 【STM32】软件I2C的使用 —— 看这一篇就够了(附代码)

    欢迎来到我的博客.今天我想向大家介绍一下STM32软件I2C功能. 首先,让我们来了解一下I2C(Inter-Integrated Circuit)总线.I2C是一种串行通信总线,最初由Philips ...

  5. STM32软件 I2C Master (不支持Clock stretch)

    软件 I2C 搞定了. 继续搞案子. 没事换换换,STM32F103C8 换 C6. 给自己找事! Header File <SoftIIC.h> /******************* ...

  6. harmonyos能否移植到MCU,HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验

    HarmonyOS(LiteOs_m) 官方例程移植到STM32初体验 硬件平台 基于正点原子战舰V3开发板 MCU:STM32F103ZET6 片上SRAM大小:64KBytes 片上FLASH大小 ...

  7. 软件I2C读写MPU6050代码

    1.硬件电路 SCL引到了STM32的PB10号引脚,SDA引到了PB11号引脚 软件I2C协议: 用普通GPIO口,手动反转电平实现协议,不需要STM32内部的外设资源支持,故端口是可以任意指定 M ...

  8. GUI Guider设计UI界面移植到STM32

    GUI Guider设计UI界面移植到STM32 一.什么是GUI Guider 什么是 GUI-Guider? GUI Guider 是恩智浦为 LVGL 开发了一个上位机GUI 设计工具,可以通过 ...

  9. 触摸控制芯片MPR121驱动移植(STM32)

    本文记录将arduino下的mpr121触摸板驱动程序移植到stam32f1 1.触摸板简介 之前买了块mpr121做主控的触摸控制板(如下图),卖家给的驱动是arduino的,最近做项目需要移植到s ...

最新文章

  1. 新生男婴自带新冠抗体,感染者母亲如今抗体消失,医生:抗体转移了
  2. FILLED is not a menber of 'cv' in opencv2.4.9
  3. mysql 关联关系
  4. java 图片上传
  5. java模块是什么6_Java 9 揭秘(6. 封装模块)
  6. 1英寸大底手机来了 是索尼的营销噱头吗?
  7. Compile error: Cannot find a C++ compiler that supports both C++11 and the specified C++ flags
  8. python输入三次密码程序_请教各位大神,为啥以下代码输入修改密码后连输错三次还是能输入...
  9. 引用数据类型Scanner,Random
  10. nginx的编译安装以及启动脚本编写
  11. 补充其他数字类型 (了解)
  12. xp系统怎么进pe修改计算机名,PE下安装原版XP系统装系统图文教程
  13. 【除夕】春晚,我只要红包(内附节目单)
  14. js文件中引入js的方法
  15. TogetherJS – 酷!在网站中添加在线实时协作功能
  16. 「有趣」基因组上除了ATCGN还能有什么字符
  17. 什么是Hadoop?大数据与Hadoop简介
  18. 跨浏览器CSS文本模糊效果
  19. siki学院愤怒的小鸟脚本
  20. mac 上双击终端执行sh文件

热门文章

  1. 数据分析学习总结笔记03:数据降维经典方法
  2. phpadmin安装
  3. 【python】程序员最浪漫的表白方式,将情书写在她的照片里
  4. Hive小练习之youtobe影音数据处理
  5. 上周工作中遇到的问题以及解决方法总结
  6. 3.3V降压1.2V高效率大电流电源芯片
  7. 933计算机大纲,2017年北京航空航天大学933控制工程综合硕士研究生考试大纲
  8. php地址隐藏最快的办法,就是这么简单!拿快车破译php?隐藏下载地址
  9. sap学习手册III
  10. python中axes什么意思_python matplotlib中axes与axis的区别是什么?