打印
[活动]

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

[复制链接]
94|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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[MY_DISP_HOR_RES * 32];                        /*A buffer for 10 rows*/
    static lv_color_t buf_2_2[MY_DISP_HOR_RES * 32];                        /*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需要占用多大的内存空间

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

71

帖子

0

粉丝