网络知识 娱乐 小熊派实现鸿蒙开机界面(LiteOS+LVGL)

小熊派实现鸿蒙开机界面(LiteOS+LVGL)

文章目录

  • 小熊派实现鸿蒙开机界面(LiteOS+LVGL)
    • 一、文章前言
    • 二、编写代码
    • 三、实验现象
    • 四、项目源码

小熊派实现鸿蒙开机界面(LiteOS+LVGL)

一、文章前言

之前使用小熊派实现了鸿蒙动画的开机界面,具体使用的技术栈为 STM32 + LiteOS + LVGL + FATFS +DMA 方式实现,刷新效率非常高,预览视频如下:

启动界面

关于这个的实现过程我会写一系列的教程分享出来,主要分为下面几个部分,本节为第四部分,在前三节的移植之后

  • 小熊派移植华为 LiteOS-M(基于MDK):链接;
  • 小熊派基于 LiteOS 移植 LVGL 显示接口:链接;
  • 小熊派基于 LiteOS 移植 LVGL 文件系统:链接;
  • 小熊派实现鸿蒙开机界面(LiteOS+LVGL):链接;

二、编写代码

实现 LVGL 和 LiteOS 的底层移植之后,下一步就是编写显示代码,显示的原理就是依次读取图片 bin 文件的数据,将数据打印到屏幕上,这里使用的图片大小是 150*60 ,因为小熊派的内存有限,无法准备太大的 RAM 空间,所以我只显示一小部分关键视频信息,这里的视频 bin 文件先使用导出软件将视频导出每一张图片,然后用 lvgl 的转化工具转化为 bin 文件,将 bin 文件按顺序合并成一个 bin 文件,然后放到 SD 卡中,这里的 bin 文件我已经上传到 Github 的项目工程里面

20220118171420

然后我么编写逻辑代码,主要在 Lcd_Task 任务中编写代码:

先在开头定义一个图像文件参数:

lv_img_dsc_t testimg1 = {
	.header.always_zero = 0,
	.header.w = 150,
	.header.h = 60,
	.data_size = 150 * 60 * 2,
	.header.cf = LV_IMG_CF_TRUE_COLOR,
};

然后在任务内进行变量定义和初始化:

	lv_fs_res_t fs_res=LV_FS_RES_NOT_IMP;
	lv_fs_file_t lv_file;
	int offset;
	LCD_Init();
	lv_init();
	lv_port_disp_init();//lvgl 显示接口初始化,放在 lv_init()的后面
	lv_port_fs_init();

然后创建 LVGL 对象:分别是样式结构体、背景对象以及图片对象

	lv_style_t style1;
	lv_style_init(&style1);
	lv_style_set_bg_color(&style1, LV_STATE_DEFAULT,LV_COLOR_BLACK);
	lv_style_set_border_width(&style1,LV_STATE_DEFAULT, 0);
	lv_style_set_radius(&style1,LV_STATE_DEFAULT,0);
	
	lv_obj_t* bkg = lv_obj_create(lv_scr_act(),NULL);
	lv_obj_set_pos(bkg,0,0);
	lv_obj_set_size(bkg,240,240);
	lv_obj_add_style(bkg,LV_OBJ_PART_MAIN,&style1);
	
	lv_obj_t* homonoryimg = lv_img_create(lv_scr_act(), NULL);

后面在函数主循环内申请动态内存,打开读取 SD 卡图片 bin 文件

    uint8_t* framebuffer1 = (uint8_t*)lv_mem_alloc(sizeof(uint8_t)*18000);
    fs_res = lv_fs_open(&lv_file, "S:/os.bin", LV_FS_MODE_RD| LV_FS_MODE_WR);
    if ( fs_res != LV_FS_RES_OK )
        printf( "LVGL FS open error. (%d)rn", fs_res );

定位文件,因为生成的 bin 文件开头有4个字节的非图片数据,跳过它

    offset = 0;
    offset += 4; //从offset=4
    lv_fs_seek(&lv_file, offset);

然后因为这个 bin 文件有 401 张图片 ,所以我循环往后读 401 次,把读取的图片依次显示在 homonoryimg 图片对象上

    //计算bin文件里一共包含多少张图片,然后不断的给tft进行显示
    for(int i = 0 ; i < 401 ; i++)
    {
        fs_res = lv_fs_read(&lv_file, (uint8_t *)framebuffer1, 18000,NULL);
        testimg1.data = (const uint8_t *)framebuffer1;
        lv_img_set_src(homonoryimg, &testimg1);
        lv_obj_align(homonoryimg, NULL, LV_ALIGN_CENTER, 0, 0);

        lv_task_handler();
        offset += 18004;
        fs_res = lv_fs_seek(&lv_file, offset);
        osDelay(20);
    }

执行完一次 for 循环后,回收资源,延时 1s 继续播放动画:

    lv_mem_free(framebuffer1);
	framebuffer1 = NULL;
    lv_fs_close(&lv_file);
    osDelay(1000);

逻辑代码编写完成,编译下载:

三、实验现象

显示如开头的动画

20220118172401

四、项目源码

Github 下载源码:链接