硬件配置
- CPU是STM32F051
- 屏幕是0.96的SSD1306
- CPU-屏的接口是 硬件4線SPI
硬件接口
HW_Cfg.png
軟件配置
- IDE是MDK5.24骚秦,搭配Vs code
移植
-
先用CubeMX生成初始化代碼,我沒(méi)有用HAL若贮,用的LL更加適合單片機(jī)開(kāi)發(fā)者的思維模式
MX_Cfg.png
配置模式不作細(xì)述戳吝。
- 然后去這里下載U8g2
- 下載完成后浩销,解壓,進(jìn)入目錄復(fù)制csrc听哭,本次移植不考慮C++
- KEIL里面加入csrc的文件慢洋,并加入包含路徑,加入文件是要注意一個(gè)u8x8_d_芯片名.c欢唾,只要加入自己需要使用的即可且警,其他的沒(méi)有必要加入
- 重寫(xiě)U8g2需要的兩個(gè)回調(diào)函數(shù),根據(jù)接口不一樣回調(diào)的名字也不一樣礁遣。這個(gè)需要看一下github的介紹斑芜,本例是SPI
uint8_t u8x8_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
void *arg_ptr)
{
uint8_t *data = NULL;
switch (msg)
{
case U8X8_MSG_BYTE_SEND:
data = (uint8_t*)arg_ptr;
do
{
while(LL_SPI_IsActiveFlag_TXE(SPI1) == RESET);
LL_SPI_TransmitData8(SPI1, *(data++));
while(LL_SPI_IsActiveFlag_BSY(SPI1) == SET){}
arg_int--;
}while(arg_int > 0);
break;
case U8X8_MSG_BYTE_INIT:
break;
case U8X8_MSG_BYTE_SET_DC:
GPIO_WriteBit(OLED_DC_GPIO_Port, OLED_DC_Pin, arg_int);
break;
case U8X8_MSG_BYTE_START_TRANSFER:
break;
case U8X8_MSG_BYTE_END_TRANSFER:
break;
default:
return 0;
}
return 1;
}
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_AND_DELAY_INIT:
// HAL_Delay(1);
LL_mDelay(1);
break;
case U8X8_MSG_DELAY_MILLI:
LL_mDelay(arg_int);
break;
case U8X8_MSG_GPIO_CS:
GPIO_WriteBit(OLED_CS_GPIO_Port, OLED_CS_Pin, arg_int);
case U8X8_MSG_GPIO_DC:
// HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, arg_int);
GPIO_WriteBit(OLED_DC_GPIO_Port, OLED_DC_Pin, arg_int);
break;
case U8X8_MSG_GPIO_RESET:
// HAL_GPIO_WritePin(OLED_RES_GPIO_Port, OLED_RES_Pin, arg_int);
GPIO_WriteBit(OLED_RST_GPIO_Port, OLED_RST_Pin, arg_int);
break;
}
return 1;
}
在使用LL庫(kù)的SPI之前需要手動(dòng)Enable SPI,庫(kù)生成的代碼有BUG祟霍,在配置完成后沒(méi)有對(duì)SPI進(jìn)行Enable
- 目前工程應(yīng)該已經(jīng)可以進(jìn)行編譯了杏头,不過(guò)會(huì)有很多錯(cuò)誤接下來(lái)對(duì)錯(cuò)誤進(jìn)行修正
- 首先要對(duì)u8_setup.c里面沒(méi)有使用的函數(shù)進(jìn)行注釋?zhuān)駝t會(huì)調(diào)用大量的緩存盈包,導(dǎo)致內(nèi)存不夠
- 內(nèi)存不夠:先執(zhí)行上一步再執(zhí)行本步不然會(huì)報(bào)大量的未定義錯(cuò)誤,內(nèi)存不夠是因?yàn)閁8g2支持了大量的屏幕有很多不同形式的緩沖區(qū)醇王,只需要留下自己要用的一個(gè)即可其余的全部可以刪除掉呢燥,具體緩沖區(qū)定義在U8g2_d_memory.c里面,調(diào)用是在u8x8_d_etup.c寓娩,快速的修改方法是注釋掉u8g2_d_memory.c里面所有的緩沖區(qū)編譯一下看哪個(gè)緩沖區(qū)報(bào)未定義叛氨,再回去取消那個(gè)緩沖存的注釋。
- 然后在函數(shù)里對(duì)外設(shè)和u8g2進(jìn)行初始化
static u8g2_t u8g2; //首先定義u8g2的對(duì)象
//對(duì)u8g2和屏幕進(jìn)行初始化
u8g2_Setup_ssd1306_128x64_noname_1(&u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay);
u8g2_InitDisplay(&u8g2);
u8g2_SetPowerSave(&u8g2, 0);
定義一個(gè)顯示用的測(cè)試函數(shù)
void draw(u8g2_t *u8g2)
{
u8g2_SetFontMode(u8g2, 1); // Transparent
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
u8g2_DrawStr(u8g2, 0, 20, "U");
u8g2_SetFontDirection(u8g2, 1);
u8g2_SetFont(u8g2, u8g2_font_inb30_mn);
u8g2_DrawStr(u8g2, 21,8,"8");
u8g2_SetFontDirection(u8g2, 0);
u8g2_SetFont(u8g2, u8g2_font_inb24_mf);
u8g2_DrawStr(u8g2, 51,30,"g");
u8g2_DrawStr(u8g2, 67,30,"\xb2");
u8g2_DrawHLine(u8g2, 2, 35, 47);
u8g2_DrawHLine(u8g2, 3, 36, 47);
u8g2_DrawVLine(u8g2, 45, 32, 12);
u8g2_DrawVLine(u8g2, 46, 33, 12);
u8g2_SetFont(u8g2, u8g2_font_4x6_tr);
u8g2_DrawStr(u8g2, 1,54,"github.com/olikraus/u8g2");
}
然后在主循環(huán)中進(jìn)行調(diào)用
while (1)
{
/* USER CODE END WHILE */
u8g2_FirstPage(&u8g2);
do
{
draw(&u8g2);
} while (u8g2_NextPage(&u8g2));
/* USER CODE BEGIN 3 */
}
至此棘伴,移植就全部完成了寞埠,不是經(jīng)常寫(xiě)文章,沒(méi)有什么排版焊夸,主要是提供一個(gè)思路給各位