STM32CUBEIDE下littleVGL的移植+分配外部SRAM

下载官方源码

https://github.com/lvgl/lvgl

  • 复制lvgl到工程界面
  • 复制lvgl/lv_conf_temp1.h,并改为lv_conf.h,放到lvgl同等级的文件夹下,将#if 0 改成 1,使能这个文件,并且设置 分辨率LV_HOR_RES_MAXLV_VER_RES_MAX,还有颜色深度, LV_COLOR_DEPTH,其他暂时放着不管
#define LV_HOR_RES_MAX          (480)
#define LV_VER_RES_MAX          (800)
#define LV_COLOR_DEPTH     16
  • 引用头文件lvgl/lvgl.h
  • 选一个定时器作为lvgl的时钟心跳,一般是1ms,然后添加lv_tick_inc(x)到中断服务函数中,x可以是任意值
    这里我选用TIM7
void TIM7_IRQHandler(void)
{
    if(TIM7->SR&TIM_FLAG_UPDATE)
    {
        lv_tick_inc(1);//lvgl 的 1ms 心跳
        TIM7->SR = (uint16_t)~TIM_FLAG_UPDATE;
    }
}
  • 实现底层驱动
    1、将\lvgl\examples\porting下除了lv_port_fs_template以外的四个文件,添加到文件夹lv_driver中并添加到工程中,同时去掉template后缀
    2、在lv_port_disp.c中的disp_flush函数下添加用户自己的颜色填充函数,并适当屏蔽文件中一些用不到的代码和函数,记得包含对应的显示驱动头文件到此目录下
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
/
    //use user define funcitons to fill color
    LCD_Color_Fill(area->x1,area->y1,area->x2,area->y2,(uint16_t *)color_p);
/
    /* IMPORTANT!!!
     * Inform the graphics library that you are ready with the flushing*/
    lv_disp_flush_ready(disp_drv);
}

3、在lv_port_indev,c中的touchpad_read函数下添加用户自己的触摸识别函数,并适当屏蔽文件中一些用不到的代码和函数,记得包含对应的触摸驱动头文件到此目录下

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

    /*Set the last pressed coordinates*/
    data->point.x = last_x;
    data->point.y = last_y;
#endif
    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;
    }
    /*Return `false` because we are not buffering and no more data to read*/
    return false;
}

  • 删除lvgl文件夹中一些用不到的文件和文件夹,最后剩下两个
    STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第1张图片

移植一些基本的示例

  • 下载源码https://github.com/lvgl/lv_examples
  • 修改lv_ex_conf_templ.hlv_ex_conf.h 并将文件中的#if 0 改为 1 使能文件
  • 删除没用的文件,最后剩下
    STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第2张图片
  • 包含src中的各例程的头文件和assets的头文件到 cubeide中
  • 使能lv_ex_conf.h 中的需要使用到的例程
    这里我使能了widgets
    STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第3张图片

main函数中的配置

//包含必要的头文件
#include "lcd.h"  //lcd驱动
#include "touchConf.h"  //触摸驱动
#include "timer.h" //心跳时钟驱动
#include "lvgl.h"  //lvgl 核心
#include "lv_port_disp.h" //lvgl底层显示
#include "lv_port_indev.h" //lvgl 底层触摸
#include "lv_demo_widgets.h" //lvgl widgets demo 可以自行添加别的,但要注意使能lv_ex_conf.h中的对应模块
 
//main函数中

 TIM7_Init(72-1,1000-1); //使能心跳时钟

 LCD_Init(); //初始化lcd

 tp_dev.init(); //初始化触摸屏

 //lvgl 初始化函数
  lv_init();
  lv_port_disp_init();
  lv_port_indev_init(); //顺序不能换

  lv_demo_widgets(); //widgets例程调用函数

while(1)
{
	tp_dev.scan(0); //触摸扫描
	lv_task_handler(); //lvgl任务处理
}
 

配置外部SRAM

由于cubeide 不能像keil中一样直接使用__attribute__指定地址,这里需要一些特殊的操作

  • cubeide中自行配置FSMC ,我这里外部SRAM的首地址是 0x68000000
  • 修改linker script 也就是 ld文件
    STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第4张图片
    STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第5张图片
    红色框为添加或修改的地方
    这里顺便修改了栈的大小为0x800
    -STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第6张图片
  • 具体原因请参考这个文章https://www.cnblogs.com/RegressionWorldLine/p/11968467.html
  • lv_port_disp.h添加如下代码
#pragma pack(4)
#define COLOR_BUF_SIZE  (400*400) //不宜太大,否则会出现显示错误
static lv_color_t color_buf[COLOR_BUF_SIZE]  __attribute__((section(".sram")));
  • 修改lv_port_disp_init函数
void lv_port_disp_init(void)
{
//..................省略.................
 /* Example for 1) */
    static lv_disp_buf_t disp_buf_1;
    lv_disp_buf_init(&disp_buf_1, color_buf, NULL, COLOR_BUF_SIZE);   /*Initialize the display buffer*/
    
    /*屏蔽其他内存分配方式*/
#if 0
    /* Example for 2) */
    static lv_disp_buf_t disp_buf_2;
    static lv_color_t buf2_1[LV_HOR_RES_MAX * 10];                        /*A buffer for 10 rows*/
    static lv_color_t buf2_2[LV_HOR_RES_MAX * 10];                        /*An other buffer for 10 rows*/
    lv_disp_buf_init(&disp_buf_2, buf2_1, buf2_2, LV_HOR_RES_MAX * 10);   /*Initialize the display buffer*/

    /* Example for 3) */
    static lv_disp_buf_t disp_buf_3;
    static lv_color_t buf3_1[LV_HOR_RES_MAX * LV_VER_RES_MAX];            /*A screen sized buffer*/
    static lv_color_t buf3_2[LV_HOR_RES_MAX * LV_VER_RES_MAX];            /*An other screen sized buffer*/
    lv_disp_buf_init(&disp_buf_3, buf3_1, buf3_2, LV_HOR_RES_MAX * LV_VER_RES_MAX);   /*Initialize the display buffer*/
#endif
//..................省略.................
}

修改 cubeide的编译优化等级(防止内存溢出)

STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第7张图片
STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第8张图片
STM32CUBEIDE下littleVGL的移植+分配外部SRAM_第9张图片

至此全部配置完毕

你可能感兴趣的:(STM32笔记)