目录
- AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告
- AIR32F103(二) Linux环境和LibOpenCM3项目模板
- AIR32F103(三) Linux环境基于标准外设库的项目模板
- AIR32F103(四) 27倍频216MHz,CoreMark跑分测试
- AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码
- AIR32F103(六) ADC,I2S,DMA和ADPCM实现的录音播放功能
- AIR32F103(七) AIR32F103CBT6/CCT6启用96K内存
- AIR32F103(八) 集成Helix MP3解码库播放MP3
- AIR32F103(九) CAN总线的通信和ID过滤机制及实例
- AIR32F103(十) 在无系统环境和FreeRTOS环境集成LVGL
- AIR32F103(十一) 在AIR32F103上移植微雪墨水屏驱动
- AIR32F103(十二) 搭载 AIR32F103CBT6 的Bluepill核心板
LVGL简介
嵌入式常用的图形显示库
- 官网: https://lvgl.io/
- GitHub仓库: https://github.com/lvgl/lvgl
对设备的要求是 "all you need is at least 32kB RAM and 128 kB Flash, a C compiler, a frame buffer, and at least an 1/10 screen sized buffer for rendering". 最低要求是128KB Flash, 但实际上这个大小基本上什么也做不了, 所以直接用256K Flash 的 AIR32F103CCT6 和 AIR32F103RPT6.
集成LVGL到AIR32F103
Principle 大佬写过一篇 Air32F103试玩-移植LVGL+FreeRTOS Keil5 用户可以参考. 基于STM32标准库, 用的屏幕是 GC9306X 320x240LCD.
我没有这个型号的屏幕, 手里能找到现成的串口屏只有一个128x160的ST7735, 就用这个做测试吧.
基本步骤
参考LVGL的文档, 这两片内容差不多的, 第二篇会更细节一点
- https://docs.lvgl.io/master/get-started/quick-overview.html
- https://docs.lvgl.io/master/porting/project.html
需要做的步骤为
- 将 lvgl 库目录放到项目里
- 复制一份 lvgl/lv_conf_template.h , 改名为 lv_conf.h 并修改定制
- 在项目中需要使用lvgl的地方, 包含 lvgl/lvgl.h 头文件
- 建一个定时器, 每隔1到10毫秒调用一次 lv_tick_inc(x) 用于lvgl内部定时. 如果不用这个方法, 就要定义 LV_TICK_CUSTOM 让 LVGL 可以直接读取时间.
- 调用 lv_init() 执行初始化
- 创建一个图像缓冲, 最小为1/10个屏幕尺寸所需要的数据大小.
- 实现一个绘图函数, 用于LVGL调用后往设备的指定区域写入显示内容.
- 如果有输入设备, 还可以再实现一个输入读取函数
- 在主循环 main while(1) 中, 如果是RTOS环境则在一个循环任务中, 每隔几个毫秒调用一次 lv_timer_handler(), 用于LVGL绘制更新图像显示.
最小化实现
1.将LVGL添加到项目中
从 https://github.com/lvgl/lvgl/releases 下载LVGL, 当前版本是v8.3.5, 解压.
在项目 Libraries 下创建lvgl目录, 复制必须的文件到这个目录下
demos/
examples/
src/
LICENCE.txt
lv_conf_template.h
lvgl.h
lvgl.mk
复制后的 Libraries 目录结构为
Libraries
├───AIR32F10xLib
├───CMSIS
├───Debug
├───DeviceSupport
├───EPaper
├───FreeRTOS
├───Helix
├───LDScripts
├───lvgl
│ ├───demos
│ ├───examples
│ └───src
│ ├───core
│ ├───draw
│ ├───extra
│ ├───font
│ ├───hal
│ ├───misc
│ └───widgets
在 Makefile 中添加 LVGL 选项
# Build with lvgl, y:yes, n:no
USE_LVGL ?= n
LVGL的编译列表和头文件路径都已经在 lvgl.mk 里定义好了, 这里只需要把它 include 进来, 再合并到项目的列表中.
ifeq ($(USE_LVGL),y)
LVGL_DIR ?= Libraries
LVGL_DIR_NAME ?= lvgl
include Libraries/lvgl/lvgl.mk
CFILES += $(CSRCS)
INCLUDES += Libraries/lvgl
else
CFLAGS ?=
endif
将 USE_LVGL 设为 y 之后, make 就会带上 LVGL 一起编译. 因为 LVGL 文件很多, 编译时间较长, 可以根据自己电脑的CPU个数设置并发编译, 例如对于8个逻辑核的L480, 可以执行
make -j8
因为编译结果有200多KByte, 写入的速度也很慢, 暂时没有什么好办法.
2. 定制 lv_conf.h
将 lvgl/lv_conf_template.h, 复制到 user 目录下, 改名为 lv_conf.h, 编辑
将#if 0
改为#if 1
/* clang-format off */
#if 1 /*Set it to "1" to enable content*/
因为ST7735支持的是2byte的像素, 色深设为 16
/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
#define LV_COLOR_DEPTH 16
再往下, 都是用0和1代表对应功能项的关和开, 可以保持默认. 因为ST7735屏幕分辨率较小, 所以再修改一下字体, 将 LV_FONT_MONTSERRAT_10
改为1, 将LV_FONT_MONTSERRAT_14
改为0 启用10像素字体
#define LV_FONT_MONTSERRAT_10 0
#define LV_FONT_MONTSERRAT_12 0
#define LV_FONT_MONTSERRAT_14 1
再设置一下LV_FONT_DEFAULT
, 改为&lv_font_montserrat_10
, 替换为刚才启用的 10像素字体
/*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_montserrat_14
3. 创建 lv_tick_inc(x) 定时器
这里使用TIM3, 将定时间隔设为1毫秒, 开启 TIM_IT_Update 中断
void TIM3_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure