avatar

松果工作室

欢迎光临

  • 首页
  • freeRTOS
  • ESP
  • 开发手册
  • 快速笔记
  • 个人收藏
  • 工具
Home LVGL UI 代码格式
文章

LVGL UI 代码格式

Posted 2024-07-3 Updated 2024-07- 3
By YCP
100~129 min read

UI初始化

void ui_init(void){
  lv_disp_t * dispp = lv_disp_get_default();
  lv_theme_t * theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED),
                                             false, LV_FONT_DEFAULT);
  lv_disp_set_theme(dispp, theme);
  ui_Screen1_screen_init();
  ui____initial_actions0 = lv_obj_create(NULL);
  lv_disp_load_scr(ui_Screen1);
}

主代码

void ui_Screen1_screen_init(void)
{
  lv_group_t * group = lv_group_create();
  lv_indev_set_group(indev_keypad, group);

  ui_Screen1 = lv_obj_create(NULL);
  lv_obj_clear_flag(ui_Screen1, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Screen1, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Screen1, lv_color_hex(0x0c0c0c), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Screen1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_left(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_right(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_top(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_bottom(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Panel1 = lv_obj_create(ui_Screen1);
  lv_obj_set_width(ui_Panel1, 480);
  lv_obj_set_height(ui_Panel1, 24);
  lv_obj_set_x(ui_Panel1, 0);
  lv_obj_set_y(ui_Panel1, -10);
  lv_obj_set_align(ui_Panel1, LV_ALIGN_TOP_MID);
  lv_obj_clear_flag(ui_Panel1, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Panel1, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Panel1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Panel1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_color(ui_Panel1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(ui_Panel1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label1 = lv_label_create(ui_Panel1);
  lv_obj_set_width(ui_Label1, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label1, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_align(ui_Label1, LV_ALIGN_LEFT_MID);
  lv_label_set_text(ui_Label1, "Friday, March 11, 2024");
  lv_obj_set_style_text_color(ui_Label1, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label1, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label3 = lv_label_create(ui_Panel1);
  lv_obj_set_width(ui_Label3, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label3, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_align(ui_Label3, LV_ALIGN_RIGHT_MID);
  lv_label_set_text(ui_Label3, "AM 8:45");
  lv_obj_set_style_text_color(ui_Label3, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label3, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label3, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label4 = lv_label_create(ui_Screen1);
  lv_obj_set_width(ui_Label4, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label4, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_x(ui_Label4, 0);
  lv_obj_set_y(ui_Label4, -110);
  lv_obj_set_align(ui_Label4, LV_ALIGN_CENTER);
  lv_label_set_text(ui_Label4, "Temperature Control");
  lv_obj_set_style_text_color(ui_Label4, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label4, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label4, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Arc_Group = lv_obj_create(ui_Screen1);
  lv_obj_set_width(ui_Arc_Group, 200);
  lv_obj_set_height(ui_Arc_Group, 200);
  lv_obj_set_x(ui_Arc_Group, 0);
  lv_obj_set_y(ui_Arc_Group, 19);
  lv_obj_set_align(ui_Arc_Group, LV_ALIGN_CENTER);
  lv_obj_clear_flag(ui_Arc_Group, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_bg_color(ui_Arc_Group, lv_color_hex(0x414141), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Arc_Group, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Arc1 = lv_arc_create(ui_Arc_Group);
  lv_obj_set_width(ui_Arc1, 150);
  lv_obj_set_height(ui_Arc1, 150);
  lv_obj_set_align(ui_Arc1, LV_ALIGN_CENTER);
  lv_arc_set_value(ui_Arc1, 50);
  lv_arc_set_bg_angles(ui_Arc1, 110, 70);
  lv_obj_set_style_radius(ui_Arc1, 75, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Arc1, lv_color_hex(0x2D2D2D), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Arc1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_left(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_right(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_top(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_bottom(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_arc_color(ui_Arc1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_arc_opa(ui_Arc1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_arc_width(ui_Arc1, 6, LV_PART_MAIN | LV_STATE_DEFAULT);

  lv_obj_set_style_arc_width(ui_Arc1, 6, LV_PART_INDICATOR | LV_STATE_DEFAULT);

  lv_obj_set_style_border_side(ui_Arc1, LV_BORDER_SIDE_FULL, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_left(ui_Arc1, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_right(ui_Arc1, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_top(ui_Arc1, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_bottom(ui_Arc1, -1, LV_PART_KNOB | LV_STATE_DEFAULT);

  ui_Panel3 = lv_obj_create(ui_Arc_Group);
  lv_obj_set_width(ui_Panel3, 122);
  lv_obj_set_height(ui_Panel3, 122);
  lv_obj_set_align(ui_Panel3, LV_ALIGN_CENTER);
  lv_obj_clear_flag(ui_Panel3, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Panel3, 61, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Panel3, lv_color_hex(0x646464), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Panel3, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_color(ui_Panel3, lv_color_hex(0x646464), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(ui_Panel3, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Panel4 = lv_obj_create(ui_Panel3);
  lv_obj_set_width(ui_Panel4, 90);
  lv_obj_set_height(ui_Panel4, 90);
  lv_obj_set_align(ui_Panel4, LV_ALIGN_CENTER);
  lv_obj_clear_flag(ui_Panel4, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Panel4, 45, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_color(ui_Panel4, lv_color_hex(0x5A646E), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(ui_Panel4, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_color(ui_Panel4, lv_color_hex(0x746D6D), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_opa(ui_Panel4, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_width(ui_Panel4, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_spread(ui_Panel4, 5, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label5 = lv_label_create(ui_Panel4);
  lv_obj_set_width(ui_Label5, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label5, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_align(ui_Label5, LV_ALIGN_CENTER);
  lv_label_set_text(ui_Label5, "23");
  lv_obj_set_style_text_color(ui_Label5, lv_color_hex(0x808080), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label5, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label5, &ui_font_Font1, LV_PART_MAIN | LV_STATE_DEFAULT);

  lv_obj_add_event_cb(ui_Arc1, ui_event_Arc1, LV_EVENT_ALL, NULL);

  lv_group_add_obj(group, ui_Arc1);
}

UI 控件事件,这里单有Arc1的控件事件

void ui_event_Arc1(lv_event_t * e)
{
  lv_event_code_t event_code = lv_event_get_code(e);
  lv_obj_t * target = lv_event_get_target(e);
  if(event_code == LV_EVENT_VALUE_CHANGED) {
    _ui_arc_set_text_value(ui_Label3, target, "AM", ":45");
  }
  if(event_code == LV_EVENT_VALUE_CHANGED) {
    _ui_arc_set_text_value(ui_Label5, target, "", "");
  }
}

整体代码

#include "lvTask.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <driver/gpio.h>
#include <driver/ledc.h>
#include <driver/spi_master.h>
#include <esp_err.h>
#include <esp_log.h>
#include <esp_lcd_panel_io.h>
#include <esp_lcd_panel_vendor.h>
#include <esp_lcd_panel_ops.h>
#include <esp_lcd_ili9488.h>
#include <esp_timer.h>
#include <lvgl.h>
#include "../managed_components/lvgl__lvgl/src/hal/lv_hal_indev.h"
#include "benchmark/lv_demo_benchmark.h"
#include "btTask.h"

#define CONFIG_SPI_MOSI 11
#define CONFIG_SPI_MISO 13
#define CONFIG_SPI_CLOCK 12
#define CONFIG_TFT_BACKLIGHT_PIN 1
#define CONFIG_TFT_CS_PIN 10
#define CONFIG_TFT_DC_PIN 15
#define CONFIG_TFT_RESET_PIN 16
#define CONFIG_DISPLAY_COLOR_MODE 1

static const char *TAG = "main";

static const int DISPLAY_HORIZONTAL_PIXELS = 320;
static const int DISPLAY_VERTICAL_PIXELS = 480;
static const size_t LV_BUFFER_SIZE = DISPLAY_HORIZONTAL_PIXELS * DISPLAY_VERTICAL_PIXELS / 4;
static const int LVGL_UPDATE_PERIOD_MS = 5;
static const uint32_t BACKLIGHT_LEDC_FRQUENCY = 5000;

static esp_lcd_panel_io_handle_t lcd_io_handle = NULL;    //储存SPI硬件配置信息
static esp_lcd_panel_handle_t lcd_handle = NULL;          //传入硬件配置到驱动函数引出操作LCD的配置
static lv_disp_draw_buf_t lv_disp_buf;                    //初始化缓存配置到这个结构体
static lv_disp_drv_t lv_disp_drv;                         //LVGL抽象出来的对外接口以及函数配置
static lv_indev_drv_t lv_indev_drv;
lv_indev_t *indev_keypad;
static lv_color_t *lv_buf_1 = NULL;
static lv_color_t *lv_buf_2 = NULL;


/** 把 LVGL 抽象出来的配置中的刷屏结束标志置位 **/
static bool notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io,
                                    esp_lcd_panel_io_event_data_t *edata, void *user_ctx) {
  lv_disp_drv_t *disp_driver = (lv_disp_drv_t *) user_ctx;
  lv_disp_flush_ready(disp_driver);
  return false;
}

/** LVGL刷屏对接ILI9488 **/
static void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_map) {
  esp_lcd_panel_handle_t panel_handle = (esp_lcd_panel_handle_t) drv->user_data;
  esp_lcd_panel_draw_bitmap(panel_handle, area->x1, area->y1, area->x2 + 1, area->y2 + 1, color_map);
}

/** LVGL心跳 **/
static void IRAM_ATTR lvgl_tick_cb(void *param) {
  lv_tick_inc(LVGL_UPDATE_PERIOD_MS);
}

/** 底层硬件IO初始化 **/
static void display_brightness_init(void) {
  const ledc_channel_config_t LCD_backlight_channel = {
          .gpio_num = (gpio_num_t) CONFIG_TFT_BACKLIGHT_PIN,
          .speed_mode = LEDC_LOW_SPEED_MODE,
          .channel = LEDC_CHANNEL_0,
          .intr_type = LEDC_INTR_DISABLE,
          .timer_sel = LEDC_TIMER_1,
          .duty = 0,
          .hpoint = 0,
          .flags ={
                  .output_invert = 0
          }
  };
  const ledc_timer_config_t LCD_backlight_timer = {
          .speed_mode = LEDC_LOW_SPEED_MODE,
          .duty_resolution = LEDC_TIMER_10_BIT,
          .timer_num = LEDC_TIMER_1,
          .freq_hz = BACKLIGHT_LEDC_FRQUENCY,
          .clk_cfg = LEDC_AUTO_CLK
  };
  ESP_LOGI(TAG, "Initializing LEDC for backlight pin: %d", CONFIG_TFT_BACKLIGHT_PIN);
  ESP_ERROR_CHECK(ledc_timer_config(&LCD_backlight_timer));
  ESP_ERROR_CHECK(ledc_channel_config(&LCD_backlight_channel));
}
void display_brightness_set(int brightness_percentage) {
  if (brightness_percentage > 100) {
    brightness_percentage = 100;
  } else if (brightness_percentage < 0) {
    brightness_percentage = 0;
  }
  ESP_LOGI(TAG, "Setting backlight to %d%%", brightness_percentage);
  uint32_t duty_cycle = (1023 * brightness_percentage) / 100;
  ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty_cycle));
  ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
}

/** 将底层SPI抽象出一个句柄交给esplcd控制 ,而这个句柄也会交给lvgl控制**/
void initialize_display() {
  ESP_LOGI(TAG, "Initializing SPI bus (MOSI:%d, MISO:%d, CLK:%d)",
           CONFIG_SPI_MOSI, CONFIG_SPI_MISO, CONFIG_SPI_CLOCK);
  spi_bus_config_t bus =
          {
                  .mosi_io_num = CONFIG_SPI_MOSI,
                  .miso_io_num = CONFIG_SPI_MISO,
                  .sclk_io_num = CONFIG_SPI_CLOCK,
                  .quadwp_io_num = GPIO_NUM_NC,
                  .quadhd_io_num = GPIO_NUM_NC,
                  .data4_io_num = GPIO_NUM_NC,
                  .data5_io_num = GPIO_NUM_NC,
                  .data6_io_num = GPIO_NUM_NC,
                  .data7_io_num = GPIO_NUM_NC,
                  .max_transfer_sz = 4096*8,
                  .flags = SPICOMMON_BUSFLAG_SCLK | SPICOMMON_BUSFLAG_MISO |
                           SPICOMMON_BUSFLAG_MOSI | SPICOMMON_BUSFLAG_MASTER,
                  .intr_flags = ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM
          };

  ESP_ERROR_CHECK(spi_bus_initialize(SPI2_HOST, &bus, SPI_DMA_CH_AUTO));

  const esp_lcd_panel_io_spi_config_t io_config = {
          .cs_gpio_num = CONFIG_TFT_CS_PIN,
          .dc_gpio_num = CONFIG_TFT_DC_PIN,
          .spi_mode = 0,
          .pclk_hz = 80*1000*1000,
          .trans_queue_depth = 10,
          .on_color_trans_done = notify_lvgl_flush_ready,
          .user_ctx = &lv_disp_drv,//把notify_lvgl_flush_ready传入lv_disp_drv来通知刷新完成
          .lcd_cmd_bits = 8,
          .lcd_param_bits = 8,
          .flags ={
                  .dc_as_cmd_phase = 0,
                  .dc_low_on_data = 0,
                  .octal_mode = 0,
                  .lsb_first = 0
          }
  };

  const esp_lcd_panel_dev_config_t lcd_config ={
          .reset_gpio_num = CONFIG_TFT_RESET_PIN,
          .color_space = CONFIG_DISPLAY_COLOR_MODE,
          .bits_per_pixel = 18,
          .flags ={
                  .reset_active_high = 0
          },
          .vendor_config = NULL
  };
  ESP_ERROR_CHECK(
          esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t) SPI2_HOST, &io_config, &lcd_io_handle));
  ESP_ERROR_CHECK(esp_lcd_new_panel_ili9488(lcd_io_handle, &lcd_config, LV_BUFFER_SIZE, &lcd_handle));

  ESP_ERROR_CHECK(esp_lcd_panel_reset(lcd_handle));
  ESP_ERROR_CHECK(esp_lcd_panel_init(lcd_handle));
  ESP_ERROR_CHECK(esp_lcd_panel_invert_color(lcd_handle, false));
  ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(lcd_handle, false));
  ESP_ERROR_CHECK(esp_lcd_panel_mirror(lcd_handle, false, false));
  ESP_ERROR_CHECK(esp_lcd_panel_set_gap(lcd_handle, 0, 0));
  ESP_ERROR_CHECK(esp_lcd_panel_disp_off(lcd_handle, false));
}

void initialize_indev(){
  gpio_config_t key_config = {
          .pin_bit_mask = (1ULL << GPIO_NUM_0)|(1ULL << GPIO_NUM_2)|(1ULL << GPIO_NUM_3),
          .mode = GPIO_MODE_INPUT,
          .pull_up_en = GPIO_PULLUP_ENABLE,
          .pull_down_en = GPIO_PULLDOWN_DISABLE,
          .intr_type = GPIO_INTR_DISABLE
  };
  ESP_ERROR_CHECK(gpio_config(&key_config));
}

static void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data);

/** LVGL对接底层硬件,对接刷屏函数,以及本身的参数配置**/
void initialize_lvgl() {
  ESP_LOGI(TAG, "Initializing LVGL");
  lv_init();
  ESP_LOGI(TAG, "Allocating %zu bytes for LVGL buffer", LV_BUFFER_SIZE * sizeof(lv_color_t));
  lv_buf_1 = (lv_color_t *) heap_caps_malloc(LV_BUFFER_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
  //lv_buf_2 = (lv_color_t *) heap_caps_malloc(LV_BUFFER_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA);
  ESP_LOGI(TAG, "Creating LVLG display buffer");
  lv_disp_draw_buf_init(&lv_disp_buf, lv_buf_1, lv_buf_2, LV_BUFFER_SIZE);

  ESP_LOGI(TAG, "Initializing %dx%d display", DISPLAY_HORIZONTAL_PIXELS, DISPLAY_VERTICAL_PIXELS);
  lv_disp_drv_init(&lv_disp_drv);
  lv_disp_drv.hor_res = DISPLAY_HORIZONTAL_PIXELS;
  lv_disp_drv.ver_res = DISPLAY_VERTICAL_PIXELS;
  lv_disp_drv.flush_cb = lvgl_flush_cb;
  lv_disp_drv.draw_buf = &lv_disp_buf;
  lv_disp_drv.user_data = lcd_handle;
  lv_disp_drv.sw_rotate = 1;
  lv_disp_drv.rotated = LV_DISP_ROT_90;
  lv_disp_drv_register(&lv_disp_drv);

  lv_indev_drv_init(&lv_indev_drv);
  lv_indev_drv.type = LV_INDEV_TYPE_KEYPAD;
  lv_indev_drv.read_cb = keypad_read;
  indev_keypad = lv_indev_drv_register(&lv_indev_drv);


  ESP_LOGI(TAG, "Creating LVGL tick timer");
  const esp_timer_create_args_t lvgl_tick_timer_args = {
          .callback = &lvgl_tick_cb,
          .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, LVGL_UPDATE_PERIOD_MS * 1000));
}

void ui_init(void);
void lvTask(void *pvParameters){
  initialize_display();
  initialize_indev();
  display_brightness_init();
  display_brightness_set(30);
  initialize_lvgl();
  //lv_example_get_started();
  //lv_demo_benchmark();
  ui_init();
  while(1){
    lv_timer_handler();
    vTaskDelay(5 / portTICK_PERIOD_MS);
  }
}

static uint32_t keypad_get_key() {
  if(gpio_get_level(0) == 0){
    return LV_KEY_ENTER;
  }else if(gpio_get_level(2) == 0) {
    return LV_KEY_NEXT;
  }else if(gpio_get_level(3) == 0){
      return LV_KEY_RIGHT;
  }else return 0;
}

/** 把是哪个按键传递给data 由于这个函数是定义在外部输入设备的初始哈u中,因此最终值会传到indev_keypad ,也就是把按键加入组的哪个过程**/
static void keypad_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) {
  static uint32_t last_key = 0;
  //mouse_get_xy(&data->point.x, &data->point.y);
  uint32_t act_key = keypad_get_key();
  if (act_key != 0) {
    data->state = LV_INDEV_STATE_PR;
    switch (act_key) {
      case 1:
        act_key = LV_KEY_NEXT;
        break;
      case 2:
        act_key = LV_KEY_PREV;
        break;
      case 3:
        act_key = LV_KEY_LEFT;
        break;
      case 4:
        act_key = LV_KEY_RIGHT;
        break;
      case 5:
        act_key = LV_KEY_ENTER;
        break;
    }
    last_key = act_key;
  } else {
    data->state = LV_INDEV_STATE_REL;
  }
  data->key = last_key;
}



/****************************************************************************
* @brief		接下来是UI文件
* @details
****************************************************************************/
#include "ui_helpers.h"
LV_FONT_DECLARE(ui_font_Font1);

void ui_Screen1_screen_init(void);
lv_obj_t * ui_Screen1;
lv_obj_t * ui_Panel1;
lv_obj_t * ui_Label1;
lv_obj_t * ui_Label3;
lv_obj_t * ui_Label4;
lv_obj_t * ui_Arc_Group;
void ui_event_Arc1(lv_event_t * e);
lv_obj_t * ui_Arc1;
lv_obj_t * ui_Panel3;
lv_obj_t * ui_Panel4;
lv_obj_t * ui_Label5;
lv_obj_t * ui____initial_actions0;

void ui_event_Arc1(lv_event_t * e)
{
  lv_event_code_t event_code = lv_event_get_code(e);
  lv_obj_t * target = lv_event_get_target(e);
  if(event_code == LV_EVENT_VALUE_CHANGED) {
    _ui_arc_set_text_value(ui_Label3, target, "AM", ":45");
  }
  if(event_code == LV_EVENT_VALUE_CHANGED) {
    _ui_arc_set_text_value(ui_Label5, target, "", "");
  }
}

void ui_init(void){
  lv_disp_t * dispp = lv_disp_get_default();
  lv_theme_t * theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED),
                                             false, LV_FONT_DEFAULT);
  lv_disp_set_theme(dispp, theme);
  ui_Screen1_screen_init();
  ui____initial_actions0 = lv_obj_create(NULL);
  lv_disp_load_scr(ui_Screen1);
}
void ui_Screen1_screen_init(void)
{
  lv_group_t * group = lv_group_create();
  lv_indev_set_group(indev_keypad, group);

  ui_Screen1 = lv_obj_create(NULL);
  lv_obj_clear_flag(ui_Screen1, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Screen1, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Screen1, lv_color_hex(0x0c0c0c), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Screen1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_left(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_right(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_top(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_bottom(ui_Screen1, 10, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Panel1 = lv_obj_create(ui_Screen1);
  lv_obj_set_width(ui_Panel1, 480);
  lv_obj_set_height(ui_Panel1, 24);
  lv_obj_set_x(ui_Panel1, 0);
  lv_obj_set_y(ui_Panel1, -10);
  lv_obj_set_align(ui_Panel1, LV_ALIGN_TOP_MID);
  lv_obj_clear_flag(ui_Panel1, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Panel1, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Panel1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Panel1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_color(ui_Panel1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(ui_Panel1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label1 = lv_label_create(ui_Panel1);
  lv_obj_set_width(ui_Label1, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label1, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_align(ui_Label1, LV_ALIGN_LEFT_MID);
  lv_label_set_text(ui_Label1, "Friday, March 11, 2024");
  lv_obj_set_style_text_color(ui_Label1, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label1, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label3 = lv_label_create(ui_Panel1);
  lv_obj_set_width(ui_Label3, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label3, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_align(ui_Label3, LV_ALIGN_RIGHT_MID);
  lv_label_set_text(ui_Label3, "AM 8:45");
  lv_obj_set_style_text_color(ui_Label3, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label3, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label3, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label4 = lv_label_create(ui_Screen1);
  lv_obj_set_width(ui_Label4, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label4, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_x(ui_Label4, 0);
  lv_obj_set_y(ui_Label4, -110);
  lv_obj_set_align(ui_Label4, LV_ALIGN_CENTER);
  lv_label_set_text(ui_Label4, "Temperature Control");
  lv_obj_set_style_text_color(ui_Label4, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label4, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label4, &lv_font_montserrat_16, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Arc_Group = lv_obj_create(ui_Screen1);
  lv_obj_set_width(ui_Arc_Group, 200);
  lv_obj_set_height(ui_Arc_Group, 200);
  lv_obj_set_x(ui_Arc_Group, 0);
  lv_obj_set_y(ui_Arc_Group, 19);
  lv_obj_set_align(ui_Arc_Group, LV_ALIGN_CENTER);
  lv_obj_clear_flag(ui_Arc_Group, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_bg_color(ui_Arc_Group, lv_color_hex(0x414141), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Arc_Group, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Arc1 = lv_arc_create(ui_Arc_Group);
  lv_obj_set_width(ui_Arc1, 150);
  lv_obj_set_height(ui_Arc1, 150);
  lv_obj_set_align(ui_Arc1, LV_ALIGN_CENTER);
  lv_arc_set_value(ui_Arc1, 50);
  lv_arc_set_bg_angles(ui_Arc1, 110, 70);
  lv_obj_set_style_radius(ui_Arc1, 75, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Arc1, lv_color_hex(0x2D2D2D), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Arc1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_left(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_right(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_top(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_bottom(ui_Arc1, 4, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_arc_color(ui_Arc1, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_arc_opa(ui_Arc1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_arc_width(ui_Arc1, 6, LV_PART_MAIN | LV_STATE_DEFAULT);

  lv_obj_set_style_arc_width(ui_Arc1, 6, LV_PART_INDICATOR | LV_STATE_DEFAULT);

  lv_obj_set_style_border_side(ui_Arc1, LV_BORDER_SIDE_FULL, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_left(ui_Arc1, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_right(ui_Arc1, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_top(ui_Arc1, 0, LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_set_style_pad_bottom(ui_Arc1, -1, LV_PART_KNOB | LV_STATE_DEFAULT);

  ui_Panel3 = lv_obj_create(ui_Arc_Group);
  lv_obj_set_width(ui_Panel3, 122);
  lv_obj_set_height(ui_Panel3, 122);
  lv_obj_set_align(ui_Panel3, LV_ALIGN_CENTER);
  lv_obj_clear_flag(ui_Panel3, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Panel3, 61, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(ui_Panel3, lv_color_hex(0x646464), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(ui_Panel3, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_color(ui_Panel3, lv_color_hex(0x646464), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(ui_Panel3, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Panel4 = lv_obj_create(ui_Panel3);
  lv_obj_set_width(ui_Panel4, 90);
  lv_obj_set_height(ui_Panel4, 90);
  lv_obj_set_align(ui_Panel4, LV_ALIGN_CENTER);
  lv_obj_clear_flag(ui_Panel4, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
  lv_obj_set_style_radius(ui_Panel4, 45, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_color(ui_Panel4, lv_color_hex(0x5A646E), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(ui_Panel4, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_color(ui_Panel4, lv_color_hex(0x746D6D), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_opa(ui_Panel4, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_width(ui_Panel4, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_shadow_spread(ui_Panel4, 5, LV_PART_MAIN | LV_STATE_DEFAULT);

  ui_Label5 = lv_label_create(ui_Panel4);
  lv_obj_set_width(ui_Label5, LV_SIZE_CONTENT);   /// 1
  lv_obj_set_height(ui_Label5, LV_SIZE_CONTENT);    /// 1
  lv_obj_set_align(ui_Label5, LV_ALIGN_CENTER);
  lv_label_set_text(ui_Label5, "23");
  lv_obj_set_style_text_color(ui_Label5, lv_color_hex(0x808080), LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_opa(ui_Label5, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(ui_Label5, &ui_font_Font1, LV_PART_MAIN | LV_STATE_DEFAULT);

  lv_obj_add_event_cb(ui_Arc1, ui_event_Arc1, LV_EVENT_ALL, NULL);

  lv_group_add_obj(group, ui_Arc1);
}


Others
License:  CC BY 4.0
Share

Further Reading

OLDER

结构体指针传参

NEWER

Airtag Tag

Recently Updated

  • ESP32(八) 简单的webserver
  • ESP32(七) NVS
  • ESP32(四) STA & AP
  • 多级菜单
  • ESP32(五) ESP32 OTA

Trending Tags

WCH Linux Elec freeRTOS STM ESP Flutter Others SwiftUI

Contents

©2025 松果工作室. Some rights reserved.

Using the Halo theme Chirpy