求助,有趣的LVGL驱动ILI9488,屏幕边缘有一排亮点。[已解决]
Posted: Mon Jun 13, 2022 6:30 am
这几天我用ESP32通过LVGL成功驱动了一块ILI9488的TFT。
但是遇到一个问题始终不能解决。
无论我放置什么组件到屏幕的右侧边缘(屏幕的 x = 0 在最左边)总会出现一串亮点,并且有从上到下越来越亮的现象。
效果是这样:
[attachment=1]微信图片_40.jpg[/attachment]
或者这样:
[attachment=0]微信图片_20.jpg[/attachment]
是不是很有趣的现象?
起初问题的表现为图1,经过我的观察,总共有8个亮点,而我的屏幕y轴分辨率为 320.
仔细思考后,猜测,是否再刷新LCD时,LVGL把整个屏幕分成了8块,而每一块的最后一个点数据错误,导致变色。
随后我更改了 lvgl_helpers.h 中的这个宏定义:
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) /* 我将 40 改为20 */
因为 40 * 8 刚好是 320 , 而他定义的 DISP_BUF_SIZE 是屏幕宽度(480)的 40 倍,这样算下来刚好 8 次刷满一个屏幕。
现在我把常数 40 改为 20 , 会不会出现16个渐渐变亮的点呢?
图2,正是我修改后的结果。不多不少整整16个。
后来我又怀疑是不是屏幕本身的质量问题,导致了这样的结果。经过反复测试,无论我把屏幕定义为多大,
也就是:
#define LV_HOR_RES_MAX 480
#define LV_VER_RES_MAX 320
这无论无何改变,所规定的屏幕边缘区域都会出现这样一排亮点。
也就是说 如果我把屏幕变为 LV_HOR_RES_MAX 320 ,假设是一块320 x 320的屏幕,在屏幕 X = 320 的纵轴上依然会出现这样的亮点。
下面是我目前的代码:
1>gui任务初始化部分
static void guiTask(void *pvParameter)
{
(void)pvParameter;
xGuiSemaphore = xSemaphoreCreateMutex();
lv_init();
/* Initialize SPI or I2C bus used by the drivers */
lvgl_driver_init();
lv_color_t *buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1 != NULL);
static lv_color_t *buf2 = NULL;
static lv_disp_draw_buf_t disp_buf;
uint32_t size_in_px = DISP_BUF_SIZE; /* 就是这里传入了显示BUFF的大小 480 x 40 */
/* Initialize the working buffer depending on the selected display.
* NOTE: buf2 == NULL when using monochrome displays. */
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = disp_driver_flush;
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
disp_drv.draw_buf = &disp_buf;
lv_disp_drv_register(&disp_drv);
/* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.read_cb = touch_driver_read;
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
#endif
/* Create and start a periodic timer interrupt to call lv_tick_inc */
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task,
.name = "periodic_gui"};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, portTICK_PERIOD_MS * 1000));
/* Create the demo application */
create_demo_application();
while (1)
{
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10));
/* Try to take the semaphore, call lvgl related function on success */
if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY))
{
lv_task_handler();
xSemaphoreGive(xGuiSemaphore);
}
}
/* A task should NEVER return */
free(buf1);
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
free(buf2);
#endif
vTaskDelete(NULL);
}
2>界面实体部分
LV_IMG_DECLARE(back_img); /* 用于桌面背景的图片 size = 480 x 320 */
static void create_demo_application(void)
{
#if 1 /* 这里显示的图片就是背景图片,图片本身没有问题,我也用纯色的图片测试过,甚至改变桌面的颜色 结果都一样 */
lv_obj_t *back_img_hal = lv_img_create(lv_scr_act());
lv_img_set_src(back_img_hal, &back_img);
lv_obj_align(back_img_hal, LV_ALIGN_TOP_LEFT, 0, 0);
....以下绘制了一些用于显示内容的 box ,无论是否编译对该问题没有影响。
.
.
.
.
.
}
有没有大神帮忙分析一下,问题出在哪里?我该如何处理?
谢谢您的解答,不甚感激!
但是遇到一个问题始终不能解决。
无论我放置什么组件到屏幕的右侧边缘(屏幕的 x = 0 在最左边)总会出现一串亮点,并且有从上到下越来越亮的现象。
效果是这样:
[attachment=1]微信图片_40.jpg[/attachment]
或者这样:
[attachment=0]微信图片_20.jpg[/attachment]
是不是很有趣的现象?
起初问题的表现为图1,经过我的观察,总共有8个亮点,而我的屏幕y轴分辨率为 320.
仔细思考后,猜测,是否再刷新LCD时,LVGL把整个屏幕分成了8块,而每一块的最后一个点数据错误,导致变色。
随后我更改了 lvgl_helpers.h 中的这个宏定义:
#elif defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_ILI9488
#define DISP_BUF_SIZE (LV_HOR_RES_MAX * 40) /* 我将 40 改为20 */
因为 40 * 8 刚好是 320 , 而他定义的 DISP_BUF_SIZE 是屏幕宽度(480)的 40 倍,这样算下来刚好 8 次刷满一个屏幕。
现在我把常数 40 改为 20 , 会不会出现16个渐渐变亮的点呢?
图2,正是我修改后的结果。不多不少整整16个。
后来我又怀疑是不是屏幕本身的质量问题,导致了这样的结果。经过反复测试,无论我把屏幕定义为多大,
也就是:
#define LV_HOR_RES_MAX 480
#define LV_VER_RES_MAX 320
这无论无何改变,所规定的屏幕边缘区域都会出现这样一排亮点。
也就是说 如果我把屏幕变为 LV_HOR_RES_MAX 320 ,假设是一块320 x 320的屏幕,在屏幕 X = 320 的纵轴上依然会出现这样的亮点。
下面是我目前的代码:
1>gui任务初始化部分
static void guiTask(void *pvParameter)
{
(void)pvParameter;
xGuiSemaphore = xSemaphoreCreateMutex();
lv_init();
/* Initialize SPI or I2C bus used by the drivers */
lvgl_driver_init();
lv_color_t *buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
assert(buf1 != NULL);
static lv_color_t *buf2 = NULL;
static lv_disp_draw_buf_t disp_buf;
uint32_t size_in_px = DISP_BUF_SIZE; /* 就是这里传入了显示BUFF的大小 480 x 40 */
/* Initialize the working buffer depending on the selected display.
* NOTE: buf2 == NULL when using monochrome displays. */
lv_disp_draw_buf_init(&disp_buf, buf1, buf2, size_in_px);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = disp_driver_flush;
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
disp_drv.draw_buf = &disp_buf;
lv_disp_drv_register(&disp_drv);
/* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.read_cb = touch_driver_read;
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
#endif
/* Create and start a periodic timer interrupt to call lv_tick_inc */
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task,
.name = "periodic_gui"};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, portTICK_PERIOD_MS * 1000));
/* Create the demo application */
create_demo_application();
while (1)
{
/* Delay 1 tick (assumes FreeRTOS tick is 10ms */
vTaskDelay(pdMS_TO_TICKS(10));
/* Try to take the semaphore, call lvgl related function on success */
if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY))
{
lv_task_handler();
xSemaphoreGive(xGuiSemaphore);
}
}
/* A task should NEVER return */
free(buf1);
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
free(buf2);
#endif
vTaskDelete(NULL);
}
2>界面实体部分
LV_IMG_DECLARE(back_img); /* 用于桌面背景的图片 size = 480 x 320 */
static void create_demo_application(void)
{
#if 1 /* 这里显示的图片就是背景图片,图片本身没有问题,我也用纯色的图片测试过,甚至改变桌面的颜色 结果都一样 */
lv_obj_t *back_img_hal = lv_img_create(lv_scr_act());
lv_img_set_src(back_img_hal, &back_img);
lv_obj_align(back_img_hal, LV_ALIGN_TOP_LEFT, 0, 0);
....以下绘制了一些用于显示内容的 box ,无论是否编译对该问题没有影响。
.
.
.
.
.
}
有没有大神帮忙分析一下,问题出在哪里?我该如何处理?
谢谢您的解答,不甚感激!