概念先知道
- LVGL v8:LVGL 图形库的成熟稳定版本,控件与绘图 API 与 v9 大同小异,但部分接口不同(详见 FAQ)。
- tick 驱动方式差异:v8 例程没有显式设置 tick 回调(由
lv_port_disp_init内部用lv_tick_inc驱动),v9 则用lv_tick_set_cb注册回调。 - 显示驱动:同样通过
lv_port_disp_init初始化 LCD,屏幕型号/引脚在lcd_conf_user.h中配置。 - 演示切换:默认跑 benchmark,注释里提供了 widgets、music、stress 等演示,取消注释即可切换。
例程功能简介
本页对应博流官方 SDK 的 lvgl_v8 例程(examples/lvgl/lvgl_v8),演示 LVGL v8 在 Ai-M6x 上运行:
- 注册日志回调(
lv_log_register_print_cb),初始化 LVGL 核心(lv_init); lv_port_disp_init初始化 LCD 显示驱动;- 运行 benchmark 演示(
lv_demo_benchmark);其他演示以注释形式列出; - 主循环周期调用
lv_task_handler()刷新画面。 - 同族例程(
examples/lvgl/):lvgl_v9(v9 版本)、lvgl_v8_with_osd/lvgl_v9_with_osd(带 OSD 图层版本)。
注意
LVGL 例程依赖 LCD 显示屏与对应驱动。不同开发板屏幕型号、引脚和分辨率不同,需要按板子的 lcd_conf_user.h 配置核对;没有接屏的板子无法看到画面。
操作步骤
本页需要一块带屏幕的开发板。在终端进入 SDK 的 LVGL v8 例程目录(前提:已按快速开始(Linux)或Windows搭建好环境):
cd examples/lvgl/lvgl_v8执行编译命令。Ai-M62(BL616)与 Ai-M61(BL618)同属一个系列,统一填写引脚最少的 bl616 即可:
make CHIP=bl616 BOARD=bl616dk用 USB 线连接开发板,按住 BOOT 键(Ai-M61-32S-Kit 为 IO2)不放、短按 EN/RST 进入下载模式,然后执行烧录(把串口号换成实际值):
make flash CHIP=bl616 COMX=/dev/ttyUSB0打开串口助手(波特率 2000000)。程序打印 LVGL V8 case 和版本号后,屏幕运行 benchmark 性能演示,串口打印 lvgl success。
代码执行流程
例程从启动到画面刷新的完整流程如下(图中的循环箭头表示反复执行):
例程调用的 API 介绍
lv_log_register_print_cb(cb)
注册 LVGL 日志输出回调,把 LVGL 内部日志转到串口。
参数:
cb:日志回调函数(例程为lv_log_print_g_cb)
返回值:无
lv_demo_benchmark()
启动 benchmark 演示,绘制各类图形并统计渲染性能。其他演示(lv_demo_widgets、lv_demo_music、lv_demo_stress 等)取消注释即可切换。
参数:无
返回值:无
完整代码
以下为 lvgl_v8/main.c 完整源码,与官方示例(examples/lvgl/lvgl_v8)一致,默认折叠,点击展开:
📜 点击展开 lvgl_v8/main.c 完整代码
/**
* @file main.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#include "board.h"
#include "bflb_gpio.h"
#include "bflb_l1c.h"
#include "bflb_mtimer.h"
#include "lcd.h"
#if defined(CONFIG_FREERTOS)
#include <FreeRTOS.h>
#include "task.h"
#endif
#include "lvgl.h"
#include "lv_port_disp.h"
#ifdef CONFIG_LVGL8_PORT_INDEV
#include "lv_port_indev.h"
#endif
#include "demos/lv_demos.h"
#define DBG_TAG "MAIN"
#include "log.h"
#if defined(CONFIG_FREERTOS)
static TaskHandle_t lvgl_handle;
#endif
/* lvgl log cb */
void lv_log_print_g_cb(const char *buf)
{
LOG_RI("[LVGL]%s", buf);
}
void lvgl_main(void *param)
{
/* lvgl init */
lv_log_register_print_cb(lv_log_print_g_cb);
lv_init();
lv_port_disp_init();
#ifdef CONFIG_LVGL8_PORT_INDEV
lv_port_indev_init();
#endif
// lv_disp_set_rotation(NULL, LV_DISP_ROT_90);
lv_demo_benchmark();
// lv_demo_keypad_encoder();
// lv_demo_music();
// lv_demo_stress();
// lv_demo_widgets();
lv_task_handler();
LOG_I("lvgl success\r\n");
while (1) {
lv_task_handler();
bflb_mtimer_delay_us(10);
}
}
int main(void)
{
board_init();
LOG_I("LVGL V8 case\r\n");
LOG_I("LVGL VER: %d.%d.%d\r\n", LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH);
#if defined(CONFIG_FREERTOS)
xTaskCreate(lvgl_main, (char *)"test_task", 2048, NULL, configMAX_PRIORITIES - 2, &lvgl_handle);
vTaskStartScheduler();
#else
lvgl_main(NULL);
#endif
}FAQ
v8 和 v9 怎么选
新项目建议直接用 v9(LVGL v9 图形界面);如果项目已有 v8 代码或依赖旧组件,用 v8。两者 SDK 例程均可直接编译运行。
tick 是怎么驱动的
v8 例程由 lv_port_disp_init 内部按 lv_tick_inc 递增 tick;v9 例程显式调用 lv_tick_set_cb。手写工程时记得保证 tick 持续递增,否则动画和刷新会卡住。
屏幕没有画面
确认开发板接了 LCD 屏,且 lcd_conf_user.h 的屏幕型号、分辨率、引脚与板子一致;再确认 lv_port_disp_init 正常执行(可看串口是否有 LVGL 日志)。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions

