無獨有偶來想來移植u8g2來玩玩
硬件清單:
- stm32f334核心板一塊(沒用stm32f1是因爲f1的排針焊反了,不好直插,f1類似)
- 0.96寸的Oled屏,爲4線SPI連接
- 還有一個下載器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的使用指南