#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "driver/ledc.h"

#define LED_GPIO GPIO_NUM_4

void led_breath_init(){
    // 定时器配置
    ledc_timer_config_t ledc_timer_structure = {
        .clk_cfg = LEDC_AUTO_CLK,
        .duty_resolution = LEDC_TIMER_12_BIT,
        .freq_hz = 5000,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_num = LEDC_TIMER_0
    };
    ledc_timer_config(&ledc_timer_structure);

    // 通道配置
    ledc_channel_config_t ledc_channel_structure = {
        .channel = LEDC_CHANNEL_0,
        .duty = 0,
        .gpio_num = LED_GPIO,
        .speed_mode = LEDC_LOW_SPEED_MODE,
        .timer_sel = LEDC_TIMER_0
    };
    ledc_channel_config(&ledc_channel_structure);

    // 安装渐变功能
    ledc_fade_func_install(0);
}

void led_breath_task(void* arg){
    while(1) {
        // 从暗到亮 (0 → 4095)
        ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 4095, 2000);
        /*调用ledc_fade_start()函数后,任务会被阻塞2000ms(阻塞态),此时led仍然会完成渐变得益于pwm硬件控制,当完成渐变后会产生中断,RTOS系统会让任务重新恢复成运行态。
*/
        ledc_fade_start(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE);
        
        // 从亮到暗 (4095 → 0)
        ledc_set_fade_with_time(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0, 2000);
        ledc_fade_start(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, LEDC_FADE_WAIT_DONE);
    }
}

void app_main(void)
{
    led_breath_init();
    xTaskCreate(led_breath_task, "led_breath", 2048, NULL, 3, NULL);
    
    while(1) {
        vTaskDelay(pdMS_TO_TICKS(1000)); // 保持调度器运行
    }
}

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐