lvgl_demo — интерфейс на LVGL с сенсорным экраном
Экран с показаниями платы на библиотеке LVGL 9: температура кристалла, свободная память, адреса сети, графики температуры, загрузки процессора, ОЗУ и SDRAM за две минуты, переключатель светодиода. Русский текст — шрифтом TTF с SD-карты.
Подключение
Заголовок раздела «Подключение»Дисплей RGB 800×480 (RGB050M1) — как в рецепте lcd_ltdc. Сенсорная панель GT911 — на I2C1:
| Сигнал тача | Вывод | Контакт |
|---|---|---|
| SCL | PB8 | J1-26 |
| SDA | PB7 | J1-23 |
| INT | PB9 | J1-25 |
| RST | PD4 | J1-17 |
На SD-карте — шрифты /SD/fonts/PT_Sans-Web-Regular.ttf и PT_Sans-Web-Bold.ttf
(есть в архиве sd-card.zip; без них экран работает со встроенным шрифтом без кириллицы).
Включить
Заголовок раздела «Включить»LVGL занимает ~240 КБ Flash, поэтому вместе со всем остальным прошивка не помещается:
выключается Lua (или SSH, -DH723_WITH_SSH=OFF).
cmake --preset Release -DH723_WITH_LUA=OFF -DH723_RECIPES="lvgl_demo"cmake --build build/ReleaseПрошивка с SSH и LVGL — 724 КБ.
Вывод на плате
Заголовок раздела «Вывод на плате»lvgl_demo: startedgt911: product 911, panel 800x480lvgl_demo: fonts loaded in 105 mslvgl_demo: screen ready, full redraw 52881 usПолная перерисовка экрана — 53 мс; дальше LVGL перерисовывает только изменившееся (раз в секунду — цифры и графики). Загрузка процессора при этом — около 5 %.
Как это работает
Заголовок раздела «Как это работает»- Задача LVGL одна. LVGL не потокобезопасна: интерфейс создаётся и меняется только в задаче
lvgl, которая крутитlv_timer_handler(). Данные от других задач — через очередь или флаги, которые читает таймер LVGL (lv_timer_create). - Вывод — прямо в кадровые буферы LTDC (
LV_DISPLAY_RENDER_MODE_DIRECT). Буферов два, в SDRAM; LVGL рисует в невидимый и сама переносит изменённые места из видимого. Функция вывода (flushвlvgl_port.c) выгружает кэш и показывает готовый буфер с ближайшего кадра (lcdShowизlcd_ltdc). - Кэш. Процессор рисует через кэш (write-back), а LTDC читает память напрямую, поэтому перед показом весь кэш данных (32 КБ) выгружается в SDRAM — это быстрее, чем выгружать буфер построчно. Операции DMA2D LVGL сама окружает выгрузкой и инвалидацией кэша.
- DMA2D (
LV_USE_DRAW_DMA2D) заливает прямоугольники и копирует картинки, процессору остаются буквы, скругления и линии графиков. - Память LVGL — в SDRAM:
lv_malloc_coreи соседние функции вlvgl_port.cвызываютsdramMalloc(LV_USE_STDLIB_MALLOC = LV_STDLIB_CUSTOM). - Шрифты с карты. Tiny TTF (
LV_USE_TINY_TTF) рисует буквы из файла TTF любого размера. Файл один раз читается в SDRAM (lvglLoadFont), следующие размеры используют те же данные; нарисованные буквы кэшируются. Во Flash шрифтов нет, кроме запасного латинского. - Файлы для LVGL — буква
S::"S:fonts/x.ttf"открывается как/SD/fonts/x.ttf(LV_USE_FS_STDIO). Так же загружаются картинки. - Тач GT911 опрашивается по I2C при каждом обновлении LVGL (раз в 20 мс): регистр
состояния
0x814E(бит 7 — новые данные), координаты первого касания с0x8150, затем состояние сбрасывается записью нуля. При сбросе уровень INT задаёт адрес контроллера (0 — 0x5D). Разрешение панели контроллер хранит сам —gt911: panel 800x480. - Размер. В
config/lv_conf.hвыключены ненужные форматы пикселей программного рисования (каждый — десятки КБ), LVGL собирается с-Os(recipe.cmake). - Зависимости рецепта — в
recipe.cmake: исходники LVGL изthird_party/lvglи драйвер дисплея из рецептаlcd_ltdc(его пример при этом не запускается).
Переделать под себя
Заголовок раздела «Переделать под себя»- Свой экран — функция
buildScreenвlvgl_demo.c; документация и примеры виджетов — docs.lvgl.io. - Экраны можно собирать мышкой в SquareLine Studio или EEZ Studio — они выдают код на C для LVGL 9.
- Другой шрифт — любой TTF с кириллицей на карте и путь в
lvgl_demo.h. Шрифты бывают большими: для экономии SDRAM подходят версии с урезанным набором символов. - Картинки — PNG или BMP на карте (
LV_USE_LODEPNG/LV_USE_BMPвlv_conf.h) иlv_image_set_src(img, "S:images/logo.png"). - На той же шине I2C1 можно держать и другие датчики (например, BME280 из рецепта i2c_bme280), но HAL I2C не потокобезопасен — обращения к шине из разных задач нужно закрыть мьютексом.
Исходники рецепта: recipes/lvgl_demo
