LVGL (Light and Versatile Graphics Library) je bezplatná grafická knihovna s otevřeným zdrojovým kódem, která poskytuje vše potřebné k vytvoření vestavěného grafického rozhraní se snadno použitelnými grafickými prvky, krásnými vizuálními efekty a nízkou paměťovou náročností.

Vlastnosti

  • Výkonné stavební bloky, jako jsou tlačítka, grafy, seznamy, posuvníky, obrázky atd.

  • Pokročilá grafika s animacemi, vyhlazováním hran, neprůhledností a plynulým rolováním

  • Různá vstupní zařízení, jako je touchpad, myš, klávesnice, enkodér atd.

  • Vícejazyčná podpora s kódováním UTF-8

  • Podpora více displejů, a to i se smíšenými barevnými formáty

  • Plně přizpůsobitelné grafické prvky se styly podobnými CSS

  • Nezávislý na hardwaru: použití s ​​jakýmkoli mikrokontrolérem nebo displejem

  • Škálovatelný: schopný pracovat s malým množstvím paměti (64 kB Flash, 16 kB RAM)

  • OS, externí paměť a grafická karta jsou podporovány, ale nejsou vyžadovány

  • Provoz s jedním snímkovým bufferem i s pokročilými grafickými efekty

  • Napsáno v jazyce C pro maximální kompatibilitu (kompatibilní s C++)

  • Simulátor pro zahájení návrhu vestavěného grafického rozhraní na PC bez vestavěného hardwaru

  • Uživatelský kód vyvinutý v simulátoru lze sdílet s firmwarem, aby se zefektivnil vývoj uživatelského rozhraní.

  • Vazba na MicroPython

  • Návody, příklady, šablony pro rychlý návrh GUI

  • Dokumentace je k dispozici online

  • Zdarma a s otevřeným zdrojovým kódem pod licencí MIT

Jednoduchý program

Program, kde budeme provozovat LCD display s dotykovou obrazovkou a ukážeme ovládání vestavěné LED.

lcdTest.cpp
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"
#include "hardware/i2c.h"
#include "hardware/dma.h"
#include "hardware/pio.h"
#include "hardware/gpio.h"
#include "ili9341.h"
#include "xpt2046.h"
#include "lvgl.h"


static lv_draw_buf_t *buf1;
static lv_draw_buf_t *buf2;
static lv_obj_t *screen;

void lv_example_event_click(void);
static void event_cb(lv_event_t * e);

// stav LED diody GP25
bool led_stav = false;

int main()
{
    stdio_init_all();
    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    gpio_put(25,led_stav);

    ili9341_Init(LCD_INV_PORTRAIT);
    xpt2046_Init(TP_INV_PORTRAIT);

    lv_init();
    // nastavení displeje
    lv_display_t *disp = lv_display_create(240, 320);
    lv_display_set_flush_cb(disp, lcd_Flash_CB);
    buf1 = lv_draw_buf_create(240, 32, LV_COLOR_FORMAT_RGB565, LV_STRIDE_AUTO);
    buf2 = lv_draw_buf_create(240, 32, LV_COLOR_FORMAT_RGB565, LV_STRIDE_AUTO);
    lv_display_set_draw_buffers(disp, buf1, buf2);
    // lv_display_set_buffers(disp, buf1, buf2, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);
    lv_display_set_render_mode(disp, LV_DISPLAY_RENDER_MODE_PARTIAL);
    screen = lv_obj_create(NULL);

    // vstupní zařízení - dotyková obrazovka
    lv_indev_t *indev = lv_indev_create();
    lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
    lv_indev_set_read_cb(indev, xpt2046_read_cb);
    lv_screen_load(screen);
    lv_example_event_click();

    while (1)
    {
        sleep_ms(5);
        lv_timer_handler();
        lv_tick_inc(5);
    }
}


// obsluha událostí na tlačítku
static void event_cb(lv_event_t * e)
{
    LV_LOG_USER("Clicked");

    static uint32_t cnt = 1;
    lv_obj_t * btn = lv_event_get_target_obj(e);
    lv_obj_t * label = lv_obj_get_child(btn, 0);
    if(led_stav == false) {
        gpio_put(25,true);
        led_stav = true;
        lv_label_set_text_fmt(label, "Vypnout %" LV_PRIu32, cnt);
    } else {
        gpio_put(25,false);
        led_stav = false;
        lv_label_set_text_fmt(label, "Zapnout %" LV_PRIu32, cnt);
    }

    cnt++;
}

/**
 * Tlačítko s reakcí na stisknutí
 */
void lv_example_event_click(void)
{
    // Změna pozadí obrazovky
    lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x003a57), LV_PART_MAIN);

    // vytvoření tlačítka
    lv_obj_t * btn = lv_button_create(lv_screen_active());
    lv_obj_set_size(btn, 100, 50);
    lv_obj_center(btn);
    // události na tlačítku bude obsluhovat funkce `event_cb`
    lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);

    // nastavení popisky tlačítka
    lv_obj_t * label = lv_label_create(btn);
    lv_label_set_text(label, "Ovladani LED");
    lv_obj_center(label);
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

set(PICO_DEOPTIMIZED_DEBUG=1)

# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})

set(PICO_BOARD pico CACHE STRING "Board type")

# Pull in Raspberry Pi Pico SDK (must be before project)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)

if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0")
  message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()

project(lcdTest C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

# Add executable. Default name is the project name, version 0.1

add_executable(
  lcdTest
  lcdTest.cpp
  ili9341.h
  ili9341.c
  xpt2046.h
  xpt2046.c
  pio_spi.c
)


pico_set_program_name(lcdTest "lcdTest")
pico_set_program_version(lcdTest "0.1")

pico_enable_stdio_uart(lcdTest 0)
pico_enable_stdio_usb(lcdTest 1)

pico_generate_pio_header(lcdTest ${CMAKE_CURRENT_LIST_DIR}/spi.pio)

# Add the standard library to the build
target_link_libraries(lcdTest
        pico_stdlib)

# Add the standard include files to the build
target_include_directories(lcdTest PRIVATE
  ${CMAKE_CURRENT_LIST_DIR}
  ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required
)

# Add any user requested libraries
target_link_libraries(
        lcdTest
        hardware_gpio
        hardware_spi
        hardware_i2c
        hardware_dma
        hardware_pio
        hardware_pwm
	    lvgl
        )

pico_add_extra_outputs(lcdTest)

set(LV_CONF_BUILD_DISABLE_THORVG_INTERNAL 1)
set(LV_CONF_BUILD_DISABLE_EXAMPLES 1)
set(LV_CONF_BUILD_DISABLE_DEMOS 1)
add_subdirectory(lvgl)
Zapojení pinů displeje ili9341.c
#define LCD_MISO 12
#define LCD_CS 9
#define LCD_SCK 10
#define LCD_MOSI 11
#define LCD_RESET 15
#define LCD_DC 8
#define LCD_LED 13
Zapojení pinů touchpadu xpt2046.c
#define XPT2046_CS 16
#define XPT2046_CLK 17
#define XPT2046_MOSI 18
#define XPT2046_MISO 19
Konstrukce

IMG 20250707 065910

Tabulka 1. Tabulka zapojení pinů
LCD display pin Raspberry Pi Pico pin barva

VCC

3.3V

červená

GND

0V

černá

CS (chip select)

GP9

žlutá

RESET

GP15

oranžová

DC

GP8

modrá

SDI (MOSI)

GP11

fialová

SCK

GP10

šedá

LED

GP13

červená

SDO (MISO)

GP12

zelená

T_CLK

GP17

šedá

T_CS

GP16

žlutá

T_DIN (MOSI)

GP18

fialová

T_DO (MISO)

GP19

zelená

T_IRQ

nezapojeno

Ovládání LED na pinu GP25
Otočení videa
ffmpeg -i VID_20250707_070005.mp4 -vf "transpose=2" -acodec copy ili9341_grafika1.mp4