无独有偶来想来移植u8g2来玩玩
硬件清单:
软件清单: 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的句柄
其中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的使用指南