你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

开源GUI LittlevGL 移植  

[复制链接]
creep 发布时间:2017-9-7 22:39
本帖最后由 creep 于 2018-1-13 19:14 编辑

    推荐阅读最新的Littlevgl移植(更新时间:2018-1-13):
  
    开源GUI  LittlevGL  V5.0版本移植      


LittlevGL 是一个开源免费的GUI,支持触摸屏操作,移植简单方便,开发者一直在不断完善更新。LittlevGL 自带了丰富的控件:窗口、按键、标签、list、图表等,还可以自定义控件;支持很多特效:透明、阴影、自动显示隐藏滚动条、界面切换动画、图标打开关闭动画、平滑的拖拽控件、分层显示、反锯齿等等。


下面是我在STM32F769-DISCO上移植的演示模式的效果图片.




TIM图片20170907220239.jpg TIM图片20170907220247.jpg

主要控件可以通过下面的图片有个基本的了解:


2017-09-06_115730.png
1、移植

LittlevGL 的移植非常简单,用户只需要提供systick、触摸屏、LCD显示接口即可。源码里面有3个文件用于分别添加这3个接口,具体如下:

0895ef3e-bcca-43d2-9e1d-7a9a21b4723e.png

也就是下面几个函数:


  • hal/disp disp_fill(x1, y1, x2, y2, color) to fill area with a color
  • hal/disp disp_map(x1, y1, x2, y2, &color_array) copy a color map to an area
  • hal/disp disp_color_cpy(dest, src, length, opa) copy pixel, optional for GPU
  • hal/indev indev_get(id, &x, &y) get the x and y coordinates from an input device (e.g. touch pad)
  • hal/systick systick_get() get a system tick with 1 ms resolution
  • hal/systick systick_elapse(prev_time) get the elapsed milliseconds sience prev_time

a)systick的移植直接使用的是HAL库里面提供的

  1. /**
  2. * Get the elapsed milliseconds since start up
  3. * @return the elapsed milliseconds
  4. */
  5. uint32_t systick_get(void)
  6. {
  7.         return HAL_GetTick();
  8. }
  9. /**
  10. * Get the elapsed milliseconds science a previous time stamp
  11. * @param prev_tick a previous time stamp from 'systick_get'
  12. * @return the elapsed milliseconds since 'prev_tick'
  13. */
  14. uint32_t systick_elaps(uint32_t prev_tick)
  15. {
  16.         volatile uint32_t act_time = systick_get();

  17.         /*If there is no overflow in sys_time
  18.          simple subtract*/
  19.         if(act_time >= prev_tick) {
  20.                 prev_tick = act_time - prev_tick;
  21.         } else {
  22.                 prev_tick = UINT32_MAX - prev_tick + 1;
  23.                 prev_tick += act_time;
  24.         }
  25.         return prev_tick;
  26. }
复制代码
b)提供触摸屏的函数,用于初始化触摸屏和返回触摸屏扫描结果
  1. /**
  2. * Initialize your input devices here
  3. */
  4. void indev_init(void)
  5. {
  6.   BSP_TS_Init(DISP_HOR_RES, DISP_VER_RES);
  7. }

  8. /**
  9. * Read an input device
  10. * @param indev_id id of the input device to read
  11. * @param x put the x coordinate here
  12. * @param y put the y coordinate here
  13. * @return true: the device is pressed, false: released
  14. */
  15. bool indev_get(uint8_t indev_id, int16_t * x, int16_t * y)
  16. {
  17.         if(indev_id != 0) {
  18.                 *x = 0;
  19.                 *y = 0;
  20.                 return false;
  21.         }
  22.         static int16_t last_x = 0;
  23.         static int16_t last_y = 0;
  24.         bool press;
  25.         BSP_TS_GetState(&TS_State);
  26.         if(TS_State.touchDetected != 0) {
  27.                 *x = TS_State.touchX[0];
  28.                 *y = TS_State.touchY[0];
  29.                 press = true;
  30.         } else {
  31.                 *x = last_x;
  32.                 *y = last_y;
  33.                 press = false;
  34.         }

  35.         return press;
  36. }
复制代码
c)LCD的移植分为几个函数,

1)一个是用单一色填充矩形区域,这个实际调用的次数较小


  1. /**
  2. * Fill a rectangular area with a color
  3. * @param x1 left coordinate of the rectangle
  4. * @param x2 right coordinate of the rectangle
  5. * @param y1 top coordinate of the rectangle
  6. * @param y2 bottom coordinate of the rectangle
  7. * @param color fill color
  8. */
  9. void disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, color_t color)
  10. {
  11.     /*Return if the area is out the screen*/
  12.     if(x2 < 0) return;

  13.     if(y2 < 0) return;

  14.     if(x1 > DISP_HOR_RES - 1) return;

  15.     if(y1 > DISP_VER_RES - 1) return;

  16.     /*Truncate the area to the screen*/
  17.     int32_t act_x1 = x1 < 0 ? 0 : x1;
  18.     int32_t act_y1 = y1 < 0 ? 0 : y1;
  19.     int32_t act_x2 = x2 > DISP_HOR_RES - 1 ? DISP_HOR_RES - 1 : x2;
  20.     int32_t act_y2 = y2 > DISP_VER_RES - 1 ? DISP_VER_RES - 1 : y2;

  21.     LCD_FillRectPart(act_x1, act_y1, act_x2 - act_x1 + 1, act_y2 - act_y1 + 1, ((color.full)));
  22. }
复制代码
2)这个是用一个颜色map填充一个矩形区域,这个主要用显示时局部刷新使用,是LCD显示调用的底层接口,使用非常频繁,如果需要优先显示速度,可以从这个函数入手,使用块内存复制或者DMA2D来实现。
  1. /**
  2. * Put a color map to a rectangular area
  3. * @param x1 left coordinate of the rectangle
  4. * @param x2 right coordinate of the rectangle
  5. * @param y1 top coordinate of the rectangle
  6. * @param y2 bottom coordinate of the rectangle
  7. * @param color_p pointer to an array of colors
  8. */
  9. void disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const color_t * color_p)
  10. {
  11.     /*Return if the area is out the screen*/
  12.     if(x2 < 0) return;

  13.     if(y2 < 0) return;

  14.     if(x1 > DISP_HOR_RES - 1) return;

  15.     if(y1 > DISP_VER_RES - 1) return;

  16.     /*Truncate the area to the screen*/
  17.     int32_t act_x1 = x1 < 0 ? 0 : x1;
  18.     int32_t act_y1 = y1 < 0 ? 0 : y1;
  19.     int32_t act_x2 = x2 > DISP_HOR_RES - 1 ? DISP_HOR_RES - 1 : x2;
  20.     int32_t act_y2 = y2 > DISP_VER_RES - 1 ? DISP_VER_RES - 1 : y2;


  21.     uint32_t y;

  22.     for(y = act_y1; y <= act_y2; y++)
  23.     {
  24.         memcpy(&my_fb[y * DISP_HOR_RES + act_x1],
  25.                color_p,
  26.                (act_x2 - act_x1 + 1) * sizeof(my_fb[0]));
  27.         color_p += x2 - x1 + 1;    /*Skip the parts out of the screen*/
  28.     }

  29. }
复制代码
3)硬件加速可选项打开后可以使用下面的函数复制加速填充复制内存
  1. /**
  2. * Copy pixels to destination memory using opacity
  3. * @param dest a memory address. Copy 'src' here.
  4. * @param src pointer to pixel map. Copy it to 'dest'.
  5. * @param length number of pixels in 'src'
  6. * @param opa opacity (0, OPA_TRANSP: transparent ... 255, OPA_COVER, fully cover)
  7. */
  8. void disp_color_cpy(color_t * dest, const color_t * src, uint32_t length, opa_t opa)
  9. {
  10.     /*Wait for the previous operation*/
  11.     HAL_DMA2D_PollForTransfer(&Dma2dHandle, 100);

  12.     Dma2dHandle.LayerCfg[1].InputAlpha = opa;
  13.     HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1);
  14.     HAL_DMA2D_BlendingStart(&Dma2dHandle, (uint32_t) src, (uint32_t) dest, (uint32_t)dest, length, 1);
  15. }
复制代码
移植了上面接口之后基本问题就不大了,littlevgl 目前的代码结构有点乱,分为core、hal、misc 几个部分,我是分别建立一个文件夹然后把相应的文件全部添加到里面了,官网也没有详细的移植说明文档。所有的源码如下:
830d99b5-4b7a-45d6-bdbc-e56085de3ef1.png
添加到工程中后如下整体如下:



3446ef89-270c-4dd3-8658-84f3ba39c9c6.png

将所有的文件添加到工程中后用keil编译可能会有一些错误和警告出现,但都很好解决。


2、运行效果

LittlevGL内置一个类似桌面系统的演示例子,通过打开相应的宏定义即可



6b77cfc1-d927-422c-9a91-f5f6b01ed4d7.png

LittlevGL有个桌面上模拟的工程,下面是论坛网友 @QianFan  在linux下运行官方例子的运行效果:


X$SK81@USA577AHK@1B@E_C.gif

除此之外官网还有一个在STM32F429-DISOC上移植的例子,在youtube上可以观看,因为转换为了gif可能看起来不是很流畅,实际演示效果很不错。


test1.gif

下面是我在STM32F769-DISOC上面的移植,和linux下模拟运行的差不多。因为769-disco的分辨率很高,移植后我没有使用优化,所以可以看到画面切换有些闪烁。
IMG_0253.GIF

3、关于LittlevGL

    LittlevGL里面有个简单的时间片调度系统,刷新显示和触摸处理等任务会周期的被调用处理。LCD刷新采用了局部缓存刷新,这样能避免闪烁出现。LittlevGL目前只有一个开发者在业余时间维护更新,但是开发者热情很高,可以在github上看到更新很频繁,我测试的使用的V4.2版本,开发者正在开发4.3版本并加入了不少新的功能,有建议可以在github和作者讨论互动。
目前代码结构看上去有点乱,有人在也提到了这个问题,计划好像是在5.0版本引入新的代码组织结构,感兴趣的可以去github提意见,开发者很乐意沟通讨论。官网也有不少控件的使用介绍和例子参考。



9360da2f-c19f-499f-950b-613fb29b2857.png


官网和github地址如下:

LittlevGL官网:http://www.gl.littlev.hu/
LittlevGLgithub :http://github.com/littlevgl   和  http://github.com/littlevgl/lvgl

下面2个视频是在PC Simulator (Linux)和F4-DICO上的移植演示可能需要科学的方式才能打开。
How to Run Littlev Graphics Library in PC Simulator (Linux):http://youtu.be/ZzLdct2ymvg
Embedded GUI on STM32 Discovery with Littlev Free Graphics Library:http://youtu.be/DcJdK137WKM

  和众多开源的RTOS不一样,目前GUI开源的不是很多,虽然很多商用的GUI也很炫酷,但是我们没法知道具体效果的实现细节,也没法学习到这种能力,LittlevGL目前实现的一些特性和控件我认为是开源的GUI里面水平非常高的了。但是目前LittlevGL资料不是很多,只能通过阅读源码去学习和研究。


测试代码:

LittlevGL-STM32F769-DISCO.rar (4.72 MB, 下载次数: 862)

评分

参与人数 2 ST金币 +21 收起 理由
mcbot + 1 little VGL群,526465246 大家一起来学习.
zero99 + 20 大佬玩的好溜

查看全部评分

收藏 12 评论37 发布时间:2017-9-7 22:39

举报

37个回答
creep 最优答案 回答时间:2018-12-2 17:03:42
ioremap 发表于 2018-11-30 17:25
我遇到个大问题,求回复,空间没颜色的

看到一个别人分享的开源中文教程。
开源GUI-littevGL应用教程 V0.1.pdf (3.14 MB, 下载次数: 456)
Paderboy 回答时间:2017-9-7 23:33:35
跟着大佬学习。。。
淡定的H羊 回答时间:2017-9-8 07:34:07
wow。感觉真不错
谢谢楼主分享
@乔木 回答时间:2017-9-8 08:02:24
厉害厉害
QianFan 回答时间:2017-9-8 08:48:53
现在的代码有点乱,图形界面依赖其他的misc,HAL等库。在github中提意见,将gui部分确实需要的部分集成到gui中,其余没用的部分剥离出去。
anobodykey 回答时间:2017-9-8 08:53:59
这个不错,赞一个
MrJiu 回答时间:2017-9-8 09:22:45
已经关注了一波。。。可以看看!!!!
Xinfeng 回答时间:2017-9-8 09:23:21
学习新知识,快乐
ljt8015 回答时间:2017-9-8 13:47:08
LittlevGL有个桌面上模拟的工程,下面是论坛网友 @QianFan  在linux下运行官方例子的运行效果:


如何模拟?  如何在linux中运行?

ljt8015 回答时间:2017-9-8 14:30:15
LittlevGL 相比 ucgui 的优势?

1234下一页

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版