根据 U8g2 github 上的信息解读,将 U8g2 移植到 ESP32 是非常简单的,方式可能有很多,作为初学者,只是记录一下我移植的过程,有不正确的地方请见谅,也希望大家指正。
两个可以获取到重要信息的网址:
https://github.com/olikraus/u8g2
https://github.com/nkolban/esp32-snippets/tree/master/hardware/displays/U8G2
1. 按上述第二个网址的步骤,在工程中导入最新的 u8g2 库,步骤已经截图如下
2. 在工程根目录的 CMakteLists.txt 下添加配置,让编译时找到对应的库文件
3. 在main 目录下增加第二个网址中的4个源代码文件资源(其中有两个是示例代码)
4. main 目录下 CMakeLists.txt 配置
5. 根据可参考引入的源码文件的例子,实现自己的业务逻辑即可,以下部分我的demo代码
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c.h"
#include "u8g2_esp32_hal.h"
static const char *TAG = "i2c-u8g2-ssd1306";
#define SCL_NO 22 //esp i2c SCL
#define SDA_NO 21 //esp i2c SDA
void app_main(void) {
//不需要初始化I2C,因为 u8g2_InitDisplay 中会初始化
//构建 u8g2
u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
u8g2_esp32_hal.sda = SDA_NO;
u8g2_esp32_hal.scl = SCL_NO;
u8g2_esp32_hal_init(u8g2_esp32_hal);
u8g2_t u8g2; // a structure which will contain all the data for one display
u8g2_Setup_ssd1306_i2c_128x32_univision_f(
&u8g2,
U8G2_R0,
//u8x8_byte_sw_i2c,
u8g2_esp32_i2c_byte_cb,
u8g2_esp32_gpio_and_delay_cb); // init u8g2 structure
//!!!下面的地址,是向左移了一位的地址以包括读/写标志,所以如果I2C 地址是 0x3c 0011 1100 那么就应该使用 0x78 代替 0111 1000
u8x8_SetI2CAddress(&u8g2.u8x8, 0x78);
ESP_LOGI(TAG, "u8g2_InitDisplay");
u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,
ESP_LOGI(TAG, "u8g2_SetPowerSave");
u8g2_SetPowerSave(&u8g2, 0); // wake up display
ESP_LOGI(TAG, "u8g2_ClearBuffer");
u8g2_ClearBuffer(&u8g2);
while (1) {
u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
ESP_LOGI(TAG, "u8g2_DrawStr");
u8g2_DrawStr(&u8g2, 2, 17,"Hi nkolban!");
ESP_LOGI(TAG, "u8g2_SendBuffer");
u8g2_SendBuffer(&u8g2);
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
}
成功编译后,但在运行时,我这里会报以下截图红框中的错误:(因为,引入的源码里,u8g2_InitDisplay(&u8g2) 对屏幕初始化时,会对 esp32 的 I2C 进行初始化配置,源码中 conf 是函数内的局部变量,导致 conf 有成员未初始化,会从 stack 里分配内存空值,值未知)
解决方法:(在引入的源代码报错的地方,增加 static 关键字即可)
仿真结果