原文:https://www.jianshu.com/p/8306f948b854
LVGL展示
此lvgl开发板开源链接:
准备工作
- 显示屏驱动,需要用到“画点”或者“画区域”函数
- 触摸驱动,如果需要用到触摸功能,还需要准备触摸函数,该函数将会返回触摸坐标给lvgl
修改lvgl
下载下来的lvgl是不能直接使用的,需要根据实际修改配置文件
第一步:下载LVGL
在github选择版本下载,链接第二步:解压文件
解压到Arduino的libraries,并将lvgl-8.3.5重命名为lvgl第三步:配置文件名
1,将 lv_conf_template.h 更改为 lv_conf.h2,将 lv_conf.h 移动到Arduino的libraries的根目录下
第四步:打开宏
打开“lv_conf.h”文件,将此处的 #if 0 变成 if 1即可
// 上略
/* clang-format off */
#if 0 /*Set it to "1" to enable content*/
#ifndef LV_CONF_H
#define LV_CONF_H
#include <stdint.h>
// 下略
第五步:配置心跳时钟
在 lv_conf.h 中,找到 #define LV_TICK_CUSTOM ,如下图第88行所示。将其置1即可,这样lvgl将时钟arduino的时钟配置lvgl结束
配置工程
lvgl本身不提供屏幕驱动,只是一个gui库,说白了需要将屏幕驱动提供的画点或者画区域函数和触摸(如果有)函数与lvgl绑定,不然lvgl怎么显示东西
显示驱动
LCD的驱动用到的函数如下
void LCD_Init(void);
void LCD_Draw_Pixel(uint16_t x, uint16_t y, uint16_t *bitmap, uint16_t w, uint16_t h);
编写回调函数,注意这里的函数名不能变,因为这是lvgl的回调函数
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
LCD_Draw_Pixel(area->x1, area->y1, (uint16_t *)&color_p->full, w, h); // 替换你的
lv_disp_flush_ready(disp);
}
触摸驱动
触摸的驱动用到的函数和变量如下
extern int touch_last_x;
extern int touch_last_y;
bool touch_touched();
编写回调函数,注意这里的函数名不能变,因为这是lvgl的回调函数,程序大概意思是lvgl会定时执行 my_touchpad_read ,如果有触摸按下,则会执行if语句,并将新的触摸坐标赋值给lvgl
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
/* 替换成你的 */
if (touch_touched()) {
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = touch_last_x;
data->point.y = touch_last_y;
}
else {
data->state = LV_INDEV_STATE_REL;
}
}
完整程序
- gui.c
#include "gui.h"
#include "LCD.h"
#include "touch.h"
#include "lvgl.h"
lv_disp_draw_buf_t draw_buf;
lv_color_t *disp_draw_buf;
lv_disp_drv_t disp_drv;
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data);
void Gui_Init()
{
Touch_Init(); // 触摸初始化
LCD_Init(); // 屏幕驱动初始化
lv_init(); // LVGL初始化
disp_draw_buf = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * 10, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, screenWidth * 10);
/* Initialize the display */
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush; // 触摸回调函数
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
/* Initialize the (dummy) input device driver */
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read; // 触摸回调函数
lv_indev_drv_register(&indev_drv);
}
/* Display flushing */
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
LCD_Draw_Pixel(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
lv_disp_flush_ready(disp);
}
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
if (touch_touched()) {
data->state = LV_INDEV_STATE_PR;
/*Set the coordinates*/
data->point.x = touch_last_x;
data->point.y = touch_last_y;
}
else {
data->state = LV_INDEV_STATE_REL;
}
}
- gui.h
#ifndef GUI_H
#define GUI_H
void Gui_Init(void);
#endif
- Arduino主程序
#include <Arduino.h>
#include "gui.h"
#include "lvgl.h"
void setup() {
Gui_Init();
}
void loop()
{
lv_timer_handler(); /* let the GUI do its work */
delay(10);
}
移植结束
作者:南方的南边
链接:https://www.jianshu.com/p/8306f948b854
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 标签:disp,lvgl,Arduino,area,indev,ESP32S3,drv,lv,LVGL From: https://www.cnblogs.com/bruce1992/p/17794512.html