0、前期準(zhǔn)備
1、參考上一篇文章搭建好esp32環(huán)境
2、準(zhǔn)備好一塊esp32開(kāi)發(fā)開(kāi)發(fā)板(本作者使用了esp32c3作為開(kāi)發(fā)平臺(tái))
1、知識(shí)儲(chǔ)備
1.1 概述
? LEDC是樂(lè)鑫公司專門(mén)開(kāi)發(fā),通過(guò)PWM來(lái)控制LED,具有軟件控制占空比以及硬件自動(dòng)控制占空比的方式。同時(shí)據(jù)說(shuō)也可以用來(lái)控制電機(jī)。
1.2 功能架構(gòu)
LEDC有4個(gè)定時(shí)器可以獨(dú)立配置,定時(shí)器時(shí)鐘來(lái)源有三個(gè)時(shí)鐘源,分別是:APB_CLK、RC_FAST_CLK 和 XTAL_CLK。
架構(gòu)圖如下所示:
1.3 LEDC配置流程介紹
LEDC的配置流程可分為以下3步
1、定時(shí)器配置:設(shè)置PWM 頻率和占空比分辨率(位數(shù))
2、通道配置:設(shè)置定時(shí)器通道以及PWM的輸出引腳
3、 修改占空比
1、定時(shí)器配置
定時(shí)器的配置主要是給 ledc_timer_config_t 結(jié)構(gòu)體賦值,然后通過(guò)ledc_timer_config函數(shù)進(jìn)行對(duì)定時(shí)器設(shè)置
以下對(duì)ledc_timer_config_t 結(jié)構(gòu)體進(jìn)行說(shuō)明
typedef struct {
ledc_mode_t speed_mode; // ledc速度模式:LEDC_HIGH_SPEED_MODE和LEDC_LOW_SPEED_MODE
union {
ledc_timer_bit_t duty_resolution; //占空比的分分辨率
ledc_timer_bit_t bit_num __attribute__((deprecated)); //esp-idf 3.1以上已經(jīng)使用該參數(shù)
};
ledc_timer_t timer_num; //定時(shí)器編號(hào)
uint32_t freq_hz; //pwm頻率
ledc_clk_cfg_t clk_cfg; //時(shí)鐘源:
} ledc_timer_config_t;
例子:
// 定時(shí)器配置
ledc_timer_config_t ledcTimerConfig = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_13_BIT,
.clk_cfg = LEDC_AUTO_CLK,
.freq_hz = 5000,
.timer_num = LEDC_TIMER_0,
};
ledc_timer_config(&ledcTimerConfig);
2、通道配置
通道的配置主要是給 ledc_channel_config_t 結(jié)構(gòu)體賦值,然后通過(guò)ledc_channel_config函數(shù)進(jìn)行通道設(shè)置。
以下對(duì)ledc_channel_config_t 結(jié)構(gòu)體進(jìn)行說(shuō)明
typedef struct {
int gpio_num;//輸出pwm的gpio口
ledc_mode_t speed_mode// ledc速度模式:LEDC_HIGH_SPEED_MODE和LEDC_LOW_SPEED_MODE
ledc_channel_t channel; // ledc的輸出通道:
ledc_intr_type_t intr_type; //是否使能中斷,如果使能中斷之后,需要使用ledc_isr_register函數(shù),進(jìn)行中斷注冊(cè),在漸變完成之后,就會(huì)調(diào)用中斷函數(shù)
ledc_timer_t timer_sel;//設(shè)置使用哪一個(gè)定時(shí)器,需要和ledc_timer_config_t配置的一致
uint32_t duty;//占空比
int hpoint;//上升沿出現(xiàn)的位置,一般設(shè)置為0,最大值為0xfffff
struct {
unsigned int output_invert: 1;//電平是否翻轉(zhuǎn),1:0- >1, 0:1- >0
} flags;
} ledc_channel_config_t;
例子:
// 通道配置
ledc_channel_config_t ledcChannelConfig = {
.gpio_num = GPIO_NUM_14,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER_0,
.duty = 0,
.hpoint = 0,
.flags.output_invert = 0,
};
ledc_channel_config(&ledcChannelConfig);
3、 修改占空比
ledc占空比可以通過(guò),軟件和硬件兩個(gè)方式進(jìn)行設(shè)置。
軟件方式:主要涉及了ledc_set_duty和ledc_update_duty兩個(gè)函數(shù),其中
ledc_set_duty:用來(lái)設(shè)置占空比
ledc_update_duty:使設(shè)置生效,
函數(shù)參數(shù)說(shuō)明如下:
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
//參數(shù):speed_mode:ledc速度模式,要和ledc_channel_config_t的speed_mode保持一致
// channel:通道,要和ledc_channel_config_t的channel保持一致
// duty:占空比,取值范圍:0 ~ (2^duty_resolution) - 1
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
//參數(shù):speed_mode:ledc速度模式,要和ledc_channel_config_t的speed_mode保持一致
// channel:通道,要和ledc_channel_config_t的channel保持一致
硬件方式:主要涉及到了ledc_fade_func_install、ledc_set_fade_with_step、ledc_set_fade_with_time和ledc_fade_start幾個(gè)函數(shù),其中
ledc_fade_func_install:用來(lái)使能硬件,使得硬件能夠改變占空比,
ledc_set_fade_with_step:用于設(shè)置漸變的步長(zhǎng)
ledc_set_fade_with_time:用于設(shè)置漸變到某一個(gè)值,一般ledc_set_fade_with_step和ledc_set_fade_with_time使用其中一個(gè)即可
ledc_fade_start:開(kāi)始漸變
(注意:ledc_set_fade_with_time和ledc_fade_start不是線程安全的,不要在不同的任務(wù)中同時(shí)調(diào)用這些函數(shù)來(lái)控制一個(gè)ledc通道,API的線程安全版本是ledc_set_fade_step_and_start)
函數(shù)參數(shù)說(shuō)明如下:
esp_err_t ledc_fade_func_install(int intr_alloc_flags);
//參數(shù):intr_alloc_flags:用于分配中斷的標(biāo)志,一般填0即可
esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t scale, uint32_t cycle_num);
// 參數(shù) :speed_mode:ledc速度模式,要和ledc_channel_config_t的speed_mode保持一致
// channel:通道,要和ledc_channel_config_t的channel保持一致
// target_duty: 目標(biāo)占空比,取值范圍:0 ~ (2^duty_resolution) - 1
// scale:控制增加或減少步長(zhǎng)比例。
// cycle_num:每cycle_num個(gè)周期增加或減少占空比
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int max_fade_time_ms);
// 參數(shù) :speed_mode:ledc速度模式,要和ledc_channel_config_t的speed_mode保持一致
// channel:通道,要和ledc_channel_config_t的channel保持一致
// target_duty: 目標(biāo)占空比,取值范圍:0 ~ (2^duty_resolution) - 1
// max_fade_time_ms:減到目標(biāo)占空比花費(fèi)的時(shí)間
esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_fade_mode_t fade_mode);
// 參數(shù) :speed_mode:ledc速度模式,要和ledc_channel_config_t的speed_mode保持一致
// channel:通道,要和ledc_channel_config_t的channel保持一致
// fade_mode: 漸變模式,阻塞(LEDC_FADE_WAIT_DONE)和非阻塞(LEDC_FADE_NO_WAIT)
2、新建工程
idf.py create-project project_led # 新建工程
cd project_led
idf.py set-target esp32c3 # 設(shè)置工程使用的芯片
2、查看原理圖確定按鍵控制引腳
3、編寫(xiě)程序
本例子是使用軟件,配置占空比方式,有興趣的小伙伴可以嘗試使用硬件方式
#include
#include
#include
#include
void app_main(void) {
// 定時(shí)器配置
ledc_timer_config_t ledcTimerConfig = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_13_BIT,
.clk_cfg = LEDC_AUTO_CLK,
.freq_hz = 5000,
.timer_num = LEDC_TIMER_0,
};
ledc_timer_config(&ledcTimerConfig);
// 通道配置
ledc_channel_config_t ledcChannelConfig = {
.gpio_num = GPIO_NUM_5,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.intr_type = LEDC_INTR_DISABLE,
.timer_sel = LEDC_TIMER_0,
.duty = 0,
.hpoint = 0,
.flags.output_invert = 0,
};
ledc_channel_config(&ledcChannelConfig);
float duty_num = 0;
int der = 1;
while (pdTRUE) {
ledc_set_duty(LEDC_LOW_SPEED_MODE,LEDC_CHANNEL_0,(int)(8191*(duty_num/200)));
ledc_update_duty(LEDC_LOW_SPEED_MODE,LEDC_CHANNEL_0);
if(duty_num == 200)
der = 0;
else if(duty_num == 0)
der = 1;
if (der == 1)
duty_num +=1;
else
duty_num -=1;
vTaskDelay(10/portTICK_PERIOD_MS);
}
}
4、編譯下載
#編譯
idf.py build
#燒錄以及查看日志,使用ctrl+] 可以退出監(jiān)視窗口
idf.py -p /dev/ttyUSB0 flash monitor
審核編輯:湯梓紅
-
led
+關(guān)注
關(guān)注
242文章
23375瀏覽量
663387 -
PWM
+關(guān)注
關(guān)注
114文章
5199瀏覽量
214928 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3256瀏覽量
115407 -
開(kāi)發(fā)板
+關(guān)注
關(guān)注
25文章
5125瀏覽量
98277 -
ESP32
+關(guān)注
關(guān)注
18文章
980瀏覽量
17545
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論