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

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


  • 📍WouoUI原项目地址:https://github.com/RQNG/WouoUI
  • 📍基于STM32F103C8T6 LL库驱动版本:https://gitee.com/chcsx/platform-test/tree/master/MDK-ARM
  • 🌿串口控制WouoUIPage版本:https://github.com/Sheep118/WouoUI-PageVersion
  • 🎬视频演示:

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标准库的可以参照上面的例程测试。这里不多作说明。
  • 🔖串口控制WouoUIPage版本,该开源项目原作者,提供了较为详细的项目介绍和API接口使用说明,这里不做过多说明,该项目耦合度低,移植方便。原项目stm32 demo默认使用的是标准库SPI,这里会提供一个,移植到使用HAL库的I2C DMA方式的工程。

✅功能部分说明

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

  • 🎞SH1106驱动显示效果:
    在这里插入图片描述
  • 📺I2C SSD1306 0.96"屏幕显示效果:
    在这里插入图片描述
🌾HAL库程序是基于上面的LL库移植过来的,采用的是STM32F103VET6。保留了按键控制功能,去掉了其他没有的外设。
  • 🔖AC6编译器,优化等级默认Level 1 (o1)
    在这里插入图片描述

  • 🔖AC5编译器,优化等级至少要设置Level 1 (o1),否则会报L6406E错误。
    在这里插入图片描述

  • 🌿屏蔽相关报警信息

--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

📚串口控制WouoUIPage STM32 HAL库I2C DMA方式工程版本

  • 🔖基于STM32F103,兼容SSD1306/sh1106。在oled.h中修改对应宏,决定选择屏幕类型
#define SH1106_OLED    0
#define SSD1306_OLED    1
#define  SCREEN_TYPE   SH1106_OLED    //SSD1306:0 ; SH1106:1
  • 🔖测试方法:推荐使用带快捷键配置串口发送指令的串口调试助手,例如SSCOM、正点原子串口调试助手
    在这里插入图片描述
    在这里插入图片描述
链接:https://pan.baidu.com/s/1gh1-SFdA_IzaArTd_w4LWQ?pwd=hr3k 
提取码:hr3k
  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值