国民技术N32G45X移植LVGL8.3+ILI9488
1 准备工作
1.1 硬件方面
使用的是自制的一块控制板,主控选用的是国民技术的N32G452VEL7芯片,屏幕大小为3.5寸,驱动型号为ILI9488。
1.2 软件方面
从GitHub中获取LVGL码源: GitHub - lvgl/lvgl at release/v8.3
按照下边图示(步骤1-5)选择V8.3版本并进行下载
2 移植LVGL
2.1 修改LVGL相关文件名
打开下载好的LVGL-V8.3文件夹,移植LVGL主要就是操作下边这四份文件(/文件夹)
在项目工程文件夹中创建一份新文件夹,并命名为LVGL,然后复制LVGL-V8.3里边的这四份文件,其中porting文件夹是在上图的examples文件夹里。
为了看着专业一点的感觉,我们可以将文件名进行修改,
lv_conf_template.h重命名为lv_conf.h、
porting文件夹里的lv_port_disp_template.c重命名为lv_port_disp.c、
lv_port_disp_template.h重命名为lv_port_disp.h。
port_disp (显示相关)
port_fs (文件系统相关)
port_indev(输入设备相关)
2.2 加载LVGL头文件
将LVGL的头文件加载进来并设置为C99模式
2.3 添加LVGL码源
在项目工程文件栏处创建两份新的文件
LVGL_SRC (用来存放lvgl源码)
LVGL_POR(用来配置lvgl接口文件)
LVGL_POR文件里边加载这三份文件,(仅屏幕显示)
将LVGL/src里边的所有.c文件全都加载进LVGL_SRC文件里,数量有点多,注意别落下。
2.4 修改lv_conf.h文件
将lv_conf.h中if 0改成 if 1
修改内存大小
打开显示CPU使用率和FPS计数
2.5 修改lv_port_disp.c文件
将lv_port_disp.c中if 0改成 if 1
将lv_port_disp_template.h改为lv_port_disp.h
修改屏幕分辨率
选择缓存配置
添加屏幕填充函数
LCD_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t *)color_p);
2.6 修改lv_port_disp.h文件
将lv_port_disp.h中if 0改成 if 1
将lvgl/lvgl.h改为lvgl.h
2.7 lvgl初步编译
经过编译后,出现一些错误:
按住ctrl+F,按照下图操作来进行批量替换
修改完成后编译通过
3 屏幕显示测试
3.1修改堆栈大小
Stack栈改为0x1000(4Kb)
Heap堆改为0x800(2Kb)
3.2 添加lvgl心跳
定时器配置为1ms的中断
在定时器中断函数中添加lv_tick_inc(1);
void TIMX_IRQHandler(void)
{
if (TIM_GetIntStatus(TIMX, TIM_INT_UPDATE) != RESET)
{
TIM_ClrIntPendingBit(TIMX, TIM_INT_UPDATE);
lv_tick_inc(1);
/* Pin PC.06 toggling */
// GPIO_WriteBit(GPIOC, GPIO_PIN_6, (Bit_OperateType)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_PIN_6)));
}
}
3.3 对main.c文件进行操作
添加LVGL相关头文件
加入LVGL测试程序
#include "main.h"
#include "NZ_BitBand.h"
#include "delay.h"
#include "time.h"
#include "lcd.h"
#include "lvgl.h"
#include "lv_port_disp.h"
void lv_example_led_1(void)
{
/*Create a LED and switch it OFF*/
lv_obj_t * led1 = lv_led_create(lv_scr_act());
lv_obj_align(led1, LV_ALIGN_CENTER, -80, 0);
lv_led_off(led1);
/*Copy the previous LED and set a brightness*/
lv_obj_t * led2 = lv_led_create(lv_scr_act());
lv_obj_align(led2, LV_ALIGN_TOP_LEFT, 0, 0);
lv_led_set_brightness(led2, 150);
lv_led_set_color(led2, lv_palette_main(LV_PALETTE_RED));
/*Copy the previous LED and switch it ON*/
lv_obj_t * led3 = lv_led_create(lv_scr_act());
lv_obj_align(led3, LV_ALIGN_CENTER, 80, 0);
lv_led_on(led3);
}
int main(void)
{
TIME_Configuration_Init(5,5999);
LCD_Init();
lv_init(); // lvgl系统初始化
lv_port_disp_init(); // lvgl显示接口初始化,放在lv_init()的后面
lv_example_led_1();
while(1)
{
lv_task_handler(); // lvgl的事务处理
}
}
3.4 程序编译运行
程序编译后进行烧录,发现全屏只显示一个颜色
屏幕显示不正常,经过检查后发现,ILI9488的填充函数不对,正确的函数如下:
//在指定区域内填充指定颜色块
//(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; //高度
if (lcddev.id == 0X9486 || lcddev.id == 0X9488)
{
for (i = sy; i < ey + 1; i++)
{
for (j = sx; j < ex + 1; j++)
LCD_Fast_DrawPoint(j, i, color[(i - sy) * width + (j - sx)]);
}
}
else
{
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]; //写入数据
}
}
}
经过修改后,屏幕最终可以正常显示
4 总结
LVGL移植过程中,难免会有一些困难,但移植次数多了,后边会发现基本都差不多的,主要的问题点无非就那几种,堆栈溢出了报错、屏幕填充函数错误、LVGL内存溢出等方面原因。最后的链接中有提供初始项目工程以及移植好的工程,有需要的伙伴可以拿去参考下。
链接:https://pan.baidu.com/s/1fxSSeKr2Vq0WmGyagiMjmQ
提取码:gfep