lvgl移植以及使用记录(1)

LVGL 使用记录

一、移植LVGL

使用LVGL的V8.3.10版本,移植对照正点原子或者网上的教程。

1.1 移植部分

  1. 打开LVGL Porting中lv_port_disp的宏,将if 0改为if 1,需要使用按键、旋转编码器、触摸屏则需要再打开lv_port_indev中的宏,配置好接口。(习惯先把屏幕调通,再去调其他组件)
#if 1

/*********************
 *      INCLUDES
 *********************/
#include "lv_port_disp.h"
#include <stdbool.h>
...

  1. 我是用的是单缓冲方式,由于内存不足,只开了10行,也是LVGL的最低要求,实际看自身的屏幕,我用的是320*172方式,刷17次可以刷新一次整屏,感觉还可以。
static lv_disp_draw_buf_t draw_buf_dsc_1;
static lv_color_t buf_1[MY_DISP_HOR_RES * 10];/*A buffer for 10 rows*/
lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, MY_DISP_HOR_RES * 10); 

  1. 配置lvgl刷新函数disp_flush,采用DMA刷屏效果会更好,由于使用了Freertos操作系统,所以利用中断完成回调函数可以避免死等,充分发挥操作系统的优势,但是在这里并没有试过用信号量同步的方式来刷屏,后续可以尝试一下,目前刷屏效果还是很理想的。(注释部分是没有采用DMA刷屏时想到更换8位到16位来增加传输速率的方法,经测试,相比8位提升也很明显,DMA资源不够的时候也可以试试)。
static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    if(disp_flush_enabled) {
//        int32_t x;
//        int32_t y;
//        spi2_set_TB(1);
//        LCD_Address_Set(area->x1, area->y1, area->x2, area->y2);
//        spi2_set_TB(2);
//        for(y = area->y1; y <= area->y2; y++) {
//            for(x = area->x1; x <= area->x2; x++) {
//                /*Put a pixel to the display. For example:*/
//                /*put_px(x, y, *color_p)*/
//                LCD_WR_DATA16(color_p->full);
//                color_p++;
//            }
//        }
        lcd_draw_fast_rgb_color(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);
}

/**
 * @brief       LCD加速绘制函数
 * @param       (sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex - sx + 1) * (ey - sy + 1)
 * @param       color:要填充的颜色
 * @retval      无
 */
void lcd_draw_fast_rgb_color(int16_t x1, int16_t y1,int16_t x2, int16_t y2, uint16_t *color)
{
    uint16_t w = x2-x1+1;
    uint16_t h = y2-y1+1;

    spi2_set_TB(1);
    LCD_Address_Set(x1, y1, x2, y2);
    spi2_set_TB(2);
    uint32_t draw_size = w * h;

    LCD_CS_Clr();
    HAL_SPI_Transmit_DMA(&hspi2,(uint8_t*)color,draw_size);
}

// DMA刷屏
void HAL_SPI_TxCpltCallback( SPI_HandleTypeDef *hspi )
{
    if( hspi->Instance == SPI2 )
    {
        if( hspi->State == HAL_SPI_STATE_READY )
        {
            LCD_CS_Set();
            lv_disp_flush_ready(&disp_drv);
        }
    }
}

  1. freertos创建任务进行调度,运行例程,一定要将 lv_timer_handler()运行在循环中,非os系统可以开定时器运行或者暂时放在主循环,加入延迟可以在空闲时间运行其他任务
#include "FreeRTOS.h"
#include "task.h"
#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_demo_stress.h"

#define LV_DEMO_TASK_PRIO 3 /* 任务优先级 */
#define LV_DEMO_STK_SIZE 1024 /* 任务堆栈大小 */
TaskHandle_t LV_DEMOTask_Handler; /* 任务句柄 */
void lv_demo_task(void *pvParameters); /* 任务函数 */

void lvgl_demo(void)
{
    lv_init();
    lv_port_disp_init(); /* lvgl 显示接口初始化,放在 lv_init()的后面 */
    lv_port_indev_init();
//    /* 创建 LVGL 任务 */
     xTaskCreate((TaskFunction_t )lv_demo_task,"lv_demo_task",LV_DEMO_STK_SIZE,NULL,LV_DEMO_TASK_PRIO,&LV_DEMOTask_Handler);
}

void lv_demo_task(void *pvParameters)
{
    lv_demo_stress();
    while(1)
    {
        lv_timer_handler(); /* LVGL 计时器 */
        vTaskDelay(5);
    }
}

移植后出现错误的原因大概率是draw中gpu部分未选择对。

剩下的慢慢总结,后面会讲解如何使用内部字体和外部字体,有兴趣请点个赞,有问题丢评论区,看到就回!

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值