快速入门STM32开发:基于LVGL 8.2.0的GUI应用

手把手带你移植LVGL

  • 前言
  • 一、准备工作(工欲善其事必先利其器)
  • 1.硬件
  • 2.软件
  • 二、LVGL源码移植
  • 1.下载LVGL源码
  • 2.修改LVGL文件夹
  • 2.开始移植
  • 3.加入lvgl源码
  • 三、移植显示驱动
  • 1.使能LVGL
  • 2.代码改错
  • 2.修改lv_conf.h文件
  • 3.修改lv_port_disp.c文件
  • 4.显示测试
  • 四、移植触摸驱动
  • 1.修改lv_port_indev函数
  • 2.下载验证
  • 总结

  • 前言

    如果已经学会了移植LVGL,可以去看一下我的另一篇博客,快速使用gui—guider开发LVGL快速开发LVGL——gui guider

    在笔者学习刚开始学习LVGL的时候遇到了挺多问题和踩过很多的坑。写这篇文章的原因是为了帮助更多的人能快速入门LVGL,希望对你们有所帮助。有不足和错误之处欢迎指正。


    提示:按照我的步骤一步一步来,保证是可以移植成功的,我踩过的坑都会在文章中写出来,避免大家重蹈覆辙
    视频教程:

    快速入门LVGL第一期–准备工作

    一、准备工作(工欲善其事必先利其器)

    1.硬件

    1.一块stm32板子(带屏幕最好是触摸屏,这样体验会好一点),笔者用的是正点原子的战舰开发板(stm32f103zet6)

    2.软件

    1.根据你的板子下载好商家的程序源码,找到跟触摸显示相关的程序例程和定时相关的例程
    触摸屏
    定时器
    2.把定时器中断实验的代码移植到触摸屏实验那里,用于后续给lvgl提供心跳时间 (如果移植后遇到Error: L6218E:在文件中添加stm32f10x_tim.c即可)


    3.将定时器中断设为1ms

    4.将程序下载进开发板,触摸显示正常即可

    5.重点关注下面两个函数即可,反正不管你是什么板子,只要记得我们需要的一点即可,就是可以填充颜色的函数和能获取触摸坐标的函数就行,不管它长啥样

    //读取x,y坐标
    //最小值不能少于100.
    //x,y:读取到的坐标值
    //返回值:0,失败;1,成功。
    u8 TP_Read_XY(u16 *x,u16 *y)
    {
    	u16 xtemp,ytemp;			 	 		  
    	xtemp=TP_Read_XOY(CMD_RDX);
    	ytemp=TP_Read_XOY(CMD_RDY);	  												   
    	//if(xtemp<100||ytemp<100)return 0;//读数失败
    	*x=xtemp;
    	*y=ytemp;
    	return 1;//读数成功
    }
    
    //在指定区域内填充指定颜色块
    //(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)
    //color:要填充的颜色
    void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
    {  
    	u16 height,width;
    	u16 i,j;
    	width=ex-sx+1; 			//得到填充的宽度
    	height=ey-sy+1;			//高度
     	for(i=0;i<height;i++)
    	{
     		LCD_SetCursor(sx,sy+i);   	//设置光标位置 
    		LCD_WriteRAM_Prepare();     //开始写入GRAM
    		for(j=0;j<width;j++)LCD->LCD_RAM=color[i*width+j];//写入数据 
    	}		  
    }  
    

    第一个坑:以我的例程为模版,仔细看看屏幕扫描的方向是否一致,我第一次就是因为填充函数的填充方向不一样导致搞了半天都移植不成功,最好才找出来问题,新手务必仔细看

    二、LVGL源码移植

    1.下载LVGL源码

    LVGL源码地址:

    https://github.com/lvgl/lvgl

    我们以选择v8.2.0为例,选择8.2.0下载

    2.修改LVGL文件夹

    1.我们只需要关注这5个文件即可,把他们复制到一个新的文件夹里面

    2.为了减少内存消耗,打开examples文件将port文件复制出来,打开demos文件将keypad_encoder lv_demos lv_demo.lv_demos.mk 文件复制出来我们只需要移植下面d文件即可

    3.为了规范化,我们将下列文件进行重命名

    将lv_conf_template.h 文件改为 lv_conf.h(配置相关)
    将port文件里

    lv_port_disp_template.c 文件改为 lv_port_disp.c (显示相关)
    lv_port_disp_template.h 文件改为 lv_port_disp.h(显示相关)
    lv_port_fs_template.c 文件改为 lv_port_fs.c(文件系统相关)
    lv_port_fs_template.c 文件改为 lv_port_fs.h(文件系统相关)
    lv_port_indev_template.c 文件改为 lv_port_indev.c(输入设备相关)
    lv_port_indev_template.c 文件改为 lv_port_indev.c(输入设备相关)

    2.开始移植

    1.在之前修改的触摸屏例程中新建一个LVGL文件夹,将修改后的7个文件复制进去

    2.在MDK中包括LVGL的头文件和设置c99模式

    3.创建4个新的文件

    LVGL_SRC (用来存放lvgl源码)
    LVGL_POR(用来配置lvgl接口文件)
    LVGL_DEMO(用来配置lvgl官方例程)
    LVGL_APP(用来存放用户自己的lvgl代码)

    3.加入lvgl源码

    将lvgl中src文件全部都加进LVGL_SRC文件里

    提示:src文件有点多,要一个一个文件点开,将里面的使用.c文件加进来,src中extra文件里面有许多子文件,要多留个心眼,小心移植

    将lvgl中porting 中.c .h文件全都加进LVGL_POR文件中

    将lvgl.h lv_conf.h lv_demos.h也加进LVGL_POR中

    将keypad_encoder的文件加入到LVGL_DEMO

    三、移植显示驱动

    1.使能LVGL

    将 lv_port_disp.c 、 lv_port_disp.h 、 lv_port_indev.c 、 lv_port_indev.h、 lv_conf.h中if 0改成 if 1
    lv_port_fs.c暂时用不到,先不修改

    2.代码改错

    我们编译一下,有很多个error,不过问题,我们一个一个来修改
    (1)将_template去掉,因为我们之前有修改过源文件
    (2)将…/…/去掉
    (3)将lvgl/lvgl.h改成

    `利用ctrl+f使用替换功能可快速进行修改

    如果有_sys_exit函数记得加上void

    2.修改lv_conf.h文件

    添加屏幕的分辨率
    #define MY_DISP_HOR_RES 480
    #define MY_DISP_VER_RES 320

    3.修改lv_port_disp.c文件

    将lv_port_disp_init函数里的2和3方式注释掉

    添加上面修改的分辨率

    修改disp_flush显示函数(记得包括LCD显示的头文件进来)

    4.显示测试

    修改主函数,删除之前的显示函数,只留下mian函数

    打开使能demo的宏,在lv_conf里

    在定时器中断函数中添加lvgl心跳(#include “lvgl.h”)

    //定时器3中断服务程序
    void TIM3_IRQHandler(void)   //TIM3中断
    {
    	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
    		{
    		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
    			lv_tick_inc(1);//lvgl的1ms中断
    		LED1=!LED1;
    		}
    }
    

    在主函数中添加lvgl相关头文件

    #include "lvgl.h"
    #include "lv_port_disp.h"
    #include "lv_port_indev.h"
    #include "lv_demo_keypad_encoder.h"
    

    在主函数中添加初始化函数

    	lv_init();
    	lv_port_disp_init();  // lvgl显示接口初始化,放在lv_init()的后面
    	lv_port_indev_init(); // lvgl输入接口初始化,放在lv_init()的后面
    	lv_demo_keypad_encoder();
    

    在while(1)调用lvgl事务处理函数

     lv_task_handler(); // lvgl的事务处理
    

    修改后的主函数

    将堆栈改大一点

    下载程序,显示正常(记得将屏幕改成横屏显示)

    四、移植触摸驱动

    1.修改lv_port_indev函数

    将lv_port_indev_init函数里的其他输入设备注释掉,留下触摸

    void lv_port_indev_init(void)
    {
        static lv_indev_drv_t indev_drv;
    
        /*------------------
         * Touchpad
         * -----------------*/
    
        /*Initialize your touchpad if you have*/
        touchpad_init();
    
        /*Register a touchpad input device*/
        lv_indev_drv_init(&indev_drv);
        indev_drv.type = LV_INDEV_TYPE_POINTER;
        indev_drv.read_cb = touchpad_read;
        indev_touchpad = lv_indev_drv_register(&indev_drv);
    
    
    }
    

    再修改触摸状态返回和坐标返回

    /*Return true is the touchpad is pressed*/
    static bool touchpad_is_pressed(void)
    {
        /*Your code comes here*/
       	if(PEN==0)//有按键按下
    	  {
            return true;				// 有触摸操作 返回true
        }
        return false;					// 没有触摸操作 返回false
    }
    
    /*Get the x and y coordinates if the touchpad is pressed*/
    /*Get the x and y coordinates if the touchpad is pressed*/
    static void touchpad_get_xy(lv_coord_t * x, lv_coord_t * y)
    {
    	
        /*Your code comes here*/
    
        (*x) = tp_dev.x[0];		// 赋值x坐标
        (*y) = tp_dev.y[0];		// 赋值y坐标
    }
    

    在主函数添加触摸按键扫描

    tp_dev.scan(0);
    

    2.下载验证

    到此移植结束

    总结

  • 遇到图形显示乱码的,建议去看看你们的颜色填充函数
  • 遇到图形显示不全的,建议去修改堆栈大小
  • 开发板建议选择性能好一点的,建议是f4以上的会比较好
  • 物联沃分享整理
    物联沃-IOTWORD物联网 » 快速入门STM32开发:基于LVGL 8.2.0的GUI应用

    发表评论