walker2048 发表于 2024-6-6 16:57

【FireBeetle 2 ESP32 C6开发板】6、适配lvgl 9.1-- 完成LVGL测试程序

<div class='showpostmsg'>### 前言
lvgl已经出到9.x版本了,github上的lv_port_esp32还是7.x版本,由于我自己有Linux和esp32两种设备的开发需求,esp32的RAM和Flash也不算小,
我打算直接使用9.1版本的lvgl,然后使用lvgl_esp32_drivers仓库,仓库地址是https://github.com/lvgl/lvgl_esp32_drivers.git

### 编写lvgl测试程序

这里写的程序比较简单,抄袭的是lvgl的示范代码,然后简单修改了一下。

```c
/*
* SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"

#include "lvgl.h"
#include <inttypes.h>
#include <stdio.h>

#include "esp_err.h"
#include "esp_log.h"
#include "esp_timer.h"

#include "src/widgets/label/lv_label.h"

#define TAG "LVGL"

static void btn_event_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t *btn = lv_event_get_target(e);
if (code == LV_EVENT_CLICKED) {
    uint32_t current_time = esp_timer_get_time() / 1000;
    static bool status = true;
    static uint32_t last_check_time = 0;
    if (current_time - last_check_time >= 300) {
      static uint8_t cnt = 0;
      cnt++;
      last_check_time = current_time;
      /*Get the first child of the button which is the label and change its
       * text*/
      lv_obj_t *label = lv_obj_get_child(btn, 0);

      if (status) {
      lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_CYAN), 0);
      lv_label_set_text(label, "LED Off");
      } else {
      lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_AMBER), 0);
      lv_label_set_text(label, "LED On");
      }
      status = !status;
    }
}
}

/**
* Create a button with a label and react on click event.
*/
void lv_example_get_started_2(void) {
lv_obj_t *btn =
      lv_button_create(lv_screen_active()); /*Add a button the current screen*/

lv_obj_set_style_bg_color(btn, lv_palette_main(LV_PALETTE_AMBER), 0);

lv_obj_set_pos(btn, 80, 140);/*Set its position*/
lv_obj_set_size(btn, 120, 50); /*Set its size*/
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_ALL,
                      NULL); /*Assign a callback to the button*/

lv_obj_t *label = lv_label_create(btn); /*Add a label to the button*/
lv_label_set_text(label, "Button");   /*Set the labels text*/
lv_obj_center(label);

lv_obj_t *btn1 =
      lv_button_create(lv_screen_active()); /*Add a button the current screen*/

lv_obj_set_style_bg_color(btn1, lv_palette_main(LV_PALETTE_DEEP_ORANGE), 0);

lv_obj_set_pos(btn1, 80, 60);   /*Set its position*/
lv_obj_set_size(btn1, 120, 50); /*Set its size*/
lv_obj_add_event_cb(btn1, NULL, LV_EVENT_ALL,
                      NULL); /*Assign a callback to the button*/

lv_obj_t *label1 = lv_label_create(btn1); /*Add a label to the button*/
lv_label_set_text(label1, "LED");      /*Set the labels text*/
lv_obj_center(label1);
}

static void example_increase_lvgl_tick(void *arg) {
/* Tell LVGL how many milliseconds has elapsed */
lv_tick_inc(2);
}

extern void lv_port_disp_init(void);
extern void lv_port_indev_init(void);
void app_main(void) {
lv_init();
lv_port_disp_init();
lv_port_indev_init();

ESP_LOGI(TAG, "Install LVGL tick timer");
// Tick interface for LVGL (using esp_timer to generate 2ms periodic event)
const esp_timer_create_args_t lvgl_tick_timer_args = {
      .callback = &example_increase_lvgl_tick, .name = "lvgl_tick"};
esp_timer_handle_t lvgl_tick_timer = NULL;
ESP_ERROR_CHECK(esp_timer_create(&lvgl_tick_timer_args, &lvgl_tick_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(lvgl_tick_timer, 2 * 1000));
lv_example_get_started_2();

/* handle the tasks of LVGL */
while (1) {
    lv_task_handler();
    vTaskDelay(pdMS_TO_TICKS(30));
}
}

```

简单介绍下lvgl程序的调用过程,如图所示。
1. 初始化:
        1.1 lv_init():这是LVGL库的初始化函数,它会设置内部数据结构并准备库开始工作。
2. 硬件适配:
        2.1 lv_port_disp_init():这个函数是为LVGL配置显示适配器,使得LVGL能与特定硬件的显示屏进行交互。
        2.2 lv_port_indev_init():初始化输入设备处理,通常是为了处理触摸屏或其他形式的用户输入。
3. 设置LVGL定时器:
        3.1 example_increase_lvgl_tick 函数:LVGL需要一个定时器来更新界面,模拟时间流逝。这个函数每2毫秒调用一次lv_tick_inc(),向        LVGL报告时间的流逝。
        3.2 esp_timer_create 和 esp_timer_start_periodic:创建了一个周期性定时器,每隔2毫秒调用example_increase_lvgl_tick。
4. 运行LVGL示例:
        4.1 lv_example_get_started_2():这是LVGL的一个示例应用,帮助开发者快速了解如何创建和操作UI元素。
5. 主循环:
        5.1 while (1) 循环:这里是LVGL的主要事件处理循环。
        5.2 lv_task_handler():处理LVGL的任务队列,更新界面和处理动画。
        5.3 vTaskDelay(pdMS_TO_TICKS(30)):为了防止CPU过度占用,添加了一个短暂的延迟,让其他任务有机会运行。这样保证了界面更新的平滑性和响应性。



#### 运行的实际照片
程序功能就是展示两个简单的按钮,然后点击按钮1(黄色)后,按钮上的文字会在LED On和LED Off之间切换,按钮颜色也会变化。由于暂时找不到触屏的消抖功能在lvgl什么地方设置,就先在按钮的回调函数里写一个简单的消抖功能,消抖设置成300ms内,这样就实现一个简单的消抖按键了。
由于触屏的板子还没有打板,不好用FireBeetle板子测试,先用手头上有的esp32s3触屏板子进行测试。
点击按钮前

点击按钮后

</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                               
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

Jacktang 发表于 2024-6-7 07:32

<p>lvgl已经出到9.x版本了,进化迭代的速度真快</p>

walker2048 发表于 2024-6-7 09:54

Jacktang 发表于 2024-6-7 07:32
lvgl已经出到9.x版本了,进化迭代的速度真快

<p>不少大佬说9版本的占用资源更多,更慢,我这边没啥需求,只是不想用不同版本适应不同api</p>
页: [1]
查看完整版本: 【FireBeetle 2 ESP32 C6开发板】6、适配lvgl 9.1-- 完成LVGL测试程序