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

举报
JeckXu666 发表于 2022/01/18 22:12:27 2022/01/18
【摘要】 使用小熊派实现了鸿蒙动画的开机界面,具体使用的技术栈为 STM32 + LiteOS + LVGL + FATFS +DMA 方式实现,刷新效率非常高



小熊派实现鸿蒙开机界面(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,
};

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

	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();

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后创建 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);

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

后面在函数主循环内申请动态内存,打开读取 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)\r\n", fs_res );

  
  • 1
  • 2
  • 3
  • 4

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

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

  
  • 1
  • 2
  • 3

然后因为这个 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);
    }

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

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

  
  • 1
  • 2
  • 3
  • 4

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

三、实验现象

显示如开头的动画

20220118172401

四、项目源码

Github 下载源码:链接

文章来源: blog.csdn.net,作者:JeckXu666,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq_45396672/article/details/122564879

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。