sujingliang 发表于 2024-12-18 19:41

【极海G32A1465测评】5、移植LVGL

本帖最后由 sujingliang 于 2024-12-18 19:50 编辑

记录一下用G32A1465移植LVGL的过程。

G32A1465的SRAM为128KB,地址被分成了2部分:


每部分大约60多kb,从资源上看可以运行下LVGL。注意要勾选IRAM2。

1、复制LVGL必要文件到Middlewares中

从硬盘找到不知道从什么地方下载的LVGL,将下面几个文件和目录拷贝到SDK下的Middlewares中。


2、将原文件和头文件加入工程
按照目录名建立如下工程文件夹,将对应目录及子目录下的*.c文件全部都加进来,
这一步工作量很大。


头文件也加上


3、lv_port_disp_templ.c
位于:Middlewares/lvgl/examples/porting

加入LCD初始化函数:
static void disp_init(void)
{
    /*You code here*/
      LCD_Init();
}配置2个缓存:
void lv_port_disp_init(void)
{
static lv_disp_draw_buf_t draw_buf_dsc_2;
    static lv_color_t buf_2_1;                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2;                        /*An other buffer for 10 rows*/
    lv_disp_draw_buf_init(&draw_buf_dsc_2, buf_2_1, buf_2_2, MY_DISP_HOR_RES * 32);   /*Initialize the display buffer*/
/*Set a display buffer*/
    disp_drv.draw_buf = &draw_buf_dsc_2;disp_flush调用区域填充函数:
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
      uint16_t *p=(uint16_t*)color_p;
      uint16_t c=*p;
    if(disp_flush_enabled) {
                        LCD_Fill1(area->x1,area->y1,area->x2,area->y2,(uint16_t*)color_p);
    }
    lv_disp_flush_ready(disp_drv);
}
区域填充函数
void LCD_Fill1(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint16_t* color)
{         
      uint32_t i,j;                        
      uint16_t width=ex-sx+1;               //得到填充的宽度
      uint16_t height=ey-sy+1;                //高度
      
      int32_t num= (width) * (height) * 2;
      LCD_SetWindows(sx,sy,ex,ey);//设置显示窗口
      LCD_CS_CLR;
      LCD_RS_SET;
      SPI_WriteByte((uint8_t*)color,num);
      }SPI连续写数据函数:void SPI_WriteByte(uint8_t *spiTxBuf,uint16_t len)
{
      LPSPI_MasterTransferBlocking(LPSPI_1, spiTxBuf, NULL, len, SPI_TIMEOUT);
}


4、配置一个定时器
timer config:
LPITMR_USER_CHANNEL_CONFIG_T g_lpitmrChannelConfig =
{
    .timerMode = LPITMR_PERIODIC_COUNTER,
    .periodUnits = LPIT_PERIOD_UNITS_MICROSECONDS,
    .period = 799U,
    .triggerSrc = LPITMR_TRIG_SRC_INTERNAL,
    .triggerSelect = 0U,
    .reloadOnTriggerEn = true,
    .stopOnInterruptEn = true,
    .startOnTriggerEn = true,
    .channelChainEn = false,
初始化定时器,
void LPITMR_Initialize(void)
{
    LPITMR_DeInit(LPITMR_INSTANCE);
    LPITMR_Init(LPITMR_INSTANCE, &g_lpitmrConfig);
    LPITMR_ChannelInit(LPITMR_INSTANCE, LPITMR_CHANNEL1, &g_lpitmrChannelConfig);

    LPITMR_StartTimerChannels(LPITMR_INSTANCE, LPITMR_CHANNEL1);

    INT_SYS_InstallHandler(LPITMR_Ch1_IRQn, LPITMR_Irq, NULL);
    INT_SYS_EnableIRQ(LPITMR_Ch1_IRQn);
}定时器中断处理,调用lv_tick_inc(1);
void LPITMR_Irq(void)
{
    if(LPITMR_ReadInterruptFlagTimerChannels(LPITMR_INSTANCE, LPITMR_CHANNEL1_MASK))
    {
      /* Clear LPITMR channel1 interrupt flagure */
      LPITMR_ClearInterruptFlagTimerChannels(LPITMR_INSTANCE, LPITMR_CHANNEL1_MASK);
lv_tick_inc(1);
    }
}5、main文件
#include "lv_conf.h"
#include "lvgl.h"
#include "lv_port_disp_template.h"
lv_init();
lv_port_disp_init();
LPITMR_Initialize();      //定时器初始化
lv_demo_widgets();   //调用demo
6、lv_conf.h

#define LV_COLOR_16_SWAP 1
为了适应LCD的配置,使能颜色交换

#define LV_MEM_SIZE (40U * 1024U)
LV_MEM_SIZE 配置大一点,widgets DEMO至少需要38KB


#define LV_MEM_ADR 0x1FFF1000
配置lv_mem地址从0x1FFF1000,这是LV管理内存的起始地址。
选这个地址是因为IRAM2起始0x1FFF0000,空出前面一部分给系统,所以选了0x1FFF1000,这样后面大约还有50多KB。
内存分配可以参见sct文件:


#define LV_BUILD_EXAMPLES 1
使能DEMO

#define LV_USE_DEMO_WIDGETS 1
运行WIDGETS demo

7、实验效果




风之呢喃 发表于 2024-12-19 09:51

LVGL需要占用多大的内存空间

lemonhub 发表于 2025-1-19 14:50

能不能提供一些参考代码

闪烁黎明 发表于 2025-1-21 09:14

必须要勾选IRAM2才行吗

sujingliang 发表于 2025-1-21 13:01

闪烁黎明 发表于 2025-1-21 09:14
必须要勾选IRAM2才行吗

主要是开始只用IRAM1,编译的时候不通过。然后就想用IRAM2,顺便就勾上了,不勾不知道行不行,没试过
页: [1]
查看完整版本: 【极海G32A1465测评】5、移植LVGL