Description
I have a 320x170 (ST7789V2) LCD screen , I want to use it to display a GUI, and used the LVGL 8.3.5 graphics library to implement it. I wrote a demo scene by using GUI Guider 1.5.1, but the actual displayed on the lcd is a bit different from what I expected. The text and the picture appear blurry.
expect
but
Has anyone encountered such a phenomenon?
What MCU/Processor/Board and compiler are you using?
NXP I.MXRT1051, IAR ARM 9.40.1, LCD 320x170 with ST7789
What do you want to achieve?
Porting LVGL to the project for the GUI
What have you tried so far?
Implemented a driver for the ST7789V2 by using SPI DMA, and imported the LVGL library into the project, wrote a simple demo scene for testing, worked but the screen seems strange.
Code to reproduce
Add the relevant code snippets here.
The code block(s) should be between ```c
and ```
tags:
/*You code here*/
ST7789 Initialize
//************* Start Initial Sequence **********//
///< Software Reset
writeCommond(ST7789_SWRESET);
wait_ms(200);
///< Disable sleep
writeCommond(ST7789_SLPOUT);
wait_ms(200);
///< Vertical Scrolling Definition
writeCommond(ST7789_VSCRDEF);
writeData(0x00);
writeData(0x00);
writeData(0x14);
writeData(0x00);
writeData(0x00);
writeData(0x00);
///< Normal Display Mode On
writeCommond(ST7789_NORON);
wait_ms(10);
// Display Inversion: Invert the display colours (light becomes dark and vice versa) (ST7789 Datasheet Pages 188, 190)
if (INVERTED) {
writeCommond(ST7789_INVON);
} else {
writeCommond(ST7789_INVOFF);
}
// Set the read / write scan direction of the frame memory
writeCommond(ST7789_MADCTL); // MX, MY, RGB mode
writeData(0x70); // 0x08 set RGB
/* RGB 5-6-5-bit */
writeCommond(ST7789_COLMOD);
writeData(0x55);///< 65K, 16bit pixel
/** Display On */
writeCommond(ST7789_DISPON);
wait_ms(200);
/* Porch Setting */
writeCommond(ST7789_PORCTRL);
writeData(0x0C);
writeData(0x0C);
writeData(0x00);
writeData(0x33);
writeData(0x33);
/* Gate Control */
writeCommond(ST7789_GCTRL);
writeData(0x35);
/* VCOM Setting */
writeCommond(ST7789_VCOMS);
writeData(0x1A);
/* LCM Control */
writeCommond(ST7789_LCMCTRL);
writeData(0x2C);
/* VDV and VRH Command Enable */
writeCommond(ST7789_VDVVRHEN);
writeData(0x01);
/* VRH Set */
writeCommond(ST7789_VRHS);
writeData(0x0B);
/* VDV Set */
writeCommond(ST7789_VDVSET);
writeData(0x20);
/* Frame Rate Control in Normal Mode */
writeCommond(ST7789_FRCTR2);
writeData(0x0F);//60MHZ
/* Power Control 1 */
writeCommond(ST7789_PWCTRL1);
writeData(0xA4);
writeData(0xA1);
/* Positive Voltage Gamma Control */
writeCommond(ST7789_PVGAMCTRL);
writeData(0xF0);
writeData(0x00);
writeData(0x04);
writeData(0x04);
writeData(0x04);
writeData(0x05);
writeData(0x29);
writeData(0x33);
writeData(0x3E);
writeData(0x38);
writeData(0x12);
writeData(0x12);
writeData(0x28);
writeData(0x30);
/* Negative Voltage Gamma Control */
writeCommond(ST7789_NVGAMCTRL);
writeData(0xF0);
writeData(0x07);
writeData(0x0A);
writeData(0x0D);
writeData(0x0B);
writeData(0x07);
writeData(0x28);
writeData(0x33);
writeData(0x3E);
writeData(0x36);
writeData(0x14);
writeData(0x14);
writeData(0x29);
writeData(0x32);
/** Sleep Out */
writeCommond(ST7789_SLPOUT);
wait_ms(120);
/** Display On */
writeCommond(ST7789_DISPON);
#define LCD_WIDTH 320
#define LCD_HEIGHT 170
#define LCD_FB_BYTE_PER_PIXEL 2
#define LCD_VIRTUAL_BUF_SIZE (LCD_WIDTH * LCD_HEIGHT)
///< LVGL porting func
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t s_frameBuffer[2][LCD_VIRTUAL_BUF_SIZE * LCD_FB_BYTE_PER_PIXEL], 32);
void lv_port_disp_init(void)
{
static lv_disp_draw_buf_t disp_buf;
lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_VIRTUAL_BUF_SIZE);
/*-------------------------
* Initialize your display
* -----------------------*/
InitializeLCD();
/*-----------------------------------
* Register the display in LittlevGL
*----------------------------------*/
static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
lv_disp_drv_init(&disp_drv); /*Basic initialization*/
/*Set the resolution of the display*/
disp_drv.hor_res = LCD_WIDTH;
disp_drv.ver_res = LCD_HEIGHT;
/*Used to copy the buffer's content to the display*/
disp_drv.flush_cb = my_disp_flush;
/*Set a display buffer*/
disp_drv.draw_buf = &disp_buf;
/*Finally register the driver*/
lv_disp_drv_register(&disp_drv);
}
static void my_disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
int16_t w = (area->x2 - area->x1 + 1);
int16_t h = (area->y2 - area->y1 + 1);
uint32_t size = w * h * sizeof(lv_color_t);
// g_lcd_screen.ResetAddrWindow();
g_lcd_screen.setAddrWindow(area->x1, area->y1, area->x2, area->y2);
g_lcd_screen.writeData16Dma((uint8_t*)color_p, size);
lv_disp_flush_ready(disp_drv);
}
void setup_scr_startup(lv_ui *ui){
//Write codes startup
ui->startup = lv_obj_create(NULL);
lv_obj_set_scrollbar_mode(ui->startup, LV_SCROLLBAR_MODE_OFF);
//Set style for startup. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
lv_obj_set_style_bg_color(ui->startup, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_color(ui->startup, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_dir(ui->startup, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui->startup, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
//Write codes startup_startup_ip
ui->startup_startup_ip = lv_label_create(ui->startup);
lv_obj_set_pos(ui->startup_startup_ip, 23, 19);
lv_obj_set_size(ui->startup_startup_ip, 278, 32);
lv_obj_set_scrollbar_mode(ui->startup_startup_ip, LV_SCROLLBAR_MODE_OFF);
lv_label_set_text(ui->startup_startup_ip, "IP:\n");
lv_label_set_long_mode(ui->startup_startup_ip, LV_LABEL_LONG_WRAP);
//Set style for startup_startup_ip. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
lv_obj_set_style_radius(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(ui->startup_startup_ip, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_color(ui->startup_startup_ip, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_dir(ui->startup_startup_ip, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui->startup_startup_ip, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_width(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_color(ui->startup_startup_ip, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_opa(ui->startup_startup_ip, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_spread(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_ofs_x(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_ofs_y(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_color(ui->startup_startup_ip, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_font(ui->startup_startup_ip, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_letter_space(ui->startup_startup_ip, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_line_space(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_align(ui->startup_startup_ip, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_left(ui->startup_startup_ip, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(ui->startup_startup_ip, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(ui->startup_startup_ip, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
//Write codes startup_startup_name
ui->startup_startup_name = lv_label_create(ui->startup);
lv_obj_set_pos(ui->startup_startup_name, 23, 60);
lv_obj_set_size(ui->startup_startup_name, 172, 32);
lv_obj_set_scrollbar_mode(ui->startup_startup_name, LV_SCROLLBAR_MODE_OFF);
lv_label_set_text(ui->startup_startup_name, "Name:");
lv_label_set_long_mode(ui->startup_startup_name, LV_LABEL_LONG_WRAP);
//Set style for startup_startup_name. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
lv_obj_set_style_radius(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(ui->startup_startup_name, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_color(ui->startup_startup_name, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_dir(ui->startup_startup_name, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui->startup_startup_name, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_width(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_color(ui->startup_startup_name, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_opa(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_spread(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_ofs_x(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_ofs_y(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_color(ui->startup_startup_name, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_font(ui->startup_startup_name, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_letter_space(ui->startup_startup_name, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_line_space(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_align(ui->startup_startup_name, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_left(ui->startup_startup_name, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(ui->startup_startup_name, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(ui->startup_startup_name, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
//Write codes startup_startup_version
ui->startup_startup_version = lv_label_create(ui->startup);
lv_obj_set_pos(ui->startup_startup_version, 23, 102);
lv_obj_set_size(ui->startup_startup_version, 100, 32);
lv_obj_set_scrollbar_mode(ui->startup_startup_version, LV_SCROLLBAR_MODE_OFF);
lv_label_set_text(ui->startup_startup_version, "Version:\n");
lv_label_set_long_mode(ui->startup_startup_version, LV_LABEL_LONG_WRAP);
//Set style for startup_startup_version. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
lv_obj_set_style_radius(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(ui->startup_startup_version, lv_color_make(0x26, 0xB0, 0x8C), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_color(ui->startup_startup_version, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_grad_dir(ui->startup_startup_version, LV_GRAD_DIR_NONE, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui->startup_startup_version, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_width(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_color(ui->startup_startup_version, lv_color_make(0x21, 0x95, 0xf6), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_opa(ui->startup_startup_version, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_spread(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_ofs_x(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_shadow_ofs_y(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_color(ui->startup_startup_version, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_font(ui->startup_startup_version, &lv_font_montserratMedium_16, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_letter_space(ui->startup_startup_version, 2, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_line_space(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_text_align(ui->startup_startup_version, LV_TEXT_ALIGN_LEFT, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_left(ui->startup_startup_version, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(ui->startup_startup_version, 8, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(ui->startup_startup_version, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
//Write codes startup_img_1
ui->startup_img_1 = lv_img_create(ui->startup);
lv_obj_set_pos(ui->startup_img_1, 281, 8);
lv_obj_set_size(ui->startup_img_1, 32, 33);
lv_obj_set_scrollbar_mode(ui->startup_img_1, LV_SCROLLBAR_MODE_OFF);
//Set style for startup_img_1. Part: LV_PART_MAIN, State: LV_STATE_DEFAULT
lv_obj_set_style_img_recolor(ui->startup_img_1, lv_color_make(0xff, 0xff, 0xff), LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_img_recolor_opa(ui->startup_img_1, 0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_img_opa(ui->startup_img_1, 255, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_add_flag(ui->startup_img_1, LV_OBJ_FLAG_CLICKABLE);
lv_img_set_src(ui->startup_img_1,&_heart_alpha_32x33);
lv_img_set_pivot(ui->startup_img_1, 50,50);
lv_img_set_angle(ui->startup_img_1, 0);
//Init events for screen
events_init_startup(ui);
}
Color setting in lv_conf.h
/*====================
COLOR SETTINGS
*====================*/
/*Maximal horizontal resolution*/
#define LV_HOR_RES_MAX (320)
#define LV_VER_RES_MAX (170)
#define LV_COLOR_DEPTH 16
#define LV_COLOR_16_SWAP 1
#define LV_COLOR_SCREEN_TRANSP 1
#define LV_COLOR_MIX_ROUND_OFS 64
#define LV_DPI_DEF 100
#define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00)
#define LV_DRAW_COMPLEX 1
#define LV_SHADOW_CACHE_SIZE 0
#define LV_CIRCLE_CACHE_SIZE 4
#define LV_BIG_ENDIAN_SYSTEM 0
#define LV_ATTRIBUTE_TICK_INC
#define LV_ATTRIBUTE_TIMER_HANDLER
#define LV_ATTRIBUTE_FLUSH_READY
#define LV_ATTRIBUTE_MEM_ALIGN_SIZE 64
#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1
Screenshot and/or video
If possible, add screenshots and/or videos about the current state.