初试--移植u8g2库到stm32

无独有偶来想来移植u8g2来玩玩

硬件清单:

  1.        stm32f334核心板一块(没用stm32f1是因为f1的排针焊反了,不好直插,f1类似)
  2.        0.96寸的Oled屏,为4线SPI连接
  3.        还有一个下载器DAP

软件清单: keil5和cubemx

先在cubemx创建一个相关的工程并生成代码,用软件模拟spi:(总览)

然后去u8g2的github下载相关包(下载链接戳这里),解压后:)

由于是在单片机上使用,我们打开csrc这个文件夹,可以看到里面有很多.c文件和两个.h文件。

在keil5的main.c中添加那俩个.h文件:

再在该项目下的创建一个文件夹,将csrc复制到此,然后在keil5中添加其中一些要用到的文件,我这个是弄好了的:

其中那个u8x8_d_ssd1306_128x64_noname.c是随oled屏的驱动芯片来选择的(我的Oled的驱动芯片是ssd1306)

然后在再加入以下代码,即创建一个回调函数(可根据相关的宏来知其意,比如U8X8_MSG_GPIO_SPI_DATA就是表示软件模拟spi的数据管脚,那个arg_int表示是将当前管脚置高还是复位,其中的OLED_Init()是OLED初始化函数):

uint8_t u8x8_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)
{
  switch (msg)
  {
		case U8X8_MSG_GPIO_SPI_DATA:
			(arg_int)?SET_BIT(GPIOB->ODR,OLED_DI_Pin):CLEAR_BIT(GPIOB->ODR,OLED_DI_Pin);
			break;
		case U8X8_MSG_GPIO_SPI_CLOCK:
			(arg_int)?SET_BIT(GPIOB->ODR,OLED_DO_Pin):CLEAR_BIT(GPIOB->ODR,OLED_DO_Pin);
			break;
		case U8X8_MSG_GPIO_AND_DELAY_INIT:
					OLED_Init();
					HAL_Delay(1);
			break;
		case U8X8_MSG_DELAY_MILLI:
			HAL_Delay(arg_int);
			break;
			case U8X8_MSG_GPIO_CS:
				(arg_int)?SET_BIT(GPIOA->ODR,OLED_CS_Pin):CLEAR_BIT(GPIOA->ODR,OLED_CS_Pin);
		case U8X8_MSG_GPIO_DC:
					(arg_int)?SET_BIT(GPIOB->ODR,OLED_DC_Pin):CLEAR_BIT(GPIOB->ODR,OLED_DC_Pin);
			break;
		case U8X8_MSG_GPIO_RESET:
					(arg_int)?SET_BIT(GPIOB->ODR,OLED_RES_Pin):CLEAR_BIT(GPIOB->ODR,OLED_RES_Pin);
			break;
  }
  return 1;
}

初始化u8g2,先上一张图,来说明如何选择相关构造函数

这里我选择的是u8g2_Setup_ssd1306_128x64_noname_f,即表示一帧的的大小为1024(128*8)bytes.

(这里说明一下,如果选择u8g2_Setup_ssd1306_128x64_noname_1或者u8g2_Setup_ssd1306_128x64_noname_2的话,显示调用函数跟下面不一样,可参考以下(这是后来加的,句柄名字不一样,还请注意),当然清除函数还是一样的

在主函数中初始化u8g2,先创建u8g2的句柄

参数U8G2_R0表示不旋转,参考

其中u8x8_byte_4wire_sw_spi是在u8x8_byte.c中,自行添加相关.c文件,表示用软件模拟spi,4线。

先别添加u8g2_d_memory.c,先添加并解决u8g2_d_setup.c的文件的问题。

首次编译,不出意外的话会出现很多问题,具体解决是注释掉没用到的函数(比如我这只用到u8g2_Setup_ssd1306_128x64_noname_f这个函数,就保留这个函数,其他函数都注释掉)这个视自己的情况来

然后添加u8g2_d_memory.c,并将里面所有的函数注释掉,然后再次编译

不出意外的话,会接着出现很多问题,这是需要在众多错误中寻找一个以u8g2_m_xxx的函数名称,然后去u8g2_d_memory.c中去寻找该函数名,并只取消该函数的注释即可

并再次编译,如果依旧出现很多错误,应该都是未定义的函数,这时只需要在项目添加相关.c文件即可。

大多数函数都可以以函数名就知道它是哪个.c文件里的了,如果还不知道就全部添加进来吧(当热这种方法并不万能,也可以试着移除一些已经添加的.c文件,保留一些必要就可以)。

主函数中添加

        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
		HAL_Delay(100);
		u8g2_ClearBuffer(&u8g2); 
		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);  

最后添个图:

如果想知道u8g2的具体其他使用可参考u8g2的GitHub的使用指南

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章