LVGL V8在STM32F429上的移植

LVGL是个很好用的东西,现在网上出的教程也越来越多,很多是针对V7及以下的版本的,但是V8针对V7的升级还是很大的,很多控件的使用方法也不一样了,所以需要有个合适的移植工程来使用。

这两天一直在想办法移植,也出了很多问题,但是最终还是成功了,特将过程记录下,供大家参考。
首先,针对的是正点原子的阿波罗开发板。核心是STM32F429IGT6,显示屏是分辨率480*272的RGB电容触摸屏。

先看下效果图
在这里插入图片描述
然后说下大概的移植过程及过程中问题的解决吧。
一开始我是直接下载的官方的lvgl源码,配合正点原子的触摸屏例程移植的,但是这个过程报错太多太多,解决一个会出来无数个,我估计这也是目前为止V8的移植教程不多的原因。

然后在官网找到了针对F429的移植例程:贴上地址 https://github.com/lvgl
在这里插入图片描述
就是上图的lv_port_stm32f429_disco。使用git拉取内容,注意一定要把lvgl文件夹下的子模块对应的拉取出来,使用命令:git clone --recurse-submodules https://github.com/lvgl/lv_port_stm32f429_disco.git
该方法前提是你科学上网没问题,如果网速不行,可以直接下载我提供的包。

文档中的内容如下图所示
在这里插入图片描述
我们需要使用到的就是红框中的4个。为什么不直接使用这个工程呢?因为这个工程是基于CUBEIDE编辑的,我还是更熟悉Keil,所以必须要移植过去。

接下来准备正点原子官方的触摸例程,这个主要图省事,而且屏幕和触摸初始化都做好了,避免了很多麻烦。在工程目录下新建一个文件夹“lvgl” 用来存上述4个文件。然后将上述4个文件拷贝到lvgl文件夹内。路径要放正确,因为内部的文件是要靠这个路径找头文件的。放在哪儿,见下图
在这里插入图片描述

在这里插入图片描述
好了,最让人纠结的基本上结束了,因为你已经拿到了可以移植的文件了。这个是困扰我很久的,因为很多源文件拿过来根本没法移植,也是因为我太菜了吧。

然后打开工程,在目录下新建3个目录,如下
在这里插入图片描述
简单说明一下:lvgl/src这个是存放.c源文件的;lvgl/ports是存放显示和触摸接口的;lvgl/app是用来存放官方demo例程和你将来的显示代码的。

lvgl/src存放的文件路径在下图的路径
在这里插入图片描述
打开这个文件夹,里面有多少c文件就都添加进去,包括子文件夹里面的内容也需要添加。

lvgl/ports存放的文件路径如下图
在这里插入图片描述
c文件添加好了记得添加库路径!然后编译一次。会报一些错误
在这里插入图片描述
上图是截自lv_port_disp_template.c。红框中的定义会报找不到,所以需要到lv_conf.h文件中定义这两个量,用宏定义就可以

#define MY_DISP_HOR_RES 480
#define MY_DISP_VER_RES 272

就是确定你的屏幕的分辨率。这个改完之后再编译还会报错,Library reports error: __use_no_semihosting was requested 如果大家遇到这个错误可以参考这个文章:https://blog.csdn.net/baidu_37973494/article/details/81168704
我的验证是方法三可用;使用方法一会解决这个报错,但会引入新的报错。
如果你还有关于GPU方面的报错,那就先去lv_conf.h中把下面的宏定义改成0,我们不使用GPU

/*-------------
 * GPU
 *-----------*/

/*Use STM32's DMA2D (aka Chrom Art) GPU*/
#define LV_USE_GPU_STM32_DMA2D  0
#if LV_USE_GPU_STM32_DMA2D

大的问题好像就是上面这些,可能还有的零散的小问题,有遗漏的可以自己查查看看。
然后就是针对LVGL的一些代码方面的修改了。

int main(void)
{
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    uart_init(115200);              //初始化USART
	TIM3_Init(999,89);
    LED_Init();                     //初始化LED 
    KEY_Init();                     //初始化按键
    SDRAM_Init();                   //初始化SDRAM
   // LCD_Init();                     //初始化LCD
	//tp_dev.init();				    //触摸屏初始化 
	lv_init();
	
	lv_port_disp_init();
	lv_port_indev_init();
  	
	lv_demo_widgets();
		while (1)
	{
		tp_dev.scan(0);
		lv_task_handler();
	}
}

main函数其实很简单,stm32的硬件初始化了就开始初始化LVGL。代码中注释掉的两行初始化LCD和触摸屏初始化,我把它们移动到了下面的lv_port_disp_init和lv_port_indev_init中初始化了,因为我发现先初始化屏幕会显示不出来。

lv_port_disp_init如下

void lv_port_disp_init(void)
{
    /*-------------------------
     * Initialize your display
     * -----------------------*/
    disp_init();

    /*-----------------------------
     * Create a buffer for drawing
     *----------------------------*/

    /* Example for 1) */
    static lv_disp_draw_buf_t draw_buf_dsc_1;
    static lv_color_t buf_1[MY_DISP_HOR_RES * 10];                          /*A buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10);   /*Initialize the display buffer*/

    /*-----------------------------------
     * Register the display in LVGL
     *----------------------------------*/
    static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/
    lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/

    /*Set up the functions to access to your display*/

    /*Set the resolution of the display*/
    disp_drv.hor_res = MY_DISP_HOR_RES;
    disp_drv.ver_res = MY_DISP_VER_RES;

    /*Used to copy the buffer's content to the display*/
    disp_drv.flush_cb = disp_flush;

    /*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_1;

    /*Finally register the driver*/
    lv_disp_drv_register(&disp_drv);
}
/*Initialize your display and the required peripherals.*/
static void disp_init(void)
{
    /*You code here*/
	    LCD_Init();                     //初始化LCD
	if(lcdltdc.pwidth!=0)		
		LCD_Display_Dir(1);//如果是RGB屏的话,则强制设置为横屏显示 这一句还是很重要的,一开始没加,屏幕也没显示
}

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);
}

/*Initialize your touchpad*/
static void touchpad_init(void)
{
    /*Your code comes here*/
		tp_dev.init();				    //触摸屏初始化 
}

/*Will be called by the library to read the touchpad*/
static void 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;

    /*Save the pressed coordinates and the state*/
	if(tp_dev.sta&TP_PRES_DOWN)//触摸按下了
		{
			last_x = tp_dev.x[0];
			last_y = tp_dev.y[0];
			data->point.x = last_x;
			data->point.y = last_y;
			data->state = LV_INDEV_STATE_PR;
		}else{
			data->point.x = last_x;
			data->point.y = last_y;
			data->state = LV_INDEV_STATE_REL;
		}
}

然后就是添加官方demo进来了
在这里插入图片描述

注意这4个文件都要加进来,不然会报错,找不到文件。
这次编译应该就不会有问题了。下载验证就可以了。
以上就是我在移植LVGL8的过程中的总结,相关的工程请大家移步到QQ群:795010850。欢迎大家指正。

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值