0
点赞
收藏
分享

微信扫一扫

RT thread 中 LVGL 动画效果不起作用的原因及解决办法

苦茶如歌 2022-03-11 阅读 219

最近在将LVGL移植到GD32的过程中发现动画效果在RT thread 上运行的不好,非常卡顿,似乎是没有起作用。先看一下错误的使用方法。

注意以下是LVGL 定时器的错误用法

在配置文件中将 LV_TICK_CUSTOM 选项打开,将获取时钟间隔的函数配置为  rt thread 操作系统的 rt_tick_get() 函数

/*Use a custom tick source that tells the elapsed time in milliseconds.
 *It removes the need to manually update the tick with `lv_tick_inc()`)*/
#define LV_TICK_CUSTOM 0
#if LV_TICK_CUSTOM
    #define LV_TICK_CUSTOM_INCLUDE "rtthread.h"        /*Header for the system time function*/
    #define LV_TICK_CUSTOM_SYS_TIME_EXPR (rt_tick_get())    /*Expression evaluating to current system time in ms*/
#endif   /*LV_TICK_CUSTOM*/

然后在rt thread 中创建一个 10ms 定时线程,定时调用 lv_task_handler();

while(1)
	{	
		rt_thread_mdelay(10);
		lv_task_handler();	
	}

到此,LVGL定时部分已经可以工作了,编写了一个动画显示程序,尝试去显示动画效果

1. 首先新建一个LVGL 定时器,定时500个周期调用屏幕运行函数,更新屏幕上显示控件。

lv_timer_t * UI_timer = lv_timer_create((lv_timer_cb_t)Screen_run, 500, NULL);

2. 在 Screen_run() 函数内创建一个动画效果

void Screen_run(void)
{
    static short pre_value = 0;
    /*Create an animation to set the value*/
    lv_anim_t a;
    lv_anim_init(&a);
    lv_anim_set_exec_cb(&a, set_Heading_value); /*设置动画回调函数*/
    lv_anim_set_var(&a, Heading_meter_indic);
    lv_anim_set_values(&a, pre_value, value); /* 设置开始和结束值。 */
    lv_anim_set_time(&a, 2000); /* 动画时长[ms] */
    lv_anim_set_path_cb(&a, &lv_anim_path_overshoot); /* 设置路径(曲线) */
    lv_anim_start(&a); /*动画开始*/
    pre_value = value;
}

其中动画回调函数为set_Heading_value(),这个函数就是动画效果自动去调用的函数,自动去完成插值显示。

static void set_Heading_value(void* indic, int32_t v)
{
    lv_meter_set_scale_range(Heading_meter, scale_min, 0, 3600, 360, (6300-v)%3600);
    lv_meter_set_scale_range(Heading_meter, scale_deg, 0, 270, 270, (630 - (v/10))%360);
}

 3. 经过以上设置,以为动画效果会很平滑,结果运行起来之后和没有动画效果一样。问题出在那里了?

可能的原因分析

LVGL的运行机理就是自己管理了定时函数,实现自己的一套任务切换逻辑,当和其他操作系统联合使用时,就需要注意任务的优先级,传入LVGL 时间间隔的精度。

当LV_TICK_CUSTOM  选项打开后,原本是不需要再手动去调用lv_tick_inc(tick_period)函数(tick_period 为间隔时间,单位ms),lv_task_handler() 中会定时读取时间间隔,但是这样带来一个问题,在低优先级任务中,lv_task_handler的执行间隔不能被保证,会影响LVGL定时器的执行。从而影响了动画效果。

为了精确地知道经过的毫秒数,lv_tick_inc 应该在比 lv_task_handler() 更高优先级的例程中被调用(例如在中断中)。

以下为正确设置

 1. 取消掉 LV_TICK_CUSTOM 选项,设置值为0 ;

 2.在 SysTick_Handler 定时中断中手动调用 lv_tick_inc(1000/RT_TICK_PER_SECOND);

void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();
    rt_tick_increase();
	lv_tick_inc(1000/RT_TICK_PER_SECOND);
    /* leave interrupt */
    rt_interrupt_leave();
}

 3. 其他程序照旧

结果验证

动画效果正常显示

举报

相关推荐

0 条评论