HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例

HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例


  • 基于STM32F103C8T6 LL库驱动版本:https://gitee.com/chcsx/platform-test/tree/master/MDK-ARM
  • 视频演示:

WouoUI移植磁贴案例,新增确认弹窗


  • 基于标准库驱动,STM32F103RCT6移植u8g2 硬件i2c WouoUI磁贴:https://gitee.com/henrycrh/stm32-f103-rct6_-wouo-ui/tree/master/STM32F10x_FWlib/src
  • 视频演示:

[开源]STM32F103RCT6移植u8g2 > 硬件i2c > WouoUI移植

  • 使用LL库和STD标准库的可以参照上面的例程测试。这里不多种说明。

✅功能部分说明

  • 显示部分:U8g2库驱动
  • 按键:采用Multi-button库驱动

  • SH1106驱动显示效果:
    HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例_第1张图片
  • I2C SSD1306 0.96"屏幕显示效果:
    HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例_第2张图片
HAL库程序是基于上面的LL库移植过来的,采用的是STM32F103VET6。保留了按键控制功能,去掉了其他没有的外设。
  • AC6编译器,优化等级默认Level 1 (o1)
    HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例_第3张图片

  • AC5编译器,优化等级至少要设置Level 1 (o1),否则会报L6406E错误。
    HAL/LL/STD STM32 U8g2库 +I2C SSD1306/sh1106 WouoUI磁贴案例_第4张图片

  • 屏蔽相关报警信息

--diag_suppress=1,111,223,1295
  • 测试使用1.3“SH1106屏幕显示正常,0.96" ssd1306屏幕会闪屏。
  • 移植的HAL库程序:
链接:https://pan.baidu.com/s/1Oh3ysdU8-1X0I_JJVVemkg?pwd=slro 
提取码:slro

HAL库程序引脚说明

STM32F103VET6
按键控制
PE8 上翻页
PE7 下翻页
PB1  确认/长按返回
===================
	  I2C1   SCL ---- PB6
	  I2C1   SDA ---- PB7

HAL库程序SSD1306/sh1106屏幕选择与代码调整

  • ✨在oled.c中,OLED初始化OLED_Init(void)函数。(sh1106屏幕刷SSD1306程序也可以显示,只是边框有一部分是马赛克雪花)
//*****************************   使用下面2个
	u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, stm32_gpio_and_delay); //1.3" sh1106 使用这个
// u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, stm32_gpio_and_delay); //0.96"SSD1306使用这个
//******************************  使用上面2个

U8g2库移植说明

  • 可以借用上面的LL库的工程,直接拷贝对应的驱动文件夹到自己所创建的工程目录下。
  • 其他屏幕型号,需要提前准备一个能驱动显示的工程作为模板。
  • 将以下3个核心函数,拷贝到能显示的模板工程中,根据驱动屏幕型号进行调整:
uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);//硬件I2C
uint8_t stm32_gpio_and_delay(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr);
void OLED_Init(void);
uint8_t u8x8_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)//硬件I2C
{
	/* 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_I2C1_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:
		{
			int ret = HAL_I2C_Master_Transmit(&hi2c1, (OLED_ADDRESS), buffer, buf_idx, 1000);
			if (ret != HAL_OK)
			{
				return 0;
			}
		}
		break;
		case U8X8_MSG_BYTE_SET_DC:
				break;
		default:
				return 0;
	}
	return 1;
}

uint8_t stm32_gpio_and_delay(U8X8_UNUSED u8x8_t *u8x8, U8X8_UNUSED uint8_t msg, U8X8_UNUSED uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
{
#if 0
  switch (msg)
  {
//  case U8X8_MSG_GPIO_AND_DELAY_INIT:
//       oled_init();                    
//  break;
		case U8X8_MSG_GPIO_SPI_DATA:
				if(arg_int)OLED_SDIN_Set();
				else OLED_SDIN_Clr();
		break;
		case U8X8_MSG_GPIO_SPI_CLOCK:
				if(arg_int)OLED_SCLK_Set();
				else OLED_SCLK_Clr();
		break;        
		case U8X8_MSG_GPIO_CS:
				//CS????
		case U8X8_MSG_GPIO_DC:
				if(arg_int)OLED_DC_Set();
				else OLED_DC_Clr();
		break;
		case U8X8_MSG_GPIO_RESET:
				if(arg_int)OLED_RST_Set();
				else OLED_RST_Clr();
		break;
		//Function which delays 100ns  
		case U8X8_MSG_DELAY_100NANO:  
				__NOP();  
		break;  
		case U8X8_MSG_DELAY_MILLI:
				HAL_Delay(arg_int);
		break;
		default:
				return 0;//A message was received which is not implemented, return 0 to indicate an error
  }
  return 1;
#elif 0
	// printf("%s:msg = %d,arg_int = %d\r\n",__FUNCTION__,msg,arg_int);
	switch (msg)
	{
		//		case U8X8_MSG_GPIO_AND_DELAY_INIT:
		//				oled_init();
		//		break;
	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
		// delay 5us
		delay_us(5); // 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
		if (arg_int == 1)
		{
			LL_GPIO_SetOutputPin(LCD_SCL_GPIO_Port, LCD_SCL_Pin);
			//        HAL_GPIO_WritePin(GPIOB, SCL2_Pin, GPIO_PIN_SET);
		}
		else if (arg_int == 0)
		{
			LL_GPIO_ResetOutputPin(LCD_SCL_GPIO_Port, LCD_SCL_Pin);
			//        HAL_GPIO_WritePin(GPIOB, SCL2_Pin, GPIO_PIN_RESET);
		}
		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
		//  printf("U8X8_MSG_GPIO_I2C_DATA:%d\r\n",arg_int);
		if (arg_int == 1)
		{
			LL_GPIO_SetOutputPin(LCD_SDA_GPIO_Port, LCD_SDA_Pin);
			//        HAL_GPIO_WritePin(GPIOB, SDA2_Pin, GPIO_PIN_SET);
		}
		else if (arg_int == 0)
		{
			LL_GPIO_ResetOutputPin(LCD_SDA_GPIO_Port, LCD_SDA_Pin);
			//        HAL_GPIO_WritePin(GPIOB, SDA2_Pin, GPIO_PIN_RESET);
		}
		break; // arg_int=1: Input dir with pullup high for I2C data pin

	default:
		u8x8_SetGPIOResult(u8x8, 1); // default return value
		break;
	}
	return 1;
#elif 0
	switch (msg)
	{
	case U8X8_MSG_GPIO_AND_DELAY_INIT:
		break;
	case U8X8_MSG_DELAY_MILLI:
		HAL_Delay(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.
#elif 1	
	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
//				delay_us(5);
				for (uint16_t n = 0; n < 160; n++)
				{
					__NOP();
				}
				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;
}
#endif

/**
 * @brief	OLED初始化
*/			    
void OLED_Init(void)
{ 	
		//	u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_4wire_sw_spi, stm32_gpio_and_delay);
	//	u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_sw_i2c, stm32_gpio_and_delay);
	u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, stm32_gpio_and_delay);
	u8g2_InitDisplay(&u8g2);
	u8g2_SetPowerSave(&u8g2, 0);
}

HAL库U8g2单独驱动程序SSD1306/sh1106屏幕

  • SSD1306/sh1106屏幕选择
//    u8g2_Setup_sh1106_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_stm32_gpio_and_delay); //1.3" sh1106 使用这个
     u8g2_Setup_ssd1306_i2c_128x64_noname_f(&u8g2, U8G2_R0, u8x8_byte_hw_i2c, u8x8_stm32_gpio_and_delay);//0.96"SSD1306使用这个
链接:https://pan.baidu.com/s/1_hQ1Op00aBoBkjhudml9pw?pwd=6z3u 
提取码:6z3u

你可能感兴趣的:(stm32,WouoUI磁贴,U8g2)