ESP32 LVGL 一、移植相关事项
·
准备
使用windows espidf + vscode
移植:
通过组件管理器安装最新lvgl库和lvgl port库。
ESP32 底层相关配置
void setup_gpio_init(void)
{
gpio_config_t gpio_cfg = {};
gpio_cfg.mode = GPIO_MODE_OUTPUT;
gpio_cfg.pin_bit_mask = 1ULL << LCD_BLK_NUM;
gpio_cfg.pull_down_en = GPIO_PULLUP_DISABLE;
gpio_cfg.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_cfg.intr_type = GPIO_INTR_DISABLE;
ESP_ERROR_CHECK(gpio_config(&gpio_cfg));
}
void setup_spi_init(void)
{
spi_bus_config_t spi_cfg = {};
spi_cfg.sclk_io_num = LCD_SCLK_NUM;
spi_cfg.mosi_io_num = LCD_MOSI_NUM;
spi_cfg.miso_io_num = LCD_MISO_NUM;
spi_cfg.quadwp_io_num = GPIO_NUM_NC;
spi_cfg.quadhd_io_num = GPIO_NUM_NC;
//spi_cfg.max_transfer_sz应当比显存容量大,避免刷新失败,计算时应将像素点总数乘以每个像素点的字节数
spi_cfg.max_transfer_sz = LCD_H_RES_DATA * LCD_BUFFER_H_DATA * sizeof(uint16_t);
ESP_ERROR_CHECK(spi_bus_initialize(LCD_SPI2_HOST, &spi_cfg, SPI_DMA_CH_AUTO));
}
lcd面板
void device_lcd_init(void)
{
esp_lcd_panel_io_spi_config_t io_config = {};
io_config.dc_gpio_num = LCD_DC_NUM;
io_config.cs_gpio_num = LCD_CS_NUM;
io_config.pclk_hz = LCD_PIXEL_CLK_HZ;
io_config.lcd_cmd_bits = LCD_CMD_BITS;
io_config.lcd_param_bits = LCD_PARAM_BITS;
io_config.spi_mode = 0;
io_config.trans_queue_depth = 10;
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_SPI2_HOST, &io_config, &lcd_io));
esp_lcd_panel_dev_config_t panel_config = {};
panel_config.reset_gpio_num = LCD_RST_NUM;
panel_config.rgb_ele_order = LCD_COLOR_SPACE;
panel_config.bits_per_pixel = LCD_BITS_PER_PIXEL;
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(lcd_io, &panel_config, &lcd_panel));
esp_lcd_panel_reset(lcd_panel);
esp_lcd_panel_init(lcd_panel);
esp_lcd_panel_set_gap(lcd_panel, 0, 0);
//_设置偏移
esp_lcd_panel_invert_color(lcd_panel,true);
// esp_lcd_panel_mirror(lcd_panel,false,_true);
esp_lcd_panel_disp_on_off(lcd_panel, true);
}
实例一个lvgl输入设备
lv_indev_t * init_button_event_mode(void)
{
// create indev
indev_button = lv_indev_create();
lv_indev_set_type(indev_button, LV_INDEV_TYPE_KEYPAD);
lv_indev_set_mode(indev_button, LV_INDEV_MODE_EVENT); // event-driven
lv_indev_set_read_cb(indev_button, lv_event_button_read_cb);
lv_indev_set_driver_data(indev_button, &ctx);
lv_indev_set_display(indev_button, lv_display_get_default()); // or your disp handle
ctx.indev = indev_button;
ctx.pressed = false;
return indev_button;
}
lvgl输入设备回调
static void lv_event_button_read_cb(lv_indev_t * indev, lv_indev_data_t * data)
{
printf("got\n");
btn_ctx_t *ctx = (btn_ctx_t *)lv_indev_get_driver_data(indev);
// read and clear the pressed flag (do not block)
data->key = ctx->lv_key;
bool pressed = ctx->pressed;
if (pressed) {
data->state = LV_INDEV_STATE_PRESSED;
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
// printf("focused=%p\n", lv_group_get_focused(lv_indev_get_act()));
lv_obj_t *f = lv_group_get_focused(lv_indev_get_group(indev));
printf("focused=%p ", f);
printf("read_cb key=%lu state=%d\n", data->key, data->state);
}
实际lv_event_button_read_cb的事件来源(注意pseudo,其实由于没有实际输入设备,这个将交给控制台,由命令行控制伪装输入):
/*
* @para btnx:0:left,1:enter,2:right
*/
void pseudo_button_gpio_isr(uint8_t btnX,uint8_t click)
{
switch (btnX)
{
case 0:
ctx.lv_key = LV_KEY_LEFT;
break;
case 1:
ctx.lv_key = LV_KEY_ENTER;
break;
case 2:
ctx.lv_key = LV_KEY_RIGHT;
break;
default:
break;
}
ctx.pressed = (click != 0);
// esp_lvgl_port provides this ISR-safe wake. It will set event bits and yield from ISR if needed.
lvgl_port_task_wake(LVGL_PORT_EVENT_TOUCH, ctx.indev);
}
正式建立lvgl与硬件lcd的联系;
void soft_drv_lvgl_port_init(void)
{
/*_LCD_backlight_on_*/
ESP_ERROR_CHECK(gpio_set_level(LCD_BLK_NUM, LCD_BL_NO_LEVEL));
// encoder_init_todo
lvgl_port_cfg_t lvgl_cfg = {};
lvgl_cfg.task_priority = 4; /*_LVGL_task_priority_*/
lvgl_cfg.task_stack = 12 * 1024; /*LVGL_task_stack_size_*/
lvgl_cfg.task_affinity = -1; /*LVGL_task_pinned_to_core(-l_is_no_affinity)*/
lvgl_cfg.task_max_sleep_ms = 500; /*_Maximum_sleep_in_LVGL_task*/
lvgl_cfg.timer_period_ms = 5; /*LVGL_timer_tick_period_in_ms_ */
ESP_ERROR_CHECK(lvgl_port_init(&lvgl_cfg));
lvgl_port_display_cfg_t disp_cfg = {};
disp_cfg.io_handle = lcd_io;
disp_cfg.panel_handle = lcd_panel;
//disp_cfg.buffer_size应该小于spi_cfg.max_transfer_sz
disp_cfg.buffer_size = LCD_H_RES * LCD_DRAW_BUFF_HEIGHT;
disp_cfg.double_buffer = LCD_DEAW_BUFF_DOUBLE;
disp_cfg.hres = LCD_H_RES;
disp_cfg.vres = LCD_V_RES;
disp_cfg.monochrome = false;
#if LVGL_VERSION_MAJOR >= 9
disp_cfg.color_format = LV_COLOR_FORMAT_RGB565;
#endif
disp_cfg.rotation.swap_xy = false;
disp_cfg.rotation.mirror_x = false;
disp_cfg.rotation.mirror_y = false;
disp_cfg.flags.buff_dma = true;
#if LVGL_VERSION_MAJOR >= 9
disp_cfg.flags.swap_bytes = true;
#endif
lvgl_disp = lvgl_port_add_disp(&disp_cfg);
}
移植更多细节可以参考:“https://www.bilibili.com/video/BV1rNPjeEE34/?vd_source=8a28106cecc10670fe9dc17e05c6226f”
更多推荐



所有评论(0)