1 下载
下载地址:
https://github.com/lvgl/lv_examples
下载解压后, 把lvgl改名为lvgl_core, lv_example改名为lvgl_example
1 把lvgl目录下得lv_confi-tempplate.h改名为lv_conf.h, 并且修改了if 0 为if 1, 最好复制到最外层文件夹, 对于lv_ex_confi也是如此
必须要改名和修改0为1, 不然编译会报错找不到头文件和宏定义
2 复制example/porting的文件到lvgl_port目录, 并且把所有源文件的template后缀去掉, 并且把头文件的if 0修改为if 1
修改前
修改后
2 配置keil工程
新建这3个文件夹
把lvgl_core/src目录下里面这些源文件全部加入到lvgl/core中
最后添加lvgl_core的头文件目录和lvgl目录 这个包含目录只需要包含第一层目录就可以了
最终lvgl目录效果
3 添加demo
我要运行的demo是widgets, 于是修改lv_ex-confi.h
#define LV_USE_DEMO_WIDGETS 1
#if LV_USE_DEMO_WIDGETS
#define LV_DEMO_WIDGETS_SLIDESHOW 0
添加源文件到example目录
可以编译一下, 看有没有什么其他问题
4 添加port
把port目录下源文件都加入到port文件夹,并且添加头文件包含
配置后
编译发现后几个错误
这些错误是因为我们还没移植工作, 所以下一步我们工作是移植
5 移植
PORT目录下的3个文件,分别对应显示, 文件系统,触摸
1 修改lv_config.h的分辨率和接口
#define LV_HOR_RES_MAX (1024)
#define LV_VER_RES_MAX (600)
/* Color depth:
* - 1: 1 byte per pixel
* - 8: RGB332
* - 16: RGB565
* - 32: ARGB8888
*/
#define LV_COLOR_DEPTH 16
2 lv_port_disp.c移植
主要进行显示的移植工作
1 显示初始化, 我在main.c里面初始化了 这里就不初始化了
static void disp_init(void)
{
/*You code here*/
}
2 lv_port_disp_init函数缓冲区设置
我是用的SDRAM ,地址为0XC0000000, 所以在LTDC里面有一个缓冲区, 在分配给lvgl的缓冲区要跳过这个
#define LTDC_LCD_FRAMEBUF_SIZE (1024*600*2) //ltdc.c中ltdc_lcd_framebuf缓冲区的大小
#define COLOR_BUF_SIZE (LV_HOR_RES_MAX*LV_VER_RES_MAX) //全屏的大小
static lv_color_t color_buf[COLOR_BUF_SIZE] __attribute__((at(LCD_FRAME_BUF_ADDR+LTDC_LCD_FRAMEBUF_SIZE))); //分配到外部SDRAM,需要跳过ltdc.c中分配的帧缓冲区
static lv_color_t color_buf2[COLOR_BUF_SIZE] __attribute__((at(LCD_FRAME_BUF_ADDR+LTDC_LCD_FRAMEBUF_SIZE+COLOR_BUF_SIZE*2)));//lvgl的第二个缓冲区,紧跟在第一个缓冲区的后面
static lv_disp_buf_t draw_buf_dsc_1;
lv_disp_buf_init(&draw_buf_dsc_1, color_buf,color_buf2, 1024*600); /*Initialize the display buffer*/
/*Set the resolution of the display*/
disp_drv.hor_res = LV_HOR_RES_MAX;
disp_drv.ver_res = LV_VER_RES_MAX;
3 修改disp_fulsh函数, 这个函数是用来刷新图像的, 我们只需要在这里实现刷图的接口就可以了
我是用的RGB屏幕, 直接用LTDC加DMA2D刷图就可以了
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
LTDC_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t*)(color_p));
lv_disp_flush_ready(disp_drv);
}
4 触摸移植
修改lv_port_indev.c中的这个函数, 告诉如果获得x,y就可以了
/* Will be called by the library to read the touchpad */
static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
static lv_coord_t last_x = 0;
static lv_coord_t last_y = 0;
uint16_t tx;
uint16_t ty;
/*Save the pressed coordinates and the state*/
if(touch_get(&tx,&ty)) {
last_x = tx;
last_y = ty;
data->state = LV_INDEV_STATE_PR;
} else {
data->state = LV_INDEV_STATE_REL;
}
/*Set the last pressed coordinates*/
data->point.x = last_x;
data->point.y = last_y;
/*Return `false` because we are not buffering and no more data to read*/
return false;
}
5 添加一个1ms的定时器给touchgfx使用
我使用的是TIM6, 具体如何配置定时器这个很简单的,
主函数中开启定时器6
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
lv_tick_inc(1);
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
/* USER CODE END TIM6_DAC_IRQn 1 */
}
5 使用
主函数中调用就可以了
int main()
{
lv_init();
lv_port_disp_init();
lv_port_indev_init();
lv_demo_widgets();
while(1){
touch_scan();
lv_task_handler();
}
return 0;
}
效果:
6代码下载
git: https://github.com/KiritoGoLeon/stm32-HAL-learn
csdn: https://download.csdn.net/download/a2267542848/13674593
7开启GPU加速
lv_conf.h中找到GPU, 修改DMA2D开起, 包含头文件,
#define LV_USE_GPU 0 /*Only enables `gpu_fill_cb` and `gpu_blend_cb` in the disp. drv- */
#define LV_USE_GPU_STM32_DMA2D 1
/*If enabling LV_USE_GPU_STM32_DMA2D, LV_GPU_DMA2D_CMSIS_INCLUDE must be defined to include path of CMSIS header of target processor
e.g. "stm32f769xx.h" or "stm32f429xx.h" */
#define LV_GPU_DMA2D_CMSIS_INCLUDE "stm32f429xx.h"
宏定义STM32F4
这样就开启了GPU加速, 这个加速主要是颜色转换之类的