初試--移植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的使用指南

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