939 views|3 replies

445

Posts

0

Resources
The OP
 

【All-round small gateway|CH32V208】--8. OLED display of graphics library u8g2 [Copy link]

 
This post was last edited by dirty on 2024-7-19 22:34

This article describes how to use the u8g2 graphics library to drive the oled display. The advantages of using this graphics library are that it is powerful and has a font library that includes Chinese GB2312. It is very convenient and comprehensive to display Chinese characters. There is no need for a modulus tool to get the Chinese character dot matrix. In addition, there are many API functions that can be designed for the interface. It is highly recommended for use in actual engineering projects.

1. Preparation

This time, ssd1306 is used to drive the OLED screen, with a pixel resolution of 128*32 and an I2C interface. u8g2 is the second version of the monochrome display library, which is open source. u8g2 supports LCD and OLED, and supports many driver chips, including SSD1306. The specific supported drivers can be viewed in the resource library.

The hardware connections are as follows:

Development Board OLED

PB9 SDA

PB8 SCL

3V3 VCC

GND GND

2. Code Preparation

This project supports ssd1306 128*64/128*32 resolution, which can be selected through the following macros. During the migration, please trim as needed and delete as much as possible to avoid occupying resources.

#define SSD1306_128x64  1
#define SSD1306_128x32  2

#define SSD1306_DEVICE  SSD1306_128x32//SSD1306_128x64//

1. After cloning the u8g2 resources, use the resources in the scrc file

2. Delete u8x8_d_xxx.c non-related driver source files. Select ssd1306 128x64/128x32 (select one)

3. Select the driver chip initialization function used in the u8g2_d_setup.c source file and delete the others. Here, keep u8g2_Setup_ssd1306_i2c_128x64_noname_f/u8g2_Setup_ssd1306_i2c_128x32_univision_f

4. Modify the "u8g2_d_memory.c" file. This file actually contains the buffer corresponding to the "u8g2_d_setup.c" file. As above, block the unused ones and keep the used ones.

5. About fonts. Various fonts are defined in the "u8g2_fonts.c" file. These fonts take up a lot of space, and the unused ones are blocked according to the usage. To use the GB2312 font library, you need to enable the macro U8G2_USE_LARGE_FONTS. The specific steps are as follows:

Figure 1: Enabling the GB2312 font library

6. Two callback functions
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); Parameters byte_cb and gpio_and_delay_cb are two callback functions that need to be written. byte_cb: is a communication-related function, such as i2c write data, gpio_and_delay_cb: is a delay-related function. Communication functions are divided into hardware interfaces and software simulation methods. The official software simulation method is basically written, and you only need to simply specify the io port. The hardware method is used here. The implementation is as follows:

uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
{
      static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
      static uint8_t buf_idx;
      uint8_t *data;

      switch (msg)
      {
      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_INIT:
            /* add your custom code to init i2c subsystem */
            break;

      case U8X8_MSG_BYTE_START_TRANSFER:
            buf_idx = 0;
            break;

      case U8X8_MSG_BYTE_END_TRANSFER:
            HW_I2cWrite(buffer, buf_idx);   //硬件I2C写字节
            break;

      default:
            return 0;
      }
      return 1;
}

uint8_t u8g2_gpio_and_delay(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
      switch (msg)
      {
      case U8X8_MSG_GPIO_AND_DELAY_INIT:
            OLED_I2C_Init();    //初始化
            break;

      case U8X8_MSG_DELAY_MILLI:
            Delay_Ms(arg_int);  //延时
            break;

      case U8X8_MSG_GPIO_I2C_CLOCK:
            break;

      case U8X8_MSG_GPIO_I2C_DATA:
            break;

      default:
            return 0;
      }
      return 1; // command processed successfully.
}

7. u8g2 initialization

void u8g2_Init(u8g2_t *u8g2)
{
     #if(SSD1306_DEVICE==SSD1306_128x64)
	  u8g2_Setup_ssd1306_i2c_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8g2_gpio_and_delay); // 初始化 u8g2,硬件I2C
      #elif(SSD1306_DEVICE==SSD1306_128x32)
	  u8g2_Setup_ssd1306_i2c_128x32_univision_f(u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8g2_gpio_and_delay);
	  #endif
	  u8g2_InitDisplay(u8g2); 		//根据所选芯片初始化,完成后显示器处于关闭状态                                                                      // 根据所选的芯片进行初始化工作,初始化完成后,显示器处于关闭状态
      u8g2_SetPowerSave(u8g2, 0); 	//唤醒显示器                                                                 
      u8g2_SetContrast(u8g2, 88);  	//设置对比度                                                                
      u8g2_ClearBuffer(u8g2);    	//清除显示缓存                                                                
}

8. Design the interface

(1) Draw diagonal lines

   #if(SSD1306_DEVICE==SSD1306_128x64)
	u8g2_DrawLine(&u8g2, 0, 0, 127, 63); // 画一条线,起始坐标(0,0),终点坐标(127,63)
	u8g2_SendBuffer(&u8g2);              // 发送缓冲区数据
	u8g2_DrawLine(&u8g2, 127, 0, 0, 63);
	u8g2_SendBuffer(&u8g2);
    #elif(SSD1306_DEVICE==SSD1306_128x32)
	u8g2_DrawLine(&u8g2, 0, 0, 127, 31); // 画一条线,起始坐标(0,0),终点坐标(127,63)
    u8g2_SendBuffer(&u8g2);              // 发送缓冲区数据
    u8g2_DrawLine(&u8g2, 127, 0, 0, 31);
    u8g2_SendBuffer(&u8g2);
    #endif

(2) Draw the U8g2 logo in general, placing it horizontally, vertically, etc.

void draw(u8g2_t *u8g2)
{
	#if(SSD1306_DEVICE==SSD1306_128x64)
	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");

	#elif(SSD1306_DEVICE==SSD1306_128x32)

	u8g2_SetFontMode(u8g2, 1);              /*字体模式选择*/
	u8g2_SetFontDirection(u8g2, 0);         /*字体方向选择*/
	u8g2_SetFont(u8g2, u8g2_font_inb24_mf); /*字库选择*/
	u8g2_DrawStr(u8g2, 0, 24, "U");

	u8g2_SetFontDirection(u8g2, 1);
	u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
	u8g2_DrawStr(u8g2, 24, 8, "8");

	u8g2_SetFontDirection(u8g2, 0);
	u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
	u8g2_DrawStr(u8g2, 64, 24, "g");
	u8g2_DrawStr(u8g2, 96, 32, "\xb2");

	#endif

}

(3) Display Chinese and English. Here we display the information related to EEWorld and Qinheng.

	#if(SSD1306_DEVICE==SSD1306_128x64)
	u8g2_ClearBuffer(&u8g2);
	u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);    //选择字库
	u8g2_DrawStr(&u8g2, 0, 15, "Hello World!");

	u8g2_SetFont(&u8g2, u8g2_font_wqy16_t_chinese2);
	u8g2_DrawUTF8(&u8g2, 0, 30, "H你好世界");

	u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese2);
	u8g2_DrawUTF8(&u8g2, 0, 43, "H你好世界");
	
	u8g2_SetFont(&u8g2, u8g2_font_fur11_tr);
	u8g2_DrawUTF8(&u8g2, 0, 59, "blog.zeruns.tech");
	#elif(SSD1306_DEVICE==SSD1306_128x32)
	u8g2_ClearBuffer(&u8g2);
	u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);    //选择字库
	u8g2_DrawStr(&u8g2, 0, 14, "EEWorld");

	u8g2_SetFont(&u8g2, u8g2_font_wqy13_t_gb2312);
	u8g2_DrawUTF8(&u8g2, 0, 30, "沁恒");

	u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);    //选择字库
	u8g2_DrawStr(&u8g2, 26, 30, "CH32V208");

	u8g2_SetFont(&u8g2, u8g2_font_wqy13_t_gb2312);
	u8g2_DrawUTF8(&u8g2, 80, 30, "开发板");

	#endif

(4) Display concentric circles with gradient changes in a loop.

	while(1)
	{
	    Delay_Ms(100);
		u8g2_ClearBuffer(&u8g2);//清除缓冲区数据
		#if(SSD1306_DEVICE==SSD1306_128x64)
		if (++t >= 32)
			t = 1;
		u8g2_DrawCircle(&u8g2, 64, 32, t, U8G2_DRAW_ALL);   //画圆
		u8g2_DrawCircle(&u8g2, 32, 32, t, U8G2_DRAW_ALL);
		u8g2_DrawCircle(&u8g2, 96, 32, t, U8G2_DRAW_ALL);
		u8g2_SendBuffer(&u8g2); // 发送缓冲区数据
		#elif(SSD1306_DEVICE==SSD1306_128x32)
		if (++t >= 16)
			t = 1;
		u8g2_DrawCircle(&u8g2, 64, 16, t, U8G2_DRAW_ALL);   //画圆
		u8g2_DrawCircle(&u8g2, 32, 16, t, U8G2_DRAW_ALL);
		u8g2_DrawCircle(&u8g2, 96, 16, t, U8G2_DRAW_ALL);
		u8g2_SendBuffer(&u8g2); // 发送缓冲区数据

		#endif

	}

9. The main function is as follows. I will not go into details about adding source files of project u8g2.

int main(void)
{
	uint8_t t = 0;

    SystemCoreClockUpdate();
    Delay_Init();
    USART_Printf_Init(115200);
    printf( "SystemClk:%d\r\n", SystemCoreClock );
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );

	OLED_I2C_Init();

    u8g2_Init(&u8g2);     //初始化U8g2
	Delay_Ms(100);

    #if(SSD1306_DEVICE==SSD1306_128x64)
	u8g2_DrawLine(&u8g2, 0, 0, 127, 63); // 画一条线,起始坐标(0,0),终点坐标(127,63)
	u8g2_SendBuffer(&u8g2);              // 发送缓冲区数据
	u8g2_DrawLine(&u8g2, 127, 0, 0, 63);
	u8g2_SendBuffer(&u8g2);
    #elif(SSD1306_DEVICE==SSD1306_128x32)
	u8g2_DrawLine(&u8g2, 0, 0, 127, 31); // 画一条线,起始坐标(0,0),终点坐标(127,63)
    u8g2_SendBuffer(&u8g2);              // 发送缓冲区数据
    u8g2_DrawLine(&u8g2, 127, 0, 0, 31);
    u8g2_SendBuffer(&u8g2);
    #endif

	Delay_Ms(300);

	u8g2_ClearBuffer(&u8g2);  //清除缓冲区数据
	draw(&u8g2);
	u8g2_SendBuffer(&u8g2);
	Delay_Ms(1000);
	
	#if(SSD1306_DEVICE==SSD1306_128x64)
	u8g2_ClearBuffer(&u8g2);
	u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);    //选择字库
	u8g2_DrawStr(&u8g2, 0, 15, "Hello World!");

	u8g2_SetFont(&u8g2, u8g2_font_wqy16_t_chinese2);
	u8g2_DrawUTF8(&u8g2, 0, 30, "H你好世界");

	u8g2_SetFont(&u8g2, u8g2_font_wqy12_t_chinese2);
	u8g2_DrawUTF8(&u8g2, 0, 43, "H你好世界");
	
	
	#elif(SSD1306_DEVICE==SSD1306_128x32)
	u8g2_ClearBuffer(&u8g2);
	u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);    //选择字库
	u8g2_DrawStr(&u8g2, 0, 14, "EEWorld");

	u8g2_SetFont(&u8g2, u8g2_font_wqy13_t_gb2312);
	u8g2_DrawUTF8(&u8g2, 0, 30, "沁恒");

	u8g2_SetFont(&u8g2, u8g2_font_ncenB08_tr);    //选择字库
	u8g2_DrawStr(&u8g2, 26, 30, "CH32V208");

	u8g2_SetFont(&u8g2, u8g2_font_wqy13_t_gb2312);
	u8g2_DrawUTF8(&u8g2, 80, 30, "开发板");

	#endif

	u8g2_SendBuffer(&u8g2);

	Delay_Ms(1300);

	while(1)
	{
	    Delay_Ms(100);
		u8g2_ClearBuffer(&u8g2);//清除缓冲区数据
		#if(SSD1306_DEVICE==SSD1306_128x64)
		if (++t >= 32)
			t = 1;
		u8g2_DrawCircle(&u8g2, 64, 32, t, U8G2_DRAW_ALL);   //画圆
		u8g2_DrawCircle(&u8g2, 32, 32, t, U8G2_DRAW_ALL);
		u8g2_DrawCircle(&u8g2, 96, 32, t, U8G2_DRAW_ALL);
		u8g2_SendBuffer(&u8g2); // 发送缓冲区数据
		#elif(SSD1306_DEVICE==SSD1306_128x32)
		if (++t >= 16)
			t = 1;
		u8g2_DrawCircle(&u8g2, 64, 16, t, U8G2_DRAW_ALL);   //画圆
		u8g2_DrawCircle(&u8g2, 32, 16, t, U8G2_DRAW_ALL);
		u8g2_DrawCircle(&u8g2, 96, 16, t, U8G2_DRAW_ALL);
		u8g2_SendBuffer(&u8g2); // 发送缓冲区数据

		#endif

	}
}

3. Test

After compiling and burning, you can see the amazing display effect as follows. Using u8g2 to do oled display design is really rich and flexible.

The effect video is as follows:

u8g2_oled_show

The source code is pinned to the top of this article, please pay attention.

This post is from Domestic Chip Exchange

Latest reply

This article describes how to use the u8g2 graphics library to drive the oled display. The advantages of using this graphics library are that it is powerful and has a font library that includes Chinese GB2312. It is very convenient and comprehensive to display Chinese characters. There is no need for a modulus tool to get the Chinese character dot matrix. In addition, there are many API functions that can be designed for the interface. It is highly recommended for use in actual engineering projects. Is the flash sufficient?   Details Published on 2024-7-20 11:50
 
 

445

Posts

0

Resources
From 2
 

oled project of graphics library u8g2

CH32V20x_OLED.rar

14.47 MB, downloads: 6

CH32V20x_U8g2_OLED 工程

This post is from Domestic Chip Exchange
 
 
 

6822

Posts

11

Resources
3
 

This article describes how to use the u8g2 graphics library to drive the oled display. The advantages of using this graphics library are that it is powerful and has a font library that includes Chinese GB2312. It is very convenient and comprehensive to display Chinese characters. There is no need for a modulus tool to get the Chinese character dot matrix. In addition, there are many API functions that can be designed for the interface. It is highly recommended for use in actual engineering projects.

Is the flash sufficient?

This post is from Domestic Chip Exchange

Comments

It is enough. Pay attention to the usage of the chip. The configuration can be up to 480K. U8g2 uses the Chinese library GB2312, and the resource consumption is about 300K.  Details Published on 2024-7-20 16:55
 
 
 

445

Posts

0

Resources
4
 
lugl4313820 posted on 2024-7-20 11:50 This article describes how to use the u8g2 graphics library to drive the oled display. The advantages of using this graphics library are powerful, with a font library, including Chinese GB2312, display...

It is enough. Pay attention to the usage of the chip. The configuration can be up to 480K. U8g2 uses the Chinese library GB2312, and the resource consumption is about 300K.

This post is from Domestic Chip Exchange
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews

Room 1530, Zhongguancun MOOC Times Building, Block B, 18 Zhongguancun Street, Haidian District, Beijing 100190, China Tel:(010)82350740 Postcode:100190

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list