На STM32F407 перенесена графическая библиотека LVGL, LCD-экран модели MSP3526; при желании сменить экран достаточно подправить драйвер дисплея. Проект представлен в двух версиях — с FreeRTOS и «голый» (bare-metal). Экран управляется по SPI с DMA.
Разрешение дисплея 320×480, диагональ 3,5 дюйма, контроллер дисплея ST7796, интерфейс SPI; контроллер емкостного тачскрина FT6336U, интерфейс I²C.
После разгона MCU полный кадр выдаёт ≈ 9 FPS, при частичном обновлении 30+ FPS; для SPI, думаю, вполне нормально.
- STM32 читает датчик температуры/влажности SHTC3 аппаратным I²C: https://blog.zeruns.com/archives/692.html
- Шаблон проекта STM32F407 со стандартной библиотекой и готовой U8g2: https://blog.zeruns.com/archives/722.html
- Драйвер 0,96″ OLED на STM32G4 (HAL), железный/программный I²C: https://blog.zeruns.com/archives/776.html
Чат по электронике/микроконтроллерам: 2169025065
Демонстрация
Видео-обзор: https://www.bilibili.com/video/BV1Ni421S7ta/
О LVGL
LVGL (Light and Versatile Graphics Library) — бесплатная библиотека с открытым исходным кодом для создания встроенных GUI: красивые элементы, плавная анимация, минимальный расход памяти.
Ключевые возможности:
- Богатый набор модулей: кнопки, графики, списки, слайдеры, изображения и др.
- Продвинутый 2-D-движок: анимация, сглаживание, прозрачность, плавный скролл, слои.
- Поддержка тачскринов, клавиатур, энкодеров, физических кнопок.
- Множество дисплеев.
- Независим от железа; работает на любом экране.
- Конфигурируемость (минимум: 64 кБ Flash, 16 кБ RAM).
- UTF-8 и многоязычность: китайский, японский, корейский, арабский и др.
- CSS-подобные layout-менеджеры: Flexbox, Grid.
- Работает под ОС, с внешней памятью, умеет DMA2D (STM32), PXP (NXP), VGLite.
- Плавная отрисовка даже при одном буфере кадра.
- Полностью на C, вызывается из C++.
- Поддержка MicroPython.
- Симулятор для разработки без платы.
- Обширные примеры и документация.
- Лицензия MIT.
Минимальные требования:
- 16-, 32- или 64-битный контроллер/процессор
- Частота >16 МГц (рекомендовано)
- Flash/ROM: >64 кБ (желательно >180 кБ)
- RAM:
– статика: ~2 кБ
– стек: >2 кБ (желательно >8 кБ)
– динамика (heap): >2 кБ (желательно >16 кБ), задаётся LV_MEM_SIZE в lv_conf.h
– буфер дисплея: >горизонтальное разрешение (желательно >10×гориз. разреш.)
– один фреймбуфер в MCU или внешнем контроллере - Компилятор C99 или новее
Сайт: https://lvgl.io/
Подключение
| LCD | MCU/плата | Назначение |
|---|---|---|
| GND | GND | Земля дисплея |
| VCC | 5В или 3,3В | Питание дисплея |
| LCD_CS | PE6 | CS SPI |
| LCD_RST | PC1 | Сброс дисплея |
| LCD_RS | PC0 | DC (Data/Command) |
| SDI/MOSI | PB5 | SPI данные, Master→Slave |
| SCK | PB3 | SPI такт |
| LED | 3,3В | Подсветка (можно на GPIO для ШИМ-CTL) |
| SDO/MISO | PB4 | SPI данные, Slave→Master |
| CTP_SCL | PB8 | I²C часовая линия тачскрина |
| CTP_RST | PB7 | Сброс контроллера тачскрина |
| CTP_SDA | PB9 | I²C данные тачскрина |
| CTP_INT | PB6 | Прерывание тачскрина |
PB4 на моей плате не выведен на боковые pin-headers, а находится в разъёме JTAG сверху.
Документация и прошивки
Онлайн-документация на экран: https://url.zeruns.com/68x3Y
Архив с доками, скачать (1): https://www.123pan.com/s/2Y9Djv-rZevH.html
Архив с доками, скачать (2): https://url.zeruns.com/gzBO4
Bare-metal проект STM32F407+LVGL (1): https://url.zeruns.com/X242k
Bare-metal проект STM32F407+LVGL (2): https://pan.baidu.com/s/1vAhHijYd_aWvRr3_c1_WtA?pwd=ry4g
FreeRTOS-проект STM32F407+LVGL (1): https://www.123pan.com/s/2Y9Djv-CzevH.html
FreeRTOS-проект STM32F407+LVGL (2): https://url.zeruns.com/0iOHF
Поставьте звёздочку ★
Gitee (开源): https://gitee.com/zeruns/STM32F407_LVGL_Template_MSP3526
GitHub: https://github.com/zeruns/STM32F407_LVGL_Template_MSP3526
Актуальная версия на Gitee/GitHub уже с FreeRTOS; bare-metal-вариант лежит в разделе Releases, версия 0.1.3.
Проект сгенерирован STM32CubeMX, разработка в Keil5 + VScode + EIDE.
Перенос делал по урокам от «正点原子».
Видео-уроки «正点原子» по LVGL:
Скачать (1): https://www.123pan.com/s/2Y9Djv-0ZevH.html
Скачать (2): https://www.alipan.com/s/Pd6TDfT2rBL
Как пользоваться
Скачайте, соберите, залейте — всё работает.
Чтобы убрать счётчики FPS и памяти, в lv_conf.h замените 1 на 0:
/*1: Show CPU usage and FPS count*/
#define LV_USE_PERF_MONITOR 1
#if LV_USE_PERF_MONITOR
#define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
#endif
/*1: Show the used memory and the memory fragmentation
* Requires LV_MEM_CUSTOM = 0*/
#define LV_USE_MEM_MONITOR 1
#if LV_USE_MEM_MONITOR
#define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
#endif
```
Если используется версия с FreeRTOS, пишите код в файле `freertos.c`; можно создавать потоки и семафоры в STM32CubeMX, а затем генерировать код — весь код размещается в строго указанных местах, и повторная генерация не затрёт ваши изменения. Для «голой» прошивки просто пишите код в `main.c`.
Чтобы отключить демо-программу, закомментируйте фрагмент, показанный на рисунке ниже.

## Адреса покупки компонентов
- Плата разработки STM32F407VET6: [https://s.click.taobao.com/sQSMWmt](https://s.click.taobao.com/t?e=m%3D2%26s%3DGxUVgIOWBWVw4vFB6t2Z2ueEDrYVVa64g3vZOarmkFi53hKxp7mNFrMfIvbtZ%2F%2B2IT%2BVhjqUP7X0JlhLk0Jl4QTquP0kWxBLBDnvz6xo38xspWc9%2BCL4bTGF1ceZMhPo8mL8HhJ3EdVrH4ks4QyiY4z4rjZDGVMAhscfsB2%2FyzZJq71CBMBeP%2F1SarTXhIOTsgIpc1WFZiJNubylQlnZt0ft88oCh4qlKjZ0Zrpn9cYR7kNHbGZ5w15bTaW0%2FWfaQBd0yVbMw3IeTeL3FeYp0owmLWBgEm80VKxcI130SjETn2JhMaQNtYWLhXkoGmYygFktLIh%2BAXuBHaXkFVFVVsYOae24fhW0&union_lens=lensId%3APUB%401716477927%40212abf30_0d16_18fa60ea164_1890%40025BlJPZdLaOG4oFPxX7gKUY%40eyJmbG9vcklkIjo4MDY3NCwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfcHJvbW9fZ29vZHNfaW5kZXhfaHRtIiiwiic3JjRmxvb3JJZCI6IjgwNjc0In0ie%3BtkScm%3AselectionPlaza_site_4358%3Bscm%3A1007.30148.329090.pub_search-item_5a7fc953-12f7-46f5-8abf-f0725f8174cf_)
- Отладчик Daplink: [https://s.click.taobao.com/9kMKWmt](https://s.click.taobao.com/t?e=m%3D2%26s%3DTHTCnVvsTHtw4vFB6t2Z2ueEDrYVVa64YUrQeSeIhnK53hKxp7mNFrMfIvbtZ%2F%2B2mFKI%2FmDcMIH0JlhLk0Jl4QTquP0kWxBLBDnvz6xo38xspWc9%2BCL4bTGF1ceZMhPo8mL8HhJ3EdVrH4ks4QyiY4z4rjZDGVMAFBcM8wkWlGmBPeR%2FUFCetKLWMw3EOEsyJN2owMjhufwDudUsQ2T%2Bdnc9abdYtRqDTzYdoB%2FDOjstFZhpb%2ByhLzPbHWUbis%2BWsZGiFV6vs3eSWi1ViPhRlULEkqTedE399KEV1g6mN9AKChukhDzWey1fmH6DK4UhxgxdTc00KD8%3D&union_lens=lensId%3APUB%401716478245%4021673e1b_0d06_18fa6137a23_e4cb%40023uxCV3Edv0RnAmphuKflFP%40eyJmbG9vcklkIjo4MDY3NCwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfcHJvbW9fZ29vZHNfaW5kZXhfaHRtIiiwiic3JjRmxvb3JJZCI6IjgwNjc0In0ie%3BtkScm%3AselectionPlaza_site_4358%3Bscm%3A1007.30148.329090.pub_search-item_be2f7d85-fcee-40ff-96c5-d9d5bd472c5d_)
- Дисплей MSP3526: [https://s.click.taobao.com/i1Z29nt](https://s.click.taobao.com/t?e=m%3D2%26s%3DepCXgq%2FZmWBw4vFB6t2Z2ueEDrYVVa64g3vZOarmkFi53hKxp7mNFrMfIvbtZ%2F%2B2tJl3z4Kcvjj0JlhLk0Jl4QTquP0kWxBLBDnvz6xo38xspWc9%2BCL4bTGF1ceZMhPo8mL8HhJ3EdVrH4ks4QyiY4z4rjZDGVMA%2FEM5jbZlb7P9R7R4oT9ML5ESMSIvSnZOMN7NXhFCiynJvjSktgLu1nmUrf%2BRsjyAm8kA6wY1r21y2p9AgG%2F91VmfPAhbcEJheBtNII99o%2FtnjWeMZ%2B39PZGZ9wPRcXV%2BQ%2FMlsmagC3ST4aDEgnPNca8ZkUY0DmW2xiXvDf8DaRs%3D&skuId=5223178287593&union_lens=lensId%3APUB%401716478528%40212c5298_0d1d_18fa617cd1e_3501%40034rs5qkRnldNGhC5eLF4gZ4%40eyJmbG9vcklkIjo4NTQ2Nywiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfcHJvbW9fZ29vZHNfZGV0YWlsX2h0bSIsInNyY0Zsb29ySWQiiOiiI4MDY3NCJ9%3BtkScm%3AselectionPlaza_site_4358%3Bscm%3A1007.30148.329090.pub_search-item_18bdbb55-0a4c-494e-96fc-a14c1b4c6732_)
- Провода «Дюпон»: [https://s.click.taobao.com/W1wHWmt](https://s.click.taobao.com/t?e=m%3D2%26s%3DD%2BKEsm2G8bhw4vFB6t2Z2ueEDrYVVa64g3vZOarmkFi53hKxp7mNFrMfIvbtZ%2F%2B2Sn8%2BqdSFAFT0JlhLk0Jl4QTquP0kWxBLBDnvz6xo38xspWc9%2BCL4bTGF1ceZMhPo8mL8HhJ3EdVrH4ks4QyiY4z4rjZDGVMAhscfsB2%2FyzZJq71CBMBeP%2F1SarTXhIOTsgIpc1WFZiJNubylQlnZt5Tr%2BZsTRXxVoTwQXkQy%2BZ5FeGSAzHUbnuYhpSNeyz6v9H5aeGRpz8mogVv1SEjhEYwmLWBgEm80VKxcI130SjETn2JhMaQNtYWLhXkoGmYyO0%2FufYOLJc1EEap0MMy2i8YOae24fhW0&union_lens=lensId%3APUB%401716478612%402104b45c_0cd2_18fa619123a_652e%40023dY61JLu6wYjo297E4L0ip%40eyJmbG9vcklkIjo4MDY3NCwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfcHJvbW9fZ29vZHNfaW5kZXhfaHRtIiiwiic3JjRmxvb3JJZCI6IjgwNjc0In0ie%3BtkScm%3AselectionPlaza_site_4358%3Bscm%3A1007.30148.329090.pub_search-item_c09a2639-b75e-40a9-8886-2b13dfb05f6a_)
- Плата разработки STM32F407VGT6: [https://s.click.taobao.com/VjC29nt](https://s.click.taobao.com/t?e=m%3D2%26s%3DimgWkSQh79Jw4vFB6t2Z2ueEDrYVVa64g3vZOarmkFi53hKxp7mNFrMfIvbtZ%2F%2B2VCC9Q%2BPYiL70JlhLk0Jl4QTquP0kWxBLBDnvz6xo38xspWc9%2BCL4bTGF1ceZMhPo8mL8HhJ3EdVrH4ks4QyiY4z4rjZDGVMAhscfsB2%2FyzZJq71CBMBeP%2F1SarTXhIOTsgIpc1WFZiJNubylQlnZt1PgRVjPwS2ItjXwer7KgrNYvdwnwfvUuaclSgSzfliuRVQ2zHzYrnKVyphVinEJT4wmLWBgEm80VKxcI130SjETn2JhMaQNtYWLhXkoGmYy0ZHJIUNbntFzUAbdwYp3usYOae24fhW0&union_lens=lensId%3APUB%401716478657%4021547cbb_0d71_18fa619c373_1476%40027J4l8QPFtC3F2VYygWUUdV%40eyJmbG9vcklkIjo4MDY3NCwiic3BtQiiI6Il9wb3J0YWxfdjJfcGFnZXNfcHJvbW9fZ29vZHNfaW5kZXhfaHRtIiiwiic3JjRmxvb3JJZCI6IjgwNjc0In0ie%3BtkScm%3AselectionPlaza_site_4358%3Bscm%3A1007.30148.329090.pub_search-item_a456d2bb-5c50-4eb6-a55f-0e6f4ff87eed_)
## Основной фрагмент кода
Практически всё сводится к вызову в функции `disp_flush` файла `lv_port_disp.c` следующей заливки LCD. Драйвер дисплея доработан на основе официального примера от производителя экрана.
```c
/**
* @brief Заливка прямоугольной области LCD
* Заливка указанной области экрана цветами из LVGL.
* @param sx начальная координата X
* @param sy начальная координата Y
* @param ex конечная координата X
* @param ey конечная координата Y
* @param color_p указатель на массив цветов
*/
void LCD_Fill_LVGL(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, lv_color_t *color_p)
{
uint32_t i, j;
uint16_t width = ex - sx + 1; // ширина области
uint16_t height = ey - sy + 1; // высота области
uint32_t Pixel = width * height; // число пикселей
LCD_SetWindows(sx, sy, ex, ey); // установить окно вывода
// for (i = 0; i < height; i++)
// {
// for (j = 0; j < width; j++){
// Lcd_WriteData_16Bit(color_p->full);
// }
// }
// порция данных для DMA-передачи
#define data_split 3000
uint8_t data[Pixel * 2]; // массив цветовых данных
for (i = 0; i < Pixel; i++)
{
// разложить 16-битный цвет на два байта
data[i * 2] = (color_p->full) >> 8; // старший байт
data[i * 2 + 1] = (uint8_t)(color_p->full); // младший байт
color_p++; // следующий цвет
// если пикселей больше 10 000 — отправляем порциями
if (Pixel > 10000)
{
if ((i + 1) % data_split == 0)
{
if ((i + 1) == data_split)
{
Lcd_WriteData_DMA(data, data_split * 2);
}
else
{
while (HAL_SPI_GetState(LCD_SPI) != HAL_SPI_STATE_READY);
uint8_t *temp = &data[((uint16_t)((i + 1) / data_split) - 1) * data_split * 2];
Lcd_WriteData_DMA(temp, data_split * 2);
}
}
else if (((i + 1) % data_split > 0) && ((i + 1) > data_split) && (i == (Pixel - 1)))
{
if ((uint16_t)((i + 1) / data_split) == 1)
{
while (HAL_SPI_GetState(LCD_SPI) != HAL_SPI_STATE_READY);
uint8_t *temp = &data[data_split * 2];
Lcd_WriteData_DMA(temp, ((i + 1) % data_split) * 2);
}
else
{
while (HAL_SPI_GetState(LCD_SPI) != HAL_SPI_STATE_READY);
uint8_t *temp = &data[(uint16_t)((i + 1) / data_split) * data_split * 2];
Lcd_WriteData_DMA(temp, ((i + 1) % data_split) * 2);
}
}
}
}
if (Pixel <= 10000)
{
// малый объём — отправить за один раз
Lcd_WriteData_DMA(data, Pixel * 2);
}
LCD_SetWindows(0, 0, lcddev.width - 1, lcddev.height - 1); // вернуть полный экран
}
Другие открытые проекты
- Трёхфазный измеритель электроэнергии (open-source): удобный контроль потребления дома — https://blog.zeruns.com/archives/771.html
- Шаблон проекта STM32F407 с портом графической библиотеки U8g2 — https://blog.zeruns.com/archives/722.html
- Минимальная плата на CH32V307VCT6 (WCH) — https://blog.zeruns.com/archives/726.html
- Автоматический Buck-Boost DC-DC на LM25118 — https://blog.zeruns.com/archives/727.html
- Синхронный повышающий модуль на EG1164, КПД до 97 % — https://blog.zeruns.com/archives/730.html
- 4G-узел мониторинга на Air700E (LuatOS), публикация данных в Alibaba Cloud через MQTT — https://blog.zeruns.com/archives/747.html
- Интеллектуальная электронная нагрузка на CH32V307 (проект с соревнований, open-source) — https://blog.zeruns.com/archives/785.html
Рекомендуем к прочтению
- Подборка недорогих VPS/облачных серверов с хорошим соотношением цена/качество: https://blog.zeruns.com/archives/383.html
- Как поднять свой сервер Minecraft: https://blog.zeruns.com/tag/mc/
- Обзор цифрового лабораторного блока Ruideng RD6012P (60 V, 12 A): https://blog.zeruns.com/archives/740.html
- Опыт использования 3D-принтера Bambu Lab P1SC: https://blog.zeruns.com/archives/770.html
- Сравнение разных типов конденсаторов и индуктивностей (D, Q, ESR, X): https://blog.zeruns.com/archives/765.html
- Разбор 120-Вт зарядки за 2.6 юаня из TikTok-Shop: https://blog.zeruns.com/archives/786.html





