LVGL(Light and Versatile Graphics Library)是一款开源的嵌入式图形库,专为资源受限的嵌入式系统设计,具有轻量、高效、可定制性强等特点。

一、LVGL 在 STM32 上的架构

要理解 LVGL 如何在 STM32 上工作,首先需要了解其软件架构。LVGL 本身是硬件无关的,它通过一系列驱动接口与你的硬件进行交互。下图清晰地展示了这一架构:

  • 显示驱动 (Display Driver): 你实现一个 flush_cb 回调函数。当 LVGL 需要刷新一块屏幕区域时(如图形变化),它会调用这个函数,并告诉你“把这块内存数据(color_buf)刷到屏幕的(x1, y1)到(x2, y2)这个区域”。你在这个函数里实现真正的屏幕写操作。

  • 输入设备驱动 (Input Device Driver): 你实现一个 read_cb 回调函数。LVGL 会定期调用这个函数并询问:“有输入事件吗?(比如触摸)” 你在这个函数里读取触摸屏或按键的数据,并返回给 LVGL。

  • 心跳驱动 (Tick Source): 你需要提供一个定时器中断(如 1ms),并在中断中调用 lv_tick_inc(1)。这是 LVGL 处理动画、延时等所有内部计时的基础。

二、在 STM32 上移植 LVGL 的关键步骤

1.获取 LVGL 源码放入你的 STM32 项目工程中。
2.   硬件准备
  • 显示屏:选择并驱动一个 LCD(如 SPI 屏、Parallel RGB 屏、MIPI DSI 屏)。STM32 通常使用 FSMC/FMC 并行接口驱动屏幕速度最快,SPI 接口次之。

  • 触摸屏:如果需要触摸,驱动触摸 IC(通常是电阻屏或电容屏,通过 I2C 或 SPI 通信)。

  • 定时器:配置一个定时器(如 Systick 或 TIMx)产生 1ms 中断。

3. 移植显示驱动

这是最核心的一步。你需要修改 lv_conf.h 和实现 lv_port_disp_init()

  • lv_conf.h

    • 将 #if 0 改为 #if 1 以启用配置。

    • 设置 LV_HOR_RES_MAX 和 LV_VER_RES_MAX 为你的屏幕分辨率。

    • 根据你的 MCU 性能调整颜色深度 (LV_COLOR_DEPTH),通常 16 位 (LV_COLOR_DEPTH_16) 即可。

    • 根据你的内存情况调整 LV_MEM_SIZE(非常重要!)。

  • 显示接口函数

    • 实现 disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_map)

    • 在此函数中,将 color_map 中的数据拷贝到屏幕的指定区域 (x1, y1x2, y2)。

    • 对于 FSMC/FMC 驱动的屏幕,这通常意味着直接进行内存拷贝

    • 对于 SPI 屏幕,你需要通过 SPI 发送数据和命令。

    • 完成后必须调用 lv_disp_flush_ready() 来通知 LVGL 刷新完成。

4. 移植输入设备驱动(可选)

如果需要触摸,你需要修改 lv_port_indev_init()

  • 实现 touchpad_read(lv_indev_data_t * data)

  • 在此函数中,读取触摸 IC 的数据,填充 data->point.xdata->point.y 和 data->state (如 LV_INDEV_STATE_PR 或 LV_INDEV_STATE_REL)。

  • 将输入设备类型注册为 LV_INDEV_TYPE_POINTER

5.提供心跳
  • 在 1ms 的定时器中断服务函数中调用 lv_tick_inc(1)

6. 主程序逻辑
  • 初始化硬件(LCD、触摸屏、定时器)。

  • 调用 lv_init()

  • 调用你的 lv_port_disp_init() 和 lv_port_indev_init()

  • 在 while(1) 主循环中,不断调用 lv_task_handler(),并插入适当的延时(如 5-30ms)

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐