对于LVGL时基函数的探索

lvgl的时基函数是不是就相当于一个计时器每记一代表1ms过去,而这个函数可以自己做一个定时器接口回传数字也可以直接用freertos的时基回传函数作为时钟计数,如果我的时基回传的不是1ms增一的时基

一、核心结论
您的理解完全正确,LVGL的时基函数本质是一个虚拟时间计数器,其核心逻辑如下:  
1. 默认单位假设:LVGL认为每次调用`lv_tick_inc(1)`对应1ms物理时间,但实际时间关联完全由开发者控制。  
2. 时基来源无关性:无论使用硬件定时器、FreeRTOS时基或其他方式,只要保证计数器增量与物理时间成正比即可。  
3. 延时误差根源:若时基增量非1ms(如10ms/次),则LVGL的`lv_task_handler`、动画等所有依赖时间的模块均会按比例拉长或缩短时间感知。

二、关键机制解析
1. 时基实现方案对比
| 方案类型         | 典型场景                     | 适配方法                                                   | 风险点   
| 1ms硬件定时器 | STM32 SysTick中断 | 直接调用`lv_tick_inc(1)`                           | 中断负载过高  
| FreeRTOS时基| (10ms/tick| 需换算`lv_tick_inc(portTICK_PERIOD_MS)`          | 时间分辨率低  
| 混合模式      | 高精度传感器同步         | 自定义`lv_tick_get()`函数,从RTC或高精度时钟获取时间                                                                                                                               | 需处理多线程同步      |

LVGL时基函数可以用lv_tick_inc(1)也可以用lv_tick_get()区别在于前者是自己计算,也就是说跟外界无关,而后者依赖外部提取的时基,比如用rtos的时间片,lv_tick_get()会返回一个数值作为时基

全部流程:首先LV_TICK_CUSTOM=0就是用lv_tick_get(),LV_TICK_CUSTOM=1就是用lv_tick_get()作为时·基,如果选择LV_TICK_CUSTOM=0就需要自己去配置我们只讲LV_TICK_CUSTOM=1

LV_TICK_CUSTOM=1后,

首先引用了rtos的头文件以方便引用rtos的时基函数,LV_TICK_CUSTOM_SYS_TIME_EXPR是用在下面lv_tick_get()作时基源,而xTaskGetTickCount()是会返回rtos的当前时间片计数值,其实现:xtickscount是rtos自己的时间片全局变量,在内部是systick中断的作用在freertos里实现加加

TickType_t xTaskGetTickCount( void )
{
    TickType_t xTicks;

    /* Critical section required if running on a 16 bit processor. */
    portTICK_TYPE_ENTER_CRITICAL();
    {
        xTicks = xTickCount;
    }
    portTICK_TYPE_EXIT_CRITICAL();

    return xTicks;
}

2. 时基错误的影响
- 动画系统:原1秒动画若时基为10ms,实际耗时10秒(比例`1:10`)。  
- 输入事件:触摸采样间隔放大,导致操作响应迟滞。  
- 定时任务:自动刷新、数据保存等周期性任务触发间隔异常。  

3. 验证与调试方法
- 代码验证:通过物理时间与计数器比对:  
  uint32_t t1 = lv_tick_get();
  HAL_Delay(1000);  // 已知准确的1秒延时
  assert((lv_tick_get() - t1) >= 990 && (lv_tick_get() - t1) <= 1010);
- 硬件验证:使用示波器监测GPIO引脚翻转,验证时基中断的实际周期。

三、FreeRTOS时基适配指南
1. 配置要点
- 配置`configTICK_RATE_HZ`:  
  - 若设为`1000`,可直接使用`xTaskGetTickCount()`作为1ms时基。  
  - 若设为`100`(默认10ms/tick),需在调用`lv_tick_inc()`时传入参数`10`。  

2. 代码示例
// FreeRTOS任务中周期调用
void vTaskGUI(void *pvParameters) {
    TickType_t xLastWakeTime = xTaskGetTickCount();
    while(1) {
        lv_task_handler();
        vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(5)); // 5ms周期
        lv_tick_inc(5);  // 手动补偿时基
    }
}

3. 性能权衡
| Tick频率(Hz) | 时基精度 | CPU负载 | 适用场景               |
|---------------|----------|---------|------------------------|
| 1000          | 1ms      | 高      | 高刷新率UI(60fps+)   |
| 100           | 10ms     | 低      | 简单界面(仪表盘等)   |
| 自定义        | 动态调整 | 中      | 混合关键任务系统       |

---

四、深度优化建议
1. 动态时基补偿
// 在时基误差超过阈值时自动修正
void lv_tick_compensate() {
    static uint32_t last_real_time = 0;
    uint32_t real_time = get_hardware_millis(); // 从RTC或高精度时钟获取
    uint32_t lv_time = lv_tick_get();
    
    if(abs(real_time - lv_time) > 50) { // 允许50ms误差
        lv_tick_set(real_time);        // 强制同步
    }
}

2. 多级时基架构
- 高精度层:1ms硬件定时器驱动LVGL核心动画。  
- 低精度层:FreeRTOS时基处理后台任务(如网络通信)。  
- 动态切换:根据系统负载自动调整时基分辨率。

---

五、设计哲学总结
1. 抽象与实现的解耦:LVGL通过虚拟时基实现跨平台,开发者需在物理层保证时间精度。  
2. 误差容忍与补偿:通过软件算法弥补硬件时基缺陷,平衡性能与精度。  
3. 系统级时间观:GUI时基需与系统其他模块(如传感器、通信协议栈)的时间参考系对齐,避免全局时序混乱。

操作建议:在嵌入式项目中优先采用独立硬件定时器生成1ms时基,若资源受限,需在FreeRTOS配置中明确标注时间换算关系,并在关键功能(如动画)中增加时间校准逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广药门徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值