STM32移植LVGL踩坑集锦

本文分享了LVGL移植过程中遇到的问题及解决方法,包括分辨率配置、内存调整、屏幕显示异常修正等,并详细介绍了如何配置触摸功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章我主要讲解一下我在移植LVGL时所遇到的一些坑以及解决方法。LVGL的移植过程可以参考我前面的文章,http://t.csdn.cn/QSVOO。

第一个

问题:
在lvgl8.1以前的版本可能会出现MY_DISP_HOR_RES 和 MY_DISP_VER_RES 未定义的报错。
解决方法:
lvgl.conf.h 头文件里定义即可
在这里插入图片描述lvgl8.1以后的版本不需要我们自己添加了,它已经在lv_port.disp.c定义好了我们只需要修改成我们自己的屏幕参数。
在这里插入图片描述

第二个

问题:
报错提示内存不足
在这里插入图片描述解决方法:
1、修改lvgl可用内存的大小,在lv_conf.h中修改LV_MEM_SIZE的值,修改后的样子(原来是128U*1024U)
在这里插入图片描述2、增大STM32的空间,在stm32f407xx.s(我这里用的是STM32F407的板子)文件中修改,修改后的样子:
在这里插入图片描述

第三个

问题:
移植好后编译下载发现屏幕显示是乱的,这是lv_port_disp.c里的disp_flush函数修改错误导致的。
在这里插入图片描述我原来用正点原子的F103的精英板移植用这个方法显示是正常的,我现在换了其他板子和屏幕也用同样的方法结果就显示不正常了。
在这里插入图片描述
这里在disp_flush函数里添加的函数是填充指定颜色函数LCD_Draw_Picture,函数原型如下:

/****************************************************************************
* 名    称: void LCD_Draw_Picture(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
* 功    能:在指定区域内画入图片
* 入口参数:(sx,sy),(ex,ey):填充矩形对角坐标
            color:要填充的图片像素颜色数组
* 返回参数:无
* 说    明:区域大小为:(ex-sx+1)*(ey-sy+1)  
****************************************************************************/
void LCD_Draw_Picture(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_WriteGRAM();        //开始写入GRAM
		for(j=0;j<width;j++)
		   LCD_DATA=color[i*height+j];//写入颜色值
	}	  
}  

错误的显示效果。
在这里插入图片描述

解决方法
我当时在这里卡了好久,后来在百度上看到一位大佬的方法,他不是用的指定颜色填充函数而是用的颜色打点函数。于是我就想我用这个方法是否可行呢?一试,果然可以。修改过后的样子:
在这里插入图片描述颜色打点函数原型如下:

/****************************************************************************
* 名    称: void LCD_Color_DrawPoint(u16 x,u16 y,u16 color)
* 功    能:在设置的坐标处画相应颜色(在该点写入自定义颜色)
* 入口参数:x:x坐标
            y:y坐标
            color 此点的颜色值
* 返回参数:无
* 说    明:color:写入此点的颜色值   GUI调用该函数
****************************************************************************/
void LCD_Color_DrawPoint(u16 x,u16 y,u16 color)
{	       
	 LCD_DrawPoint(x,y);
	 LCD_CMD=write_gramcmd; 
	 LCD_DATA=color;  
}	

编译下载。显示效果正常
在这里插入图片描述

添加触摸功能

lv_port_indev.c文件就是跟触摸有关的。在lv_port_indev.c文件里添加自己的触摸函数的头文件。在lv_port_indev.c文件中找到lv_port_indev_init函数,进行修改。这里只添加触摸功能,所以把其他功能屏蔽掉。
在这里插入图片描述接在在下面找到touchpad_read函数进行修改 ,

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(touchpad_is_pressed()) {
//        touchpad_get_xy(&last_x, &last_y);
//        data->state = LV_INDEV_STATE_PR;
//    }
//    else {
//        data->state = LV_INDEV_STATE_REL;
//    }
	//上面注释的是原本的代码
		if(PEN==0)  //判断有按键按下,PEN在自己触摸函数头文件有定义,不同厂商提供的触摸函数不同,
				//如正点原子的,在这里就可以使用if(tp_dev.sta&TP_PRES_DOWN)
		{
			last_x = Xdown;   //按键按下抬起后的坐标,自己触摸函数头文件里定义的按键键值的存放变量
			last_y = Ydown;
			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;
		}

    /*Set the last pressed coordinates*/
//    data->point.x = last_x;
//    data->point.y = last_y;
}

上述代码中我用PEN是否等于0判断是否触摸屏幕,还使用了Xdown和Ydown,这些在我使用的触摸函数头文件中有定义,如下:
在这里插入图片描述
这里还不能看出PEN的作用,在找到一个触摸扫描函数,
在这里插入图片描述
这里就可以看出当PEN为0即代表有屏幕被触摸。
这里不同的屏幕厂商提供的函数不同,所以判断方式也有不同,如正点原子的:
在这里插入图片描述可以看到正点原子定义了一个结构体,结构体中有存放键值的变量 u16 x[CT_MAX_TOUCH];
u16 y[CT_MAX_TOUCH]。还有用于判断屏幕是否被触摸的变量 u8 sta;此外还有宏定义 #define TP_CATH_PRES 0x40。我们可以查看他的屏幕扫描函数看看他怎么用的。
在这里插入图片描述我们可以看到他这里的屏幕扫描函数有返回值,返回的是 tp_dev.sta&TP_PRES_DOWN,代表当前屏幕状态,0,触屏无触摸;1,触屏有触摸,我们就可以在touchpad_read函数里使用 tp_dev.sta&TP_PRES_DOWN来进行判断。
正点原子的大家根据自己的屏幕实际情况进行修改,修改好了就可以添加测试代码,参考我前面的文章添加测试代码http://t.csdn.cn/qdxaY。

好了,我本次分享就结束了,大家有什么坑欢迎在评论区讨论。

LVGL是一个流行的开源GUI库,用于创建现代、高性能的嵌入式界面。LV_MEM_SIZE是一个宏,它用于设置内存池的大小,这个内存池主要用于LVGL的对象内存管理。分配LVGL所需的内存通常是静态初始化的一部分,尤其是在资源有限的嵌入式项目中。 以下是分配LVGL内存池大小的一般步骤: 1. **计算需求**:首先,你需要估算你的应用将需要多少内存。这取决于LVGL组件的数量、复杂度以及屏幕大小等因素。一般来说,大型布局、多个页面或复杂的动画可能会占用更多的内存。 2. **选择合适的内存池大小**:根据计算结果,选择一个足够大的数值。LVGL推荐至少4KB,但如果你的应用特别复杂,可能需要更大的值。同时要注意,过大的内存可能导致浪费,而过小则可能导致内存不足错误。 3. **配置宏**:在你的项目中找到包含`LV_MEM_SIZE`定义的地方,通常是在`lv_conf.h`文件中。然后修改宏值,例如: ```c #define LV_MEM_SIZE (4096) // 设置为4KB ``` 4. **编译并运行**:编译你的项目,并在运行过程中观察是否有内存溢出或性能问题。如果一切正常,说明你已经合理地设置了内存池大小。 5. **动态调整**:如果发现内存使用情况不稳定,你也可以考虑使用更高级的技术,如通过代码动态调整内存池大小。 记得在实际应用中,内存管理是一项微妙的工作,需要根据硬件限制和应用特性来进行优化。
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值