使用U8G库在STM32上实现基于I2C协议的OLED显示

【STM32】基于I2C协议的OLED显示(利用U82G库)

文章目录

  • 【STM32】基于I2C协议的OLED显示(利用U82G库)
  • 一、实验背景
  • 二、U8g2介绍
  • (一)获取
  • (二)简介
  • 三、实践
  • (一)CubexMX配置
  • (二)U8g2配置
  • (三)代码
  • 实验结果
  • 四、总结
  • 一、实验背景

    (一)、实验目的:

    1、了解I2C协议的基本原理和时序协议;

    2、掌握0.96寸OLED屏的工作原理,汉字点阵显示原理;

    3、掌握开源GUI库U82G在stm32上的移植编译方法,以及图形界面可视化技术。

    (二)、具体过程

    1、利用stm32f103的GPIO管脚、VCC和GND连接 OLED屏的I2C接口,采用cubemx设计一个HAL库程序框架,然后下载U82G源码,针对stm32f103和 0.96寸的I2C接口OLED屏,进行代码裁剪,然后移植到HAL程序程序中,完成OLED的各种显示,包括:

    1)U82G的demo例程;
    2)显示你自己的学号和名字(或网名昵称);
    3)掌握上下、左右滑动显示方法;
    4)显示一个图案(比如你的头像肖像),最好有动态效果。

    二、U8g2介绍

    (一)获取

    链接: https://pan.baidu.com/s/1wNN637GaZNAEDi8lkiJfmQ?pwd=whka
    提取码: whka

    (二)简介

    U8g2是一款用于嵌入式设备的微型显示库,专门设计用于单色LCD、OLED和eInk显示屏。它提供了一种简单而灵活的方式来控制这些显示屏,使开发人员能够轻松地在嵌入式系统中实现图形显示功能。
    关键特点和功能包括:
    支持多种显示屏:U8g2支持多种不同类型和尺寸的单色LCD、OLED和eInk显示屏。
    低内存占用:库的设计旨在尽可能减少内存占用,适用于资源受限的嵌入式系统。
    支持多种控制器:支持多种显示屏控制器,如SSD1306、SH1106、SSD1309等。
    丰富的API:提供了丰富的API,使开发人员可以轻松地绘制文本、图形、图标等。
    跨平台:可在多种嵌入式平台上运行,如Arduino、ESP8266、ESP32等。
    通过使用U8g2库,开发人员可以快速、简便地实现嵌入式系统中的图形显示功能,为项目增加更丰富的用户界面和交互体验。

    三、实践

    (一)CubexMX配置

    1、RCC配置

    2、SYS配置

    3、I2C2配置

    4、时钟树配置

    5、生成

    (二)U8g2配置

    参考:
    链接: 基于STM32移植U8g2图形库——OLED显示(HAL库)

    (三)代码

    stm32_u8g2.h:

    #ifndef __STM32_U8G2_H
    #define __STM32_U8G2_H
     
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "u8g2.h"
    /* USER CODE BEGIN Includes */
     
    /* USER CODE END Includes */
     
     
     
    /* USER CODE BEGIN Private defines */
     
    /* USER CODE END Private defines */
    #define u8         unsigned char  // ?unsigned char ????
    #define MAX_LEN    128  //
    #define OLED_ADDRESS  0x78 // oled
    #define OLED_CMD   0x00  // 
    #define OLED_DATA  0x40  // 
     
    /* USER CODE BEGIN Prototypes */
    uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
    uint8_t u8x8_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
    void u8g2Init(u8g2_t *u8g2);
    void draw(u8g2_t *u8g2);
    void testDrawPixelToFillScreen(u8g2_t *u8g2);
     
    #endif
    
    
    

    stm32_u8g2.c:

    #include "stm32_u8g2.h"
    #include "tim.h"
    #include "i2c.h"
     
     
    uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
    {
        /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
        static uint8_t buffer[128];
        static uint8_t buf_idx;
        uint8_t *data;
     
        switch (msg)
        {
        case U8X8_MSG_BYTE_INIT:
        {
            /* add your custom code to init i2c subsystem */
            MX_I2C2_Init(); //I2C初始化
        }
        break;
     
        case U8X8_MSG_BYTE_START_TRANSFER:
        {
            buf_idx = 0;
        }
        break;
     
        case U8X8_MSG_BYTE_SEND:
        {
            data = (uint8_t *)arg_ptr;
     
            while (arg_int > 0)
            {
                buffer[buf_idx++] = *data;
                data++;
                arg_int--;
            }
        }
        break;
     
        case U8X8_MSG_BYTE_END_TRANSFER:
        {
            if (HAL_I2C_Master_Transmit(&hi2c2, OLED_ADDRESS, buffer, buf_idx, 1000) != HAL_OK)
                return 0;
        }
        break;
     
        case U8X8_MSG_BYTE_SET_DC:
            break;
     
        default:
            return 0;
        }
     
        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 < 320; n++)
            {
                __NOP();
            }
            break;
        case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
            HAL_Delay(1);
            break;
        case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
            Tims_delay_us(5);
            break;                    // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
        case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
            break;                    // arg_int=1: Input dir with pullup high for I2C clock pin
        case U8X8_MSG_GPIO_I2C_DATA:  // arg_int=0: Output low at I2C data pin
            break;                    // arg_int=1: Input dir with pullup high for I2C data pin
        case U8X8_MSG_GPIO_MENU_SELECT:
            u8x8_SetGPIOResult(u8x8, /* get menu select pin state */ 0);
            break;
        case U8X8_MSG_GPIO_MENU_NEXT:
            u8x8_SetGPIOResult(u8x8, /* get menu next pin state */ 0);
            break;
        case U8X8_MSG_GPIO_MENU_PREV:
            u8x8_SetGPIOResult(u8x8, /* get menu prev pin state */ 0);
            break;
        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;
    }
     
    //U8g2的初始化,需要调用下面这个u8g2_Setup_ssd1306_128x64_noname_f函数,该函数的4个参数含义:
    //u8g2:传入的U8g2结构体
    //U8G2_R0:默认使用U8G2_R0即可(用于配置屏幕是否要旋转)
    //u8x8_byte_sw_i2c:使用软件IIC驱动,该函数由U8g2源码提供
    //u8x8_gpio_and_delay:就是上面我们写的配置函数
     
    void u8g2Init(u8g2_t *u8g2)
    {
    	u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_gpio_and_delay); // 初始化u8g2 结构体
    	u8g2_InitDisplay(u8g2);                                                                       // 
    	u8g2_SetPowerSave(u8g2, 0);                                                                   // 
    	u8g2_ClearBuffer(u8g2);
    }
     
     
    void draw(u8g2_t *u8g2)
    {
    	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);
    	HAL_Delay(1000);
    }
     
    //画点填充
    void testDrawPixelToFillScreen(u8g2_t *u8g2)
    {
      int t = 1000;
    	u8g2_ClearBuffer(u8g2);
     
      for (int j = 0; j < 64; j++)
      {
        for (int i = 0; i < 128; i++)
        {
          u8g2_DrawPixel(u8g2,i, j);
        }
      }
      HAL_Delay(1000);
    }
    
    
    

    test.h:

    #ifndef __TEST_H
    #define __TEST_H
     
    #include "main.h"
    #include "u8g2.h"
     
    void testDrawProcess(u8g2_t *u8g2);
    void testShowFont(u8g2_t *u8g2);
    void testDrawFrame(u8g2_t *u8g2);
    void testDrawRBox(u8g2_t *u8g2);
    void testDrawCircle(u8g2_t *u8g2);
    void testDrawFilledEllipse(u8g2_t *u8g2);
    void testDrawMulti(u8g2_t *u8g2);
    void testDrawXBM(u8g2_t *u8g2);
     
    void u8g2DrawTest(u8g2_t *u8g2);
     
    #endif
    
    
    

    test.c(以显示bilibili昵称为例):

    #include "test.h"
     
    //---------------U8g2测试函数
     
    #define SEND_BUFFER_DISPLAY_MS(u8g2, ms)\
      do {\
        u8g2_SendBuffer(u8g2); \
        HAL_Delay(ms);\
      }while(0);
     
     
    //进度条显示
    void testDrawProcess(u8g2_t *u8g2)
    {
    	for(int i=10;i<=80;i=i+2)
    	{
    		u8g2_ClearBuffer(u8g2); 
    			
    		char buff[20];
    		sprintf(buff,"%d%%",(int)(i/80.0*100));
    		
    		u8g2_SetFont(u8g2,u8g2_font_ncenB12_tf);
    		u8g2_DrawStr(u8g2,16,32,"STM32 U8g2");//字符显示
    		
    		u8g2_SetFont(u8g2,u8g2_font_ncenB08_tf);
    		u8g2_DrawStr(u8g2,100,49,buff);//当前进度显示
    		
    		u8g2_DrawRBox(u8g2,16,40,i,10,4);//圆角填充框矩形框
    		u8g2_DrawRFrame(u8g2,16,40,80,10,4);//圆角矩形
    		
    		u8g2_SendBuffer(u8g2);
    	}
    	HAL_Delay(500);
    }
     
     
    //字体测试 数字英文可选用 u8g2_font_ncenB..(粗) 系列字体
    //u8g2_font_unifont_t_symbols/u8g2_font_unifont_h_symbols(细 圆润)
    void testShowFont(u8g2_t *u8g2)
    {
    	int t = 1000;
    	char testStr[14] = "STM32F103C8T6";
    	
    	u8g2_ClearBuffer(u8g2);
    	
    	u8g2_SetFont(u8g2,u8g2_font_u8glib_4_tf);
    	u8g2_DrawStr(u8g2,0,5,testStr);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	
    	u8g2_SetFont(u8g2,u8g2_font_ncenB08_tf);
    	u8g2_DrawStr(u8g2,0,30,testStr);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	
        u8g2_SetFont(u8g2,u8g2_font_ncenB10_tr);
    	u8g2_DrawStr(u8g2,0,60,testStr);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    }
     
    //画空心矩形
    void testDrawFrame(u8g2_t *u8g2)
    {
    	int t = 1000;
    	int x = 16;
    	int y = 32;
    	int w = 50;
    	int h = 20;
    	u8g2_ClearBuffer(u8g2);
    	u8g2_DrawStr(u8g2,0, 15, "DrawFrame");
     
    	u8g2_DrawFrame(u8g2, x, y, w, h);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawFrame(u8g2, x+w+5, y-10, w-20, h+20);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    }
     
    //画实心圆角矩形
    void testDrawRBox(u8g2_t *u8g2)
    {
    	int t = 1000;
    	int x = 16;
    	int y = 32;
    	int w = 50;
    	int h = 20;
    	int r = 3;
    	u8g2_ClearBuffer(u8g2);
    	u8g2_DrawStr(u8g2,0, 15, "DrawRBox");
     
    	u8g2_DrawRBox(u8g2, x, y, w, h, r);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawRBox(u8g2, x+w+5, y-10, w-20, h+20, r);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    }
     
    //画空心圆
    void testDrawCircle(u8g2_t *u8g2)
    {
    	int t = 600;
    	int stx = 0;  //画图起始x
    	int sty = 16; //画图起始y
    	int with = 16;//一个图块的间隔
    	int r = 15;   //圆的半径
    	u8g2_ClearBuffer(u8g2);
    	u8g2_DrawStr(u8g2, 0, 15, "DrawCircle");
     
    	u8g2_DrawCircle(u8g2, stx, sty - 1 + with, r, U8G2_DRAW_UPPER_RIGHT); //右上
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawCircle(u8g2, stx + with, sty, r, U8G2_DRAW_LOWER_RIGHT); //右下
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawCircle(u8g2, stx - 1 + with * 3, sty - 1 + with, r, U8G2_DRAW_UPPER_LEFT); //左上
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawCircle(u8g2, stx - 1 + with * 4, sty, r, U8G2_DRAW_LOWER_LEFT); //左下
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawCircle(u8g2, stx - 1 + with * 2, sty - 1 + with * 2, r, U8G2_DRAW_ALL);//整个圆
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	
        u8g2_DrawCircle(u8g2, 32*3, 32, 31, U8G2_DRAW_ALL);//右侧整个圆
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    }
     
    //画实心椭圆
    void testDrawFilledEllipse(u8g2_t *u8g2)
    {
    	int t = 800;
    	int with = 16;//一个图块的间隔
    	int rx = 27;  //椭圆x方向的半径
    	int ry = 22;  //椭圆y方向的半径
    	u8g2_ClearBuffer(u8g2);
    	u8g2_DrawStr(u8g2,0, 14, "DrawFilledEllipse");
     
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawFilledEllipse(u8g2, 0, with, rx, ry, U8G2_DRAW_LOWER_RIGHT);//右下
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawFilledEllipse(u8g2, with * 4 - 1, with, rx, ry, U8G2_DRAW_LOWER_LEFT); //左下
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawFilledEllipse(u8g2, 0, with * 4 - 1, rx, ry, U8G2_DRAW_UPPER_RIGHT); //右上
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawFilledEllipse(u8g2, with * 4 - 1, with * 4 - 1, rx, ry, U8G2_DRAW_UPPER_LEFT); //左上
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    	u8g2_DrawFilledEllipse(u8g2, with * 6, with * 2.5, rx, ry, U8G2_DRAW_ALL);//整个椭圆
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    }
     
    //环形测试
    void testDrawMulti(u8g2_t *u8g2)
    {
    	u8g2_ClearBuffer(u8g2);
    	for (int j = 0; j < 64; j+=16)
    	{
    		for (int i = 0; i < 128; i+=16)
    		{
    			u8g2_DrawPixel(u8g2, i, j);
    			u8g2_SendBuffer(u8g2);
    		}
    	}
      
    	//实心矩形逐渐变大
        u8g2_ClearBuffer(u8g2);
    	for(int i=30; i>0; i-=2)
    	{
    		u8g2_DrawBox(u8g2,i*2,i,128-i*4,64-2*i);
    		u8g2_SendBuffer(u8g2);
    	}
    	//空心矩形逐渐变小
    	u8g2_ClearBuffer(u8g2);
    	for(int i=0; i<32; i+=2)
    	{
    		u8g2_DrawFrame(u8g2,i*2,i,128-i*4,64-2*i);
    		u8g2_SendBuffer(u8g2);
    	}
    	
    	//实心圆角矩形逐渐变大
    	u8g2_ClearBuffer(u8g2);
    	for(int i=30; i>0; i-=2)
    	{
    		u8g2_DrawRBox(u8g2,i*2,i,128-i*4,64-2*i,10-i/3);
    		u8g2_SendBuffer(u8g2);
    	}
        //空心圆角矩形逐渐变小
    	u8g2_ClearBuffer(u8g2);
    	for(int i=0; i<32; i+=2)
    	{
    		u8g2_DrawRFrame(u8g2,i*2,i,128-i*4,64-2*i,10-i/3);
    		u8g2_SendBuffer(u8g2);
    	}
    	
    	//实心圆逐渐变大
    	u8g2_ClearBuffer(u8g2);
    	for(int i=2; i<64; i+=3)
    	{
    		u8g2_DrawDisc(u8g2,64,32,i, U8G2_DRAW_ALL);
    		u8g2_SendBuffer(u8g2);
    	}
    	//空心圆逐渐变小
    	u8g2_ClearBuffer(u8g2);
    	for(int i=64; i>0; i-=3)
    	{
    		u8g2_DrawCircle(u8g2,64,32,i, U8G2_DRAW_ALL);
    		u8g2_SendBuffer(u8g2);
    	}
    	
    	//实心椭圆逐渐变大
        u8g2_ClearBuffer(u8g2);
    	for(int i=2; i<32; i+=3)
    	{
    		u8g2_DrawFilledEllipse(u8g2,64,32, i*2, i, U8G2_DRAW_ALL);
    		u8g2_SendBuffer(u8g2);
    	}
        //空心椭圆逐渐变小
        u8g2_ClearBuffer(u8g2);
    	for(int i=32; i>0; i-=3)
    	{
    		u8g2_DrawEllipse(u8g2,64,32, i*2, i, U8G2_DRAW_ALL);
    		u8g2_SendBuffer(u8g2);
    	}
    }
     
     
    // width: 128, height: 48
    const unsigned char bilibili[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe0, 0x03, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xf0, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x01, 0xfc, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x03, 0xfc, 0x00, 0x00, 0x3c, 0xc0, 0x0f, 0x00, 0x80, 0x03, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x07, 0xfc, 0x00, 0x00, 0x3c, 0xc0, 0x0f, 0x00, 0xc0, 0x07, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xfc, 0x00, 0x00, 0x3c, 0x80, 0x0f, 0x00, 0xc0, 0x07, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x80, 0x0f, 0xf8, 0x00, 0x00, 0x3c, 0x80, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x78, 0x80, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x78, 0x80, 0x0f, 0x00, 0x80, 0x07, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x80, 0x79, 0x80, 0x0f, 0x00, 0x98, 0x07, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0xe0, 0x79, 0x9f, 0x0f, 0x00, 0xbe, 0xe7, 0x01, 0xc0, 0x07, 0x10, 0x40, 0x00, 0x1f, 0xf8, 0x00, 0xe0, 0x7b, 0x1f, 0x0f, 0x00, 0xbe, 0xe7, 0x01, 0xc0, 0x87, 0x1f, 0xe0, 0x0f, 0x1f, 0xf8, 0x00, 0xe0, 0x7b, 0x1e, 0x0f, 0x00, 0x3e, 0xe7, 0x01, 0xc0, 0xe7, 0x3f, 0xe0, 0x3f, 0x1f, 0xf0, 0x00, 0xe0, 0x7b, 0x1e, 0x0f, 0x00, 0x3e, 0xe7, 0x01, 0xc0, 0xe7, 0x3f, 0xe0, 0x3f, 0x1f, 0xf0, 0x00, 0x60, 0x71, 0x1e, 0x0f, 0x00, 0x34, 0xe7, 0x01, 0xc0, 0xe7, 0x07, 0x00, 0x3f, 0x1f, 0xf0, 0x00, 0x00, 0x70, 0x00, 0x1f, 0x00, 0x00, 0x07, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0xc0, 0x73, 0x1e, 0x1f, 0x00, 0x3c, 0xc7, 0x01, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0xc0, 0x73, 0x1e, 0x1f, 0x00, 0x7c, 0xe7, 0x01, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x00, 0xc0, 0x73, 0x1e, 0x1f, 0x00, 0x7c, 0xef, 0x01, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xf0, 0x01, 0xc0, 0x77, 0x1e, 0x1e, 0x00, 0x7c, 0xef, 0x01, 0xc0, 0x07, 0x00, 0x03, 0x00, 0x1f, 0xf0, 0xff, 0xc1, 0xf7, 0x1e, 0xfe, 0x1f, 0x78, 0xef, 0x01, 0xc0, 0x07, 0x70, 0x37, 0x00, 0x1f, 0xe0, 0xff, 0x87, 0xf7, 0x1e, 0xfe, 0xff, 0x78, 0xee, 0x01, 0xc0, 0x07, 0xe0, 0x3f, 0x00, 0x1f, 0xe0, 0xff, 0x9f, 0xf7, 0x1e, 0xfe, 0xff, 0x79, 0xce, 0x01, 0xc0, 0x07, 0xc0, 0x18, 0x00, 0x1f, 0xe0, 0xff, 0xbf, 0xe7, 0x1e, 0xfe, 0xff, 0x7b, 0xce, 0x01, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0xc7, 0xbf, 0xe7, 0x1e, 0xfe, 0xf8, 0x77, 0xce, 0x01, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x0f, 0x3f, 0xe7, 0x1c, 0xfe, 0xf0, 0x77, 0xce, 0x03, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0xcf, 0x3f, 0xe7, 0x1c, 0xfe, 0xf8, 0xf3, 0xce, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xef, 0x1f, 0xe7, 0x1c, 0xfe, 0xfe, 0xf1, 0xce, 0x03, 0x80, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xe0, 0xff, 0x0f, 0xcf, 0x1c, 0xfc, 0xff, 0xf0, 0xc0, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0x07, 0xe0, 0xff, 0x03, 0x06, 0x1c, 0xfc, 0x7f, 0x60, 0xc0, 0x01, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x03, 0xe0, 0xff, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    // width: 128, height: 48
    const unsigned char three_support[] U8X8_PROGMEM = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x80, 0x0f, 0xf0, 0x01, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xfd, 0xff, 0x00, 0x00, 0xc0, 0x7f, 0xfe, 0x01, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x01, 0x00, 0xc0, 0x1f, 0xf8, 0x03, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x01, 0x00, 0xc0, 0x0f, 0xf0, 0x03, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x01, 0x00, 0xc0, 0x67, 0xe6, 0x03, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x01, 0x00, 0xc0, 0x67, 0xe6, 0x03, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x00, 0x00, 0xc0, 0x67, 0xe6, 0x03, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x00, 0x00, 0xc0, 0x67, 0xee, 0x03, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x00, 0x00, 0x80, 0x7f, 0xfe, 0x01, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0xff, 0x00, 0x00, 0x80, 0x7f, 0xfe, 0x01, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0xf8, 0xf9, 0x01, 0x00, 0x00, 0xe0, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0xe0, 0xfd, 0x1f, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
     
    void testDrawXBM(u8g2_t *u8g2)
    {
    	int t = 1000;
    	u8g2_ClearBuffer(u8g2);
    	u8g2_DrawStr(u8g2,0, 14, "MOODLEE");
     
    	u8g2_DrawXBM(u8g2,0, 16, 128, 48, bilibili);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
     
    	u8g2_ClearBuffer(u8g2);
    	u8g2_DrawStr(u8g2,0, 14, "bilibili");
    	u8g2_DrawXBM(u8g2,0, 16, 128, 48, three_support);
    	SEND_BUFFER_DISPLAY_MS(u8g2,t);
    }
     
    void u8g2DrawTest(u8g2_t *u8g2)
    {
    	testDrawProcess(u8g2);
    	testDrawMulti(u8g2);
    	//testDrawFrame(u8g2);
    	//testDrawRBox(u8g2);
    	//testDrawCircle(u8g2);
    	//testDrawFilledEllipse(u8g2);
    	testShowFont(u8g2);
    	testDrawXBM(u8g2);
     
    }
    
    
    

    main函数:

    int main(void)
    {
      /* USER CODE BEGIN 1 */
     
      /* USER CODE END 1 */
     
      /* MCU Configuration--------------------------------------------------------*/
     
      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();
     
      /* USER CODE BEGIN Init */
     
      /* USER CODE END Init */
     
      /* Configure the system clock */
      SystemClock_Config();
     
      /* USER CODE BEGIN SysInit */
     
      /* USER CODE END SysInit */
     
      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_I2C2_Init();
      MX_TIM1_Init();
      /* USER CODE BEGIN 2 */
      u8g2_t u8g2;
      u8g2Init(&u8g2);	
      /* USER CODE END 2 */
     
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
        /* USER CODE END WHILE */
     
        /* USER CODE BEGIN 3 */
     
           u8g2_FirstPage(&u8g2);
           do
           {
    				 draw(&u8g2);
     
    				 u8g2DrawTest(&u8g2);
           } while (u8g2_NextPage(&u8g2));
    		
     
      }
      /* USER CODE END 3 */
    }
    
    
    

    实验结果

    OLED显示

    四、总结

    经过本次学习,我深入掌握了I2C协议与OLED显示技术,并在STM32上实现了多种显示功能。我们利用U8g2库,实现了丰富的图形界面和交互体验,感受到了嵌入式开发的魅力。
    以上为此次学习成果,若有问题,烦请指正。

    作者:weixin_50037440

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用U8G库在STM32上实现基于I2C协议的OLED显示

    发表回复