34. 软件定时器

一、软件定时器

  LVGL 有一个内置的软件定时器,它构建在硬件定时器基础之上,使系统能够提供不受硬件定时器资源限制的定时服务,其实现的功能与硬件定时器也是类似的。因为 lv_timer_handler() 函数并不是准时调用的,所以导致了软件定时器有一定的误差。

  LVGL 官方提供一些与定时器相关的 API 函数。

lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data);   // 创建定时器
lv_timer_t * lv_timer_create_basic(void);                                                   // 创建定时器

void lv_timer_set_period(lv_timer_t * timer, uint32_t period);                              // 设置定时周期
void lv_timer_set_cb(lv_timer_t * timer, lv_timer_cb_t timer_cb);                           // 设置定时器的回调函数
void lv_timer_set_repeat_count(lv_timer_t * timer, int32_t repeat_count);                   // 设置定时器重复计数的次数

#define lv_timer_del                    lv_timer_delete
void lv_timer_delete(lv_timer_t * timer);                                                   // 删除定时器

void lv_timer_ready(lv_timer_t * timer);                                                    // 定时器就绪
void lv_timer_reset(lv_timer_t * timer);                                                    // 重置定时器
void lv_timer_pause(lv_timer_t * timer);                                                    // 暂停定时器
void lv_timer_resume(lv_timer_t * timer);                                                   // 恢复定时器
void lv_timer_enable(bool en);                                                              // 启用或禁用定时器

lv_timer_t * lv_timer_get_next(lv_timer_t * timer);                                         // 获取下一个定时器
uint32_t lv_timer_get_idle(void);                                                           // 获得空闲时间百分比

  我们使用 lv_timer_create() 函数或 lv_timer_create_basic() 函数 创建一个定时器

/**
 * @brief 创建定时器
 * 
 * @param timer_xcb 定时器回调函数
 * @param period 定时周期
 * @param user_data 传入参数
 * @return lv_timer_t* 指向定时器的指针
 */
lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data);
/**
 * @brief 创建定时器
 * 
 * @return lv_timer_t* 指向定时器的指针
 */
lv_timer_t * lv_timer_create_basic(void);

使用该函数创建 LVGL 定时器时,必须调用 lv_timer_set_cb() 函数,自定义定时回调函数,默认定时周期为 DEF_PERIOD。

  在创建完定时器后,我们还可以使用 lv_timer_set_period() 函数 设置定时器的周期

/**
 * @brief 设置定时周期
 * 
 * @param timer 指定定时器的指针
 * @param period 周期值
 */
void lv_timer_set_period(lv_timer_t * timer, uint32_t period);

  在创建完定时器后,我们还可以使用 lv_timer_set_cb() 函数 设置定时器的回调函数

/**
 * @brief 设置定时器的回调函数
 * 
 * @param timer 指定定时器的指针
 * @param timer_cb 定时器回调函数
 */
void lv_timer_set_cb(lv_timer_t * timer, lv_timer_cb_t timer_cb);

  用户可以使用 lv_timer_set_repeat_count() 函数 设置定时器重复计数的次数。当计数次数达到指定值后,计时器将自动删除。当计数次数设置为 -1 时,以无限期地重复计数。

/**
 * @brief 设置定时器重复计数的次数
 * 
 * @param timer 指向定时器的指针
 * @param repeat_count 重复次数,如果为-1,则以无限期地重复计数
 */
void lv_timer_set_repeat_count(lv_timer_t * timer, int32_t repeat_count);

  用户可以手动设置定时器的就绪状态以及重置定时器。

/**
 * @brief 定时器就绪
 * 
 * @param timer 指向定时器的指针
 */
void lv_timer_ready(lv_timer_t * timer);

定时器就绪后,系统将在下一次调用 lv_timer_handler() 时运行这个定时器。

/**
 * @brief 重置定时器
 * 
 * @param timer 指向定时器的指针
 */
void lv_timer_reset(lv_timer_t * timer); 

  用户可通过 lv_timer_get_idle() 函数获得 lv_timer_handler()(定时器任务)的空闲时间百分比,以此测量出 LVGL 的空闲时间。该函数仅测量 lv_timer_handler() 的空闲时间,而不会测量整个系统的空闲时间,因此,当用户使用操作系统并在定时器中调用 lv_timer_handler() 时,可能会产生误差,因为它不会实际测量操作系统在空闲线程中花费的时间。

/**
 * @brief 获得空闲时间百分比
 * 
 * @return uint32_t 空闲时间百分比
 */
uint32_t lv_timer_get_idle(void);

二、实验例程

#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"

lv_obj_t *progressBar;

int main(void)
{   
    HAL_Init();
    System_Clock_Init(8, 336, 2, 7);
    Delay_Init(168);

    SPI_Simulate_Init();
    // SRAM_Init();
    TIM_Base_Init(&g_tim6_handle, TIM6, 83, 999);
    __HAL_TIM_CLEAR_IT(&g_tim6_handle, TIM_IT_UPDATE);                          // 清除更新中断标志位
    HAL_TIM_Base_Start_IT(&g_tim6_handle);                                      // 使能更新中断,并启动计数器

    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();

    // 测试代码
    progressBar = lv_bar_create(lv_scr_act());                                  // 创建进度条部件
    lv_obj_set_align(progressBar, LV_ALIGN_CENTER);                             // 设置进度条部件居中对齐
    // 当进度条的宽度大于高度时,进度条为水平进度条,当进度条的高度大于宽度时,进度条为垂直进度条
    lv_obj_set_size(progressBar, 300, 30);                                      // 设置进度条部件的尺寸
    // 动画时间设置必须放在当前值设置之前
    lv_obj_set_style_anim_time(progressBar, 100, LV_STATE_DEFAULT);             // 设置进度条部件的动画时间

    lv_timer_t *timer = lv_timer_create(timer_cb, 100, NULL);                   // 创建软件定时器
    lv_timer_ready(timer);                                                      // 软件定时器就绪

    while (1)
    {
        lv_timer_handler();
        Delay_ms(5);
    }
  
    return 0;
}
void timer_cb(lv_timer_t *timer)
{
    static uint8_t value = 0;

    if (value <= 100)
    {
        lv_bar_set_value(progressBar, value, LV_ANIM_ON);
        value++;
    }
    else
    {
        value = 0;
    }
}
posted @ 2024-08-31 20:48  星光映梦  阅读(82)  评论(0编辑  收藏  举报