mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
Merge branch 'bugfix/clear_ledc_gamma_ram_v5.2' into 'release/v5.2'
fix(ledc): left-off gamma ram registers should be cleared (v5.2) See merge request espressif/esp-idf!37574
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -439,7 +439,18 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel
|
||||
* @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
|
||||
* @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
|
||||
* @param target_duty Target duty of fading [0, (2**duty_resolution)]
|
||||
* @param max_fade_time_ms The maximum time of the fading ( ms ).
|
||||
* @param desired_fade_time_ms The intended time of the fading ( ms ).
|
||||
* Note that the actual time it takes to complete the fade could vary by a factor of up to 2x shorter
|
||||
* or longer than the expected time due to internal rounding errors in calculations.
|
||||
* Specifically:
|
||||
* * The total number of cycles (total_cycle_num = desired_fade_time_ms * freq / 1000)
|
||||
* * The difference in duty cycle (duty_delta = |target_duty - current_duty|)
|
||||
* The fade may complete faster than expected if total_cycle_num larger than duty_delta. Conversely,
|
||||
* it may take longer than expected if total_cycle_num is less than duty_delta.
|
||||
* The closer the ratio of total_cycle_num/duty_delta (or its inverse) is to a whole number (the floor value),
|
||||
* the more accurately the actual fade duration will match the intended time.
|
||||
* If an exact fade time is expected, please consider to split the entire fade into several smaller linear fades.
|
||||
* The split should make each fade step has a divisible total_cycle_num/duty_delta (or its inverse) ratio.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
@ -447,7 +458,7 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel
|
||||
* - ESP_ERR_INVALID_STATE Channel not initialized
|
||||
* - ESP_FAIL Fade function init error
|
||||
*/
|
||||
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);
|
||||
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms);
|
||||
|
||||
/**
|
||||
* @brief Install LEDC fade function. This function will occupy interrupt of LEDC module.
|
||||
@ -538,7 +549,18 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe
|
||||
* @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
|
||||
* @param channel LEDC channel index (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
|
||||
* @param target_duty Target duty of fading [0, (2**duty_resolution)]
|
||||
* @param max_fade_time_ms The maximum time of the fading ( ms ).
|
||||
* @param desired_fade_time_ms The intended time of the fading ( ms ).
|
||||
* Note that the actual time it takes to complete the fade could vary by a factor of up to 2x shorter
|
||||
* or longer than the expected time due to internal rounding errors in calculations.
|
||||
* Specifically:
|
||||
* * The total number of cycles (total_cycle_num = desired_fade_time_ms * freq / 1000)
|
||||
* * The difference in duty cycle (duty_delta = |target_duty - current_duty|)
|
||||
* The fade may complete faster than expected if total_cycle_num larger than duty_delta. Conversely,
|
||||
* it may take longer than expected if total_cycle_num is less than duty_delta.
|
||||
* The closer the ratio of total_cycle_num/duty_delta (or its inverse) is to a whole number (the floor value),
|
||||
* the more accurately the actual fade duration will match the intended time.
|
||||
* If an exact fade time is expected, please consider to split the entire fade into several smaller linear fades.
|
||||
* The split should make each fade step has a divisible total_cycle_num/duty_delta (or its inverse) ratio.
|
||||
* @param fade_mode choose blocking or non-blocking mode
|
||||
*
|
||||
* @return
|
||||
@ -547,7 +569,7 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe
|
||||
* - ESP_ERR_INVALID_STATE Channel not initialized
|
||||
* - ESP_FAIL Fade function init error
|
||||
*/
|
||||
esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t max_fade_time_ms, ledc_fade_mode_t fade_mode);
|
||||
esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t desired_fade_time_ms, ledc_fade_mode_t fade_mode);
|
||||
|
||||
/**
|
||||
* @brief A thread-safe API to set and start LEDC fade function.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -232,6 +232,8 @@ int duty_val, ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t
|
||||
ledc_hal_set_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 0, duty_direction, duty_cycle, duty_scale, duty_num);
|
||||
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
|
||||
ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1);
|
||||
// Clear left-off LEDC gamma ram registers, random data in ram could cause output waveform error
|
||||
ledc_hal_clear_left_off_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1);
|
||||
#endif
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -303,16 +305,20 @@ static bool ledc_speed_mode_ctx_create(ledc_mode_t speed_mode)
|
||||
ledc_obj_t *ledc_new_mode_obj = (ledc_obj_t *) heap_caps_calloc(1, sizeof(ledc_obj_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (ledc_new_mode_obj) {
|
||||
new_ctx = true;
|
||||
LEDC_BUS_CLOCK_ATOMIC() {
|
||||
ledc_ll_enable_bus_clock(true);
|
||||
ledc_ll_enable_reset_reg(false);
|
||||
}
|
||||
// Enable core clock gating at early stage, some LEDC registers and gamma RAM rely on the LEDC core clock existence
|
||||
LEDC_FUNC_CLOCK_ATOMIC() {
|
||||
ledc_ll_enable_clock(LEDC_LL_GET_HW(), true);
|
||||
}
|
||||
ledc_hal_init(&(ledc_new_mode_obj->ledc_hal), speed_mode);
|
||||
ledc_new_mode_obj->glb_clk = LEDC_SLOW_CLK_UNINIT;
|
||||
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
|
||||
memset(ledc_new_mode_obj->timer_specific_clk, LEDC_TIMER_SPECIFIC_CLK_UNINIT, sizeof(ledc_clk_src_t) * LEDC_TIMER_MAX);
|
||||
#endif
|
||||
p_ledc_obj[speed_mode] = ledc_new_mode_obj;
|
||||
LEDC_BUS_CLOCK_ATOMIC() {
|
||||
ledc_ll_enable_bus_clock(true);
|
||||
ledc_ll_enable_reset_reg(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
_lock_release(&s_ledc_mutex[speed_mode]);
|
||||
@ -563,7 +569,6 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
|
||||
// TODO: release old glb_clk (if not UNINIT), and acquire new glb_clk [clk_tree]
|
||||
p_ledc_obj[speed_mode]->glb_clk = glb_clk;
|
||||
LEDC_FUNC_CLOCK_ATOMIC() {
|
||||
ledc_ll_enable_clock(p_ledc_obj[speed_mode]->ledc_hal.dev, true);
|
||||
ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk);
|
||||
}
|
||||
}
|
||||
@ -692,7 +697,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
|
||||
/*set channel parameters*/
|
||||
/* channel parameters decide how the waveform looks like in one period */
|
||||
/* set channel duty and hpoint value, duty range is [0, (2**duty_res)], hpoint range is [0, (2**duty_res)-1] */
|
||||
/* Note: On ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2, ESP32P4, due to a hardware bug,
|
||||
/* Note: On ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2 (rev < 1.2), ESP32P4, due to a hardware bug,
|
||||
* 100% duty cycle (i.e. 2**duty_res) is not reachable when the binded timer selects the maximum duty
|
||||
* resolution. For example, the max duty resolution on ESP32C3 is 14-bit width, then set duty to (2**14)
|
||||
* will mess up the duty calculation in hardware.
|
||||
@ -1120,7 +1125,7 @@ static esp_err_t _ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static 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)
|
||||
static esp_err_t _ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms)
|
||||
{
|
||||
ledc_timer_t timer_sel;
|
||||
uint32_t duty_cur = 0;
|
||||
@ -1132,7 +1137,7 @@ static esp_err_t _ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t
|
||||
if (duty_delta == 0) {
|
||||
return _ledc_set_fade_with_step(speed_mode, channel, target_duty, 0, 0);
|
||||
}
|
||||
uint32_t total_cycles = max_fade_time_ms * freq / 1000;
|
||||
uint32_t total_cycles = desired_fade_time_ms * freq / 1000;
|
||||
if (total_cycles == 0) {
|
||||
ESP_LOGW(LEDC_TAG, LEDC_FADE_TOO_FAST_STR);
|
||||
return _ledc_set_fade_with_step(speed_mode, channel, target_duty, 0, 0);
|
||||
@ -1179,7 +1184,7 @@ static void _ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, led
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, int desired_fade_time_ms)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
@ -1188,7 +1193,7 @@ esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel
|
||||
LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK, LEDC_FADE_INIT_ERROR_STR, ESP_FAIL);
|
||||
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
_ledc_set_fade_with_time(speed_mode, channel, target_duty, max_fade_time_ms);
|
||||
_ledc_set_fade_with_time(speed_mode, channel, target_duty, desired_fade_time_ms);
|
||||
_ledc_fade_hw_release(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -1332,7 +1337,7 @@ esp_err_t ledc_set_duty_and_update(ledc_mode_t speed_mode, ledc_channel_t channe
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t max_fade_time_ms, ledc_fade_mode_t fade_mode)
|
||||
esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t target_duty, uint32_t desired_fade_time_ms, ledc_fade_mode_t fade_mode)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
@ -1342,7 +1347,7 @@ esp_err_t ledc_set_fade_time_and_start(ledc_mode_t speed_mode, ledc_channel_t ch
|
||||
LEDC_ARG_CHECK(target_duty <= ledc_get_max_duty(speed_mode, channel), "target_duty");
|
||||
_ledc_op_lock_acquire(speed_mode, channel);
|
||||
_ledc_fade_hw_acquire(speed_mode, channel);
|
||||
_ledc_set_fade_with_time(speed_mode, channel, target_duty, max_fade_time_ms);
|
||||
_ledc_set_fade_with_time(speed_mode, channel, target_duty, desired_fade_time_ms);
|
||||
_ledc_fade_start(speed_mode, channel, fade_mode);
|
||||
_ledc_op_lock_release(speed_mode, channel);
|
||||
return ESP_OK;
|
||||
@ -1378,6 +1383,8 @@ static esp_err_t _ledc_set_multi_fade(ledc_mode_t speed_mode, ledc_channel_t cha
|
||||
ledc_hal_set_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, i, fade_param.dir, fade_param.cycle_num, fade_param.scale, fade_param.step_num);
|
||||
}
|
||||
ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, list_len);
|
||||
// Clear left-off LEDC gamma ram registers, random data in ram could cause output waveform error
|
||||
ledc_hal_clear_left_off_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, list_len);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
// Calculate target duty, and take account for overflow
|
||||
uint32_t target_duty = start_duty;
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/assert.h"
|
||||
#include "esp_rom_sys.h" //for sync issue workaround
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -442,6 +443,7 @@ static inline void ledc_ll_set_duty_range_wr_addr(ledc_dev_t *hw, ledc_mode_t sp
|
||||
*/
|
||||
static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint8_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
|
||||
{
|
||||
HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX);
|
||||
// To workaround sync issue
|
||||
// This is to ensure the fade param write to the gamma_wr register would not mess up the last wr_addr
|
||||
ledc_ll_set_duty_range_wr_addr(hw, speed_mode, channel_num, range);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "hal/assert.h"
|
||||
#include "esp_rom_sys.h" //for sync issue workaround
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -440,6 +441,7 @@ static inline void ledc_ll_set_duty_range_wr_addr(ledc_dev_t *hw, ledc_mode_t sp
|
||||
*/
|
||||
static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint8_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
|
||||
{
|
||||
HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX);
|
||||
// To workaround sync issue
|
||||
// This is to ensure the fade param write to the gamma_wr register would not mess up the last wr_addr
|
||||
ledc_ll_set_duty_range_wr_addr(hw, speed_mode, channel_num, range);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -372,6 +373,7 @@ static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc
|
||||
*/
|
||||
static inline void ledc_ll_set_fade_param_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint8_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
|
||||
{
|
||||
HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX);
|
||||
ledc_channel_gamma_fade_param_t range_param = {
|
||||
.duty_inc = dir,
|
||||
.duty_cycle = cycle,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -365,6 +365,15 @@ void ledc_hal_get_range_number(ledc_hal_context_t *hal, ledc_channel_t channel_n
|
||||
* @return None
|
||||
*/
|
||||
void ledc_hal_get_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step);
|
||||
|
||||
/**
|
||||
* @brief Clear left-off range fade parameters in LEDC gamma ram
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param channel_num LEDC channel index, select from ledc_channel_t
|
||||
* @param start_range Start of the range to clear
|
||||
*/
|
||||
void ledc_hal_clear_left_off_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t start_range);
|
||||
#endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
|
||||
|
||||
/**
|
||||
|
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// The HAL layer for LEDC (common part, in iram)
|
||||
// make these functions in a seperate file to make sure all LL functions are in the IRAM.
|
||||
// make these functions in a separate file to make sure all LL functions are in the IRAM.
|
||||
|
||||
#include "hal/ledc_hal.h"
|
||||
#include "hal/assert.h"
|
||||
@ -39,7 +39,6 @@ void ledc_hal_get_duty(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint
|
||||
void ledc_hal_set_fade_param(const ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
|
||||
{
|
||||
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
|
||||
HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX);
|
||||
ledc_ll_set_fade_param_range(hal->dev, hal->speed_mode, channel_num, range, dir, cycle, scale, step);
|
||||
#else // !SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
|
||||
HAL_ASSERT(range == 0);
|
||||
@ -58,6 +57,13 @@ void ledc_hal_get_range_number(ledc_hal_context_t *hal, ledc_channel_t channel_n
|
||||
{
|
||||
ledc_ll_get_range_number(hal->dev, hal->speed_mode, channel_num, range_num);
|
||||
}
|
||||
|
||||
void ledc_hal_clear_left_off_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t start_range)
|
||||
{
|
||||
for (int i = start_range; i < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX; i++) {
|
||||
ledc_ll_set_fade_param_range(hal->dev, hal->speed_mode, channel_num, i, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
#endif //SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
|
||||
|
||||
void ledc_hal_get_fade_end_intr_status(ledc_hal_context_t *hal, uint32_t *intr_status)
|
||||
|
@ -256,6 +256,10 @@ The range of the duty cycle values passed to functions depends on selected ``dut
|
||||
|
||||
On {IDF_TARGET_NAME}, when channel's binded timer selects its maximum duty resolution, the duty cycle value cannot be set to ``(2 ** duty_resolution)``. Otherwise, the internal duty counter in the hardware will overflow and be messed up.
|
||||
|
||||
.. only:: esp32h2
|
||||
|
||||
The hardware limitation above only applies to chip revision before v1.2.
|
||||
|
||||
|
||||
Change PWM Duty Cycle Using Hardware
|
||||
""""""""""""""""""""""""""""""""""""
|
||||
|
@ -256,6 +256,10 @@ LEDC 驱动提供了一个辅助函数 :cpp:func:`ledc_find_suitable_duty_resolu
|
||||
|
||||
在 {IDF_TARGET_NAME} 上,当通道绑定的定时器配置了其最大 PWM 占空比分辨率( ``MAX_DUTY_RES`` ),通道的占空比不能被设置到 ``(2 ** MAX_DUTY_RES)`` 。否则,硬件内部占空比计数器会溢出,并导致占空比计算错误。
|
||||
|
||||
.. only:: esp32h2
|
||||
|
||||
以上硬件限制仅在芯片版本低于 v1.2 的 ESP32H2 上存在。
|
||||
|
||||
|
||||
使用硬件改变 PWM 占空比
|
||||
""""""""""""""""""""""""""""""""""""
|
||||
|
@ -19,7 +19,7 @@
|
||||
#define LEDC_FREQUENCY (4000) // Frequency in Hertz. Set frequency at 4 kHz
|
||||
|
||||
/* Warning:
|
||||
* For ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2, ESP32P4 targets,
|
||||
* For ESP32, ESP32S2, ESP32S3, ESP32C3, ESP32C2, ESP32C6, ESP32H2 (rev < 1.2), ESP32P4 targets,
|
||||
* when LEDC_DUTY_RES selects the maximum duty resolution (i.e. value equal to SOC_LEDC_TIMER_BIT_WIDTH),
|
||||
* 100% duty cycle is not reachable (duty cannot be set to (2 ** SOC_LEDC_TIMER_BIT_WIDTH)).
|
||||
*/
|
||||
|
Reference in New Issue
Block a user