STM32 移植 U8g2

硬件配置

  • CPU是STM32F051
  • 屏幕是0.96的SSD1306
  • CPU-屏的接口是 硬件4线SPI

硬件接口

STM32 移植 U8g2_第1张图片
HW_Cfg.png

软件配置

  • IDE是MDK5.24,搭配Vs code

移植

  1. 先用CubeMX生成初始化代码,我没有用HAL,用的LL更加适合单片机开发者的思维模式


    STM32 移植 U8g2_第2张图片
    MX_Cfg.png

    配置模式不作细述。

  2. 然后去这里下载U8g2
  3. 下载完成后,解压,进入目录复制csrc,本次移植不考虑C++
  4. KEIL里面加入csrc的文件,并加入包含路径,加入文件是要注意一个u8x8_d_芯片名.c,只要加入自己需要使用的即可,其他的没有必要加入
  5. 重写U8g2需要的两个回调函数,根据接口不一样回调的名字也不一样。这个需要看一下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库的SPI之前需要手动Enable SPI,库生成的代码有BUG,在配置完成后没有对SPI进行Enable

  1. 目前工程应该已经可以进行编译了,不过会有很多错误接下来对错误进行修正
  • 首先要对u8_setup.c里面没有使用的函数进行注释,否则会调用大量的缓存,导致内存不够
  • 内存不够:先执行上一步再执行本步不然会报大量的未定义错误,内存不够是因为U8g2支持了大量的屏幕有很多不同形式的缓冲区,只需要留下自己要用的一个即可其余的全部可以删除掉,具体缓冲区定义在U8g2_d_memory.c里面,调用是在u8x8_d_etup.c,快速的修改方法是注释掉u8g2_d_memory.c里面所有的缓冲区编译一下看哪个缓冲区报未定义,再回去取消那个缓冲存的注释。
  1. 然后在函数里对外设和u8g2进行初始化
static u8g2_t u8g2; //首先定义u8g2的对象
//对u8g2和屏幕进行初始化
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);

定义一个显示用的测试函数

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");
}

然后在主循环中进行调用

  while (1)
  {
    /* USER CODE END WHILE */
    u8g2_FirstPage(&u8g2);
    do
    {
            draw(&u8g2);
    } while (u8g2_NextPage(&u8g2));
    /* USER CODE BEGIN 3 */
  }

至此,移植就全部完成了,不是经常写文章,没有什么排版,主要是提供一个思路给各位

你可能感兴趣的:(STM32 移植 U8g2)