ESP32 RGB组件设计搭建记录

ESP32 RGB组件设计搭建记录

开发软件版本

esp-idf v5.3.1

硬件信息

ESP32

LED低电平有效,R-led IO17 G-led IO4 B-led 16

原理介绍

通过 PWM(脉冲宽度调制)调节红(R)、绿(G)、蓝(B)三色 LED 的亮度占空比,按比例混合出不同颜色(RGB 三原色混合定律)

总体方案设计

LED工作模式

LED总体分为如下工作模式:常亮;常灭;闪烁;呼吸渐强;呼吸渐弱

模式枚举值模式名称核心行为定义关键参数
LED_MODE_ON常亮固定目标亮度持续输出,PWM 占空比恒定,无渐变 / 闪烁,定时器持续运行目标 RGB 亮度(0-255)
LED_MODE_OFF常灭PWM 占空比强制设 0,暂停 LEDC 定时器(低功耗),所有参数不生效无(仅启停控制)
LED_MODE_BLINK闪烁固定目标亮度 “亮 - 灭” 切换,亮 / 灭时长由 “总周期 + 占空比” 决定,无渐变总周期(≥10ms)、亮灯占空比(0-100%)、目标 RGB 亮度
LED_MODE_BREATH_UP呼吸渐强从 0 亮度线性渐变到目标最大亮度,渐变完成后停在最大亮度(可选循环)渐变总时长(ms)、目标 RGB 亮度、最大亮度(0-255)
LED_MODE_BREATH_DOWN呼吸渐弱从目标最大亮度线性渐变到 0 亮度,渐变完成后停在 0 亮度(可选循环)渐变总时长(ms)、目标 RGB 亮度、最大亮度(0-255)

宏定义

/************************* 硬件&LEDC配置宏 *************************/
#define LED_R_IO        GPIO_NUM_17
#define LED_G_IO        GPIO_NUM_4
#define LED_B_IO        GPIO_NUM_16

#define LEDC_TIMER      LEDC_TIMER_0
#define LEDC_MODE       LEDC_LOW_SPEED_MODE
#define LEDC_CHANNEL_R  LEDC_CHANNEL_0
#define LEDC_CHANNEL_G  LEDC_CHANNEL_1
#define LEDC_CHANNEL_B  LEDC_CHANNEL_2
#define LEDC_DUTY_RES   LEDC_TIMER_10_BIT  // 10位分辨率(0-1023)
#define LEDC_FREQ_HZ    5000               // 5kHz无频闪
#define BRIGHTNESS_TO_DUTY(bright)  ((uint32_t)(bright) * 1023 / 255)

数据结构设计

/************************* 模式&状态定义 *************************/
// LED工作模式
typedef enum _led_work_mode {
    LED_MODE_OFF = 0,        // 常灭
    LED_MODE_ON,             // 常亮
    LED_MODE_BLINK,          // 闪烁
    LED_MODE_BREATH_UP,      // 呼吸渐强(0→最大亮度)
    LED_MODE_BREATH_DOWN,    // 呼吸渐弱(最大→0亮度)
    LED_MODE_MAX             // 模式边界
} led_work_mode;

// 闪烁/呼吸状态(用于定时器回调状态机)
typedef enum _led_run_state {
    LED_STATE_IDLE,          // 空闲
    LED_STATE_BLINK_ON,      // 闪烁-亮
    LED_STATE_BLINK_OFF,     // 闪烁-灭
    LED_STATE_BREATH_UP,     // 呼吸-渐强中
    LED_STATE_BREATH_DOWN    // 呼吸-渐弱中
} led_run_state;
/************************* 全局配置结构体 *************************/
typedef struct _rgb_color_conf {
    uint8_t red;   // 0-255
    uint8_t green; // 0-255
    uint8_t blue;  // 0-255
} rgb_color_conf;

typedef struct _rgb_led_global_conf {
    // 基础配置
    rgb_color_conf color;          // 当前颜色
    led_work_mode work_mode;       // 工作模式
    led_run_state run_state;       // 运行状态
    bool led_turn_on;              // 总启用开关
    // 模式参数
    uint16_t total_period_ms;      // 基础周期(闪烁/呼吸通用,ms)
    uint8_t turn_on_per;           // 闪烁占空比(0-100%)
    uint8_t breath_max_bright;     // 呼吸最大亮度(0-255)
    // 定时器句柄
    TimerHandle_t led_timer;       // 软件定时器句柄
} rgb_led_global_conf;

// 预设颜色枚举&数组
typedef enum _G_COLOR {
    G_COLOR_RED_STANDARD,    // 0
    G_COLOR_ORANGE_STANDARD, // 1
    G_COLOR_YELLOW_STANDARD, // 2
    G_COLOR_GREEN_STANDARD,  // 3
    G_COLOR_CYAN_STANDARD,   // 4
    G_COLOR_BLUE_STANDARD,   // 5
    G_COLOR_PURPLE_STANDARD, // 6
    G_COLOR_MAX              // 7
} G_COLOR;

static const rgb_color_conf g_rgb_color_list[] = {
    {255, 0, 0},       // 红
    {255, 165, 0},     // 橙
    {255, 255, 0},     // 黄
    {0, 255, 0},       // 绿
    {0, 255, 255},     // 青
    {0, 0, 255},       // 蓝
    {255, 0, 255}      // 紫
};

// 全局配置初始化
static rgb_led_global_conf g_rgb_led_conf = {
    .color = {0, 0, 0},
    .work_mode = LED_MODE_OFF,
    .run_state = LED_STATE_IDLE,
    .led_turn_on = false,
    .total_period_ms = 2000,
    .turn_on_per = 50,
    .breath_max_bright = 255,
    .led_timer = NULL
};

接口说明

私有接口

/************************* 私有函数实现 *************************/
/** * @brief LEDC定时器启停 */
static void ledc_timer_control(bool enable)

/** * @brief PWM初始化 */
static void rgb_led_pwm_init(void)

/** * @brief 设置PWM占空比 */
static void rgb_led_set_pwm(rgb_color_conf *color)

/** * @brief 清空PWM(灭灯) */
static void rgb_led_clear_pwm(void)

/** * @brief 呼吸渐变控制 */
static void rgb_led_breath_fade(led_work_mode fade_mode) 

/** * @brief 软件定时器回调函数 */
static void led_timer_callback(TimerHandle_t xTimer)

对外接口

/**
 * @brief 切换LED工作模式
 * @param mode 目标模式
 * @return 0:成功, -1:参数非法
 */
int set_rgb_led_mode(led_work_mode mode)

/**
  * @brief 设置自定义颜色
  * @param r/g/b 亮度(0-255)
  * @return 0:成功
  */
int set_rgb_led_custom_color(uint8_t r, uint8_t g, uint8_t b)

/**
  * @brief 设置预设颜色
  * @param color 预设枚举
  * @return 0:成功, -1:参数非法
  */
int set_rgb_led_color(G_COLOR color)

/**
  * @brief 设置闪烁参数
  * @param period_ms 总周期(≥10ms)
  * @param on_per 占空比(0-100%
  * @return 0:成功, -1:参数非法
  */
int set_rgb_led_blink_param(uint16_t period_ms, uint8_t on_per)

/**
  * @brief 设置呼吸灯参数 * @param period_ms 渐变时长(≥500ms)
  * @param max_bright 最大亮度(0-255)
  * @return 0:成功, -1:参数非法
  */
int set_rgb_led_breath_param(uint16_t period_ms, uint8_t max_bright)

/**
  * @brief 总启停控制(联动低功耗)
  * @param enable true:启用 false:禁用
  * @return 操作后状态 */
bool turn_on_off_led(bool enable)

/**
  * @brief 获取当前模式
  * @return 当前工作模式
  */
led_work_mode get_rgb_led_mode(void) 

接口实现

#include <stdio.h>
/************************* 私有函数 *************************/
/**
  * @brief LEDC定时器启停
  */
static void ledc_timer_control(bool enable)
{
    if (enable)
    {
        ledc_timer_resume(LEDC_MODE, LEDC_TIMER);
    }
    else
    {
        ledc_timer_pause(LEDC_MODE, LEDC_TIMER);
    }
}

/**
  * @brief PWM初始化
  */
static void rgb_led_pwm_init(void)
{
    // LEDC定时器配置
    ledc_timer_config_t ledc_timer =
    {
        .duty_resolution = LEDC_DUTY_RES,
        .freq_hz = LEDC_FREQ_HZ,
        .speed_mode = LEDC_MODE,
        .timer_num = LEDC_TIMER,
        .clk_cfg = LEDC_AUTO_CLK
    };
    ledc_timer_config(&ledc_timer);

    // 通道配置:初始duty=LED_DUTY_OFF(灭灯)
    ledc_channel_config_t ch_r =
    {
        .channel=LEDC_CHANNEL_R, 
        .duty=LED_DUTY_OFF,  // 宏控:灭灯占空比
        .gpio_num=LED_R_IO, 
        .speed_mode=LEDC_MODE, 
        .timer_sel=LEDC_TIMER
    };
    ledc_channel_config_t ch_g =
    {
        .channel=LEDC_CHANNEL_G, 
        .duty=LED_DUTY_OFF,  // 宏控:灭灯占空比
        .gpio_num=LED_G_IO, 
        .speed_mode=LEDC_MODE, 
        .timer_sel=LEDC_TIMER
    };
    ledc_channel_config_t ch_b =
    {
        .channel=LEDC_CHANNEL_B, 
        .duty=LED_DUTY_OFF,  // 宏控:灭灯占空比
        .gpio_num=LED_B_IO, 
        .speed_mode=LEDC_MODE, 
        .timer_sel=LEDC_TIMER
    };
    ledc_channel_config(&ch_r);
    ledc_channel_config(&ch_g);
    ledc_channel_config(&ch_b);

    // 启用渐变功能
    ledc_fade_func_install(0);
}

/**
  * @brief 设置PWM占空比
  */
static void rgb_led_set_pwm(rgb_color_conf *color)
{
    if (!color)
    {
        return;
    }

    uint32_t r_duty = BRIGHTNESS_TO_DUTY(color->red * g_rgb_led_conf.breath_max_bright / 255);
    uint32_t g_duty = BRIGHTNESS_TO_DUTY(color->green * g_rgb_led_conf.breath_max_bright / 255);
    uint32_t b_duty = BRIGHTNESS_TO_DUTY(color->blue * g_rgb_led_conf.breath_max_bright / 255);

    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_R, r_duty);
    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_G, g_duty);
    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_B, b_duty);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_R);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_G);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_B);
}

/**
  * @brief 清空PWM(灭灯)
  */
static void rgb_led_clear_pwm(void)
{
    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_R, LED_DUTY_OFF);
    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_G, LED_DUTY_OFF);
    ledc_set_duty(LEDC_MODE, LEDC_CHANNEL_B, LED_DUTY_OFF);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_R);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_G);
    ledc_update_duty(LEDC_MODE, LEDC_CHANNEL_B);
}

/**
  * @brief 呼吸渐变控制
  */
static void rgb_led_breath_fade(led_work_mode fade_mode)
{
    rgb_color_conf fade_color = g_rgb_led_conf.color;
    fade_color.red = fade_color.red * g_rgb_led_conf.breath_max_bright / 255;
    fade_color.green = fade_color.green * g_rgb_led_conf.breath_max_bright / 255;
    fade_color.blue = fade_color.blue * g_rgb_led_conf.breath_max_bright / 255;

    if (fade_mode == LED_MODE_BREATH_UP)
    {
        // 渐强:0→最大亮度 → 宏控占空比映射
        uint32_t r_duty = BRIGHTNESS_TO_DUTY(fade_color.red);
        uint32_t g_duty = BRIGHTNESS_TO_DUTY(fade_color.green);
        uint32_t b_duty = BRIGHTNESS_TO_DUTY(fade_color.blue);
        ledc_set_fade_time_and_start(LEDC_MODE, LEDC_CHANNEL_R, r_duty, g_rgb_led_conf.total_period_ms, LEDC_FADE_NO_WAIT);
        ledc_set_fade_time_and_start(LEDC_MODE, LEDC_CHANNEL_G, g_duty, g_rgb_led_conf.total_period_ms, LEDC_FADE_NO_WAIT);
        ledc_set_fade_time_and_start(LEDC_MODE, LEDC_CHANNEL_B, b_duty, g_rgb_led_conf.total_period_ms, LEDC_FADE_NO_WAIT);
    }
    else
    {
        // 渐弱:最大亮度→0 → 宏控灭灯占空比
        ledc_set_fade_time_and_start(LEDC_MODE, LEDC_CHANNEL_R, LED_DUTY_OFF, g_rgb_led_conf.total_period_ms, LEDC_FADE_NO_WAIT);
        ledc_set_fade_time_and_start(LEDC_MODE, LEDC_CHANNEL_G, LED_DUTY_OFF, g_rgb_led_conf.total_period_ms, LEDC_FADE_NO_WAIT);
        ledc_set_fade_time_and_start(LEDC_MODE, LEDC_CHANNEL_B, LED_DUTY_OFF, g_rgb_led_conf.total_period_ms, LEDC_FADE_NO_WAIT);
    }
}

/**
 * 定时器回调
 */
static void led_timer_callback(TimerHandle_t xTimer)
{
    if (!g_rgb_led_conf.led_turn_on)
    {
        return;
    }

    switch (g_rgb_led_conf.work_mode)
    {
        case LED_MODE_ON:
            rgb_led_set_pwm(&g_rgb_led_conf.color);
            break;

        case LED_MODE_BLINK:
            if (g_rgb_led_conf.run_state == LED_STATE_BLINK_ON)
            {
                rgb_led_set_pwm(&g_rgb_led_conf.color);
                g_rgb_led_conf.run_state = LED_STATE_BLINK_OFF;
                xTimerChangePeriod(xTimer, 
                pdMS_TO_TICKS(g_rgb_led_conf.total_period_ms - (g_rgb_led_conf.total_period_ms * g_rgb_led_conf.turn_on_per / 100)), 0);
            }
            else
            {
                rgb_led_clear_pwm();
                g_rgb_led_conf.run_state = LED_STATE_BLINK_ON;
                xTimerChangePeriod(xTimer, 
                    pdMS_TO_TICKS(g_rgb_led_conf.total_period_ms * g_rgb_led_conf.turn_on_per / 100), 0);
            }
            break;

        case LED_MODE_BREATH_UP:
            rgb_led_breath_fade(LED_MODE_BREATH_UP);
            break;

        case LED_MODE_BREATH_DOWN:
            rgb_led_breath_fade(LED_MODE_BREATH_DOWN);
            break;

        default:
            rgb_led_clear_pwm();
            break;
    }
}
/************************* 对外接口 *************************/
/**
 * @brief 切换LED工作模式
 * @param mode 目标模式
 * @return 0:成功, -1:参数非法
 */
int set_rgb_led_mode(led_work_mode mode)
{
    if (mode >= LED_MODE_MAX || !g_rgb_led_conf.led_timer)
    {
        return -1;
    }

    g_rgb_led_conf.work_mode = mode;
    g_rgb_led_conf.run_state = LED_STATE_IDLE;

    switch (mode)
    {
        case LED_MODE_ON:
            xTimerChangePeriod(g_rgb_led_conf.led_timer, pdMS_TO_TICKS(100), 0);
            break;
        case LED_MODE_OFF:
            xTimerStop(g_rgb_led_conf.led_timer, 0);
            rgb_led_clear_pwm();
            ledc_timer_control(false);
            return 0;
        case LED_MODE_BLINK:
            g_rgb_led_conf.run_state = LED_STATE_BLINK_ON;
            xTimerChangePeriod(g_rgb_led_conf.led_timer, 
                pdMS_TO_TICKS(g_rgb_led_conf.total_period_ms * g_rgb_led_conf.turn_on_per / 100), 0);
            break;
        case LED_MODE_BREATH_UP:
        case LED_MODE_BREATH_DOWN:
            g_rgb_led_conf.run_state = 
            (mode == LED_MODE_BREATH_UP) ? LED_STATE_BREATH_UP : LED_STATE_BREATH_DOWN;
            xTimerChangePeriod(g_rgb_led_conf.led_timer, pdMS_TO_TICKS(g_rgb_led_conf.total_period_ms), 0);
            break;
        default:
            break;
    }

    if (g_rgb_led_conf.led_turn_on)
    {
        ledc_timer_control(true);
        xTimerStart(g_rgb_led_conf.led_timer, 0);
    }
    return 0;
}

/**
  * @brief 设置自定义颜色
  * @param r/g/b 亮度(0-255)
  * @return 0:成功
  */
int set_rgb_led_custom_color(uint8_t r, uint8_t g, uint8_t b)
{
    g_rgb_led_conf.color.red = r > 255 ? 255 : r;
    g_rgb_led_conf.color.green = g > 255 ? 255 : g;
    g_rgb_led_conf.color.blue = b > 255 ? 255 : b;

    if (g_rgb_led_conf.led_turn_on && g_rgb_led_conf.work_mode == LED_MODE_ON)
    {
        rgb_led_set_pwm(&g_rgb_led_conf.color);
    }
    return 0;
}

/**
  * @brief 设置预设颜色
  * @param color 预设枚举
  * @return 0:成功, -1:参数非法
  */
int set_rgb_led_color(G_COLOR color)
{
    if (color >= G_COLOR_MAX)
    {
        return -1;
    }
    g_rgb_led_conf.color = g_rgb_color_list[color];
    
    if (g_rgb_led_conf.led_turn_on && g_rgb_led_conf.work_mode == LED_MODE_ON)
    {
        rgb_led_set_pwm(&g_rgb_led_conf.color);
    }
    return 0;
}

/**
  * @brief 设置闪烁参数
  * @param period_ms 总周期(≥10ms)
  * @param on_per 占空比(0-100%
  * @return 0:成功, -1:参数非法
  */
int set_rgb_led_blink_param(uint16_t period_ms, uint8_t on_per)
{
    if (period_ms < 10 || on_per > 100)
    {
        return -1;
    }
    g_rgb_led_conf.total_period_ms = period_ms;
    g_rgb_led_conf.turn_on_per = on_per;

    if (g_rgb_led_conf.work_mode == LED_MODE_BLINK && g_rgb_led_conf.led_turn_on)
    {
        set_rgb_led_mode(LED_MODE_BLINK);
    }
    return 0;
}

/**
  * @brief 设置呼吸灯参数 * @param period_ms 渐变时长(≥500ms)
  * @param max_bright 最大亮度(0-255)
  * @return 0:成功, -1:参数非法
  */
int set_rgb_led_breath_param(uint16_t period_ms, uint8_t max_bright)
{
    if (period_ms < 500 || max_bright > 255)
    {
        return -1;
    }
    g_rgb_led_conf.total_period_ms = period_ms;
    g_rgb_led_conf.breath_max_bright = max_bright;

    if ((g_rgb_led_conf.work_mode == LED_MODE_BREATH_UP
        || g_rgb_led_conf.work_mode == LED_MODE_BREATH_DOWN)
        && g_rgb_led_conf.led_turn_on)
    {
        set_rgb_led_mode(g_rgb_led_conf.work_mode);
    }
    return 0;
}

/**
  * @brief 总启停控制
  * @param enable true:启用 false:禁用
  * @return 操作后状态 */
bool turn_on_off_led(bool enable)
{
    g_rgb_led_conf.led_turn_on = enable;
    if (enable)
    {
        ledc_timer_control(true);
        set_rgb_led_mode(g_rgb_led_conf.work_mode);
    }
    else
    {
        xTimerStop(g_rgb_led_conf.led_timer, 0);
        rgb_led_clear_pwm();
        ledc_timer_control(false);
    }
    return enable;
}

/**
  * @brief 获取当前模式
  * @return 当前工作模式
  */
led_work_mode get_rgb_led_mode(void) 
{
    return g_rgb_led_conf.work_mode;
}

/************************* 初始化 *************************/
void rgb_led_init(void)
{
    rgb_led_pwm_init();

    g_rgb_led_conf.led_timer = xTimerCreate(
        "led_timer",
        pdMS_TO_TICKS(100),
        pdTRUE,
        NULL,
        led_timer_callback
    );

    if (g_rgb_led_conf.led_timer)
    {
        xTimerStop(g_rgb_led_conf.led_timer, 0);
    }
    ledc_timer_control(false);
}

Demo进程

#include <stdio.h>
#include "RGBLED.h"

void app_main(void)
{
    rgb_led_init();
    turn_on_off_led(true);
    set_rgb_led_custom_color(0, 0, 255);
    set_rgb_led_mode(LED_MODE_BLINK);
    set_rgb_led_blink_param(1000, 50);
    vTaskDelay(pdMS_TO_TICKS(5000));
    set_rgb_led_mode(LED_MODE_OFF);
    turn_on_off_led(false);
    while (1)
    {
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

应用场景

不同颜色的LED代表当前不同阶段,比如wifi连接时/系统启动等

代码获取

https://download.youkuaiyun.com/download/stuinxdu/92479470

### 实现ESP32-S3上的RGB显示 对于ESP32-S3设备而言,在其上实现RGB显示通常涉及到特定显示屏驱动程序的使用以及图形库的支持。当目标显示器为GC9A01,并采用VS Code配合PlatformIO和Arduino框架作为开发环境时,可以利用LVGL库来简化GUI应用的创建过程[^2]。 #### LVGL库简介 LVGL (Light and Versatile Graphics Library) 是一款轻量级且功能丰富的嵌入式图形界面库,专为资源受限的微控制器设计。该库提供了多种控件组件,如按钮、滑块、图表等,支持多样的视觉效果与交互操作,非常适合用于构建精美的用户界面。通过集成LVGL到项目中,开发者能够快速搭建起直观易用的应用程序前端。 #### 配置平台与依赖项 为了使ESP32-S3能顺利运行带有RGB显示功能的应用程序,需先设置好相应的编译器选项: ```ini ; platformio.ini 文件中的配置片段 [env:esp32-s3-devkitc-1] platform = espressif32 board = esp32-s3-devkitc-1 framework = arduino lib_deps = lvgl/lvgl @ ^8.1.0 TFT_eSPI/TFT_eSPI@^1.7.4 ``` 上述代码展示了如何指定所需的硬件板子型号及其对应的软件栈版本号;同时指定了两个主要外部库——LVGL本身及TFT_eSPI屏幕控制库。这一步骤确保了后续编码阶段拥有必要的工具集来进行高效开发。 #### 初始化显示并绘制简单图案 下面给出了一段简单的C++源码示例,它演示了怎样初始化连接至ESP32-S3的GC9A01屏,并在其上面画出彩色矩形框: ```cpp #include "lvgl/lvgl.h" #include "TFT_eSPI.h" // 创建全局对象实例化TFT类 TFT_eSPI tft; void setup() { Serial.begin(115200); // 启动TFT SPI接口 tft.init(); // 设置背景颜色为黑色 tft.fillScreen(TFT_BLACK); // 初始化LVGL库 lv_init(); // 将TFT_eSPI适配给LVGL底层绘图引擎 static lv_disp_draw_buf_t draw_buf; static lv_color_t buf[LV_HOR_RES_MAX * 10]; lv_disp_draw_buf_init(&draw_buf, buf, NULL, LV_HOR_RES_MAX * 10); static lv_disp_drv_t disp_drv; lv_disp_drv_init(&disp_drv); disp_drv.flush_cb = my_disp_flush; disp_drv.draw_buf = &draw_buf; lv_disp_drv_register(&disp_drv); } void loop() { // 绘制红色填充矩形 lv_obj_t* rect1 = lv_rect_create(lv_scr_act()); lv_obj_set_size(rect1, 100, 50); /*Set the size*/ lv_obj_center(rect1); /*Align to the center of the parent (screen)*/ lv_obj_set_style_bg_color(rect1, lv_color_hex(0xFF0000), LV_PART_MAIN | LV_STATE_DEFAULT); while(true){ lv_task_handler(); /*Let the GUI do its tasks*/ delay(5); } } ``` 此脚本首先完成了对物理层面上LCD面板的基础设定工作,接着调用了LVGL API函数完成了一个静态UI元素(即一个红底方块)的渲染任务。值得注意的是,这里定义了一个无限循环用来持续处理来自LVGL的任务队列更新请求,从而保持画面流畅刷新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值