【esp32】 PWM控制LED亮度原理及代码详解

通俗的解释PWM的原理

PWM:脉冲宽度调制器

比如你有5V电源,要控制一台灯的亮度。你可以用传统的方式,串联一个可调电阻,改变电阻,灯的亮度就会改变。

使用PWM调节的原理:保持一定的电压或者电流不变,改变一定周期内的导通和关断的时间。等效于,保持导通,改变电压或者电流的大小。

【频率控制灯的闪烁:】

相当于串联了一个开关,假设在1s时间内,0.5s打开,0.5s关闭,那么灯亮0.5s,熄灭0.5s,人看到就是灯在闪烁。如果把频率调高,1s改为1ms,0.5ms打开,0.5ms关闭,那么看起来灯的闪烁频率就很高。

【占空比控制灯的亮度:】

当闪烁频率超过一直的阈值时,人眼就感受不到了。比如,在1ms内,0.9ms是关闭的,0.1ms是打开的,那么灯的亮度就只有原来的十分之一了。即通过改变LED的通电时间长短来调节亮度,通电时间长则亮度高。

ESP32-ledc源码分析

参考:ESP32 — LEDC_PWM

占空比:高电平接通时间与周期的比

分辨率:就是占空比的最小值

如代码中设置分辨率为 2**13 次方,则占空比为50%时的数字就是 ,(2**13 - 1)* 50% = 4095

以esp32为例,设置pwm的相关参数:参考库中的 esp-idf-master\examples\peripherals\ledc\ledc_basic\main
在这里插入图片描述
注意:占空比的设置,LEDC_DUTY 和分辨率有关

设置占空比为50%#define LEDC_DUTY (4095) // Set duty to 50%. ((2 ** 13) - 1) * 50% = 4095

#define LEDC_TIMER              LEDC_TIMER_0
#define LEDC_MODE               LEDC_LOW_SPEED_MODE
#define LEDC_OUTPUT_IO          (5) 					// Define the output GPIO
#define LEDC_CHANNEL            LEDC_CHANNEL_0
#define LEDC_DUTY_RES           LEDC_TIMER_13_BIT // Set duty resolution to 13 bits
#define LEDC_DUTY               (4095) // Set duty to 50%. ((2 ** 13) - 1) * 50% = 4095
#define LEDC_FREQUENCY          (5000) // Frequency in Hertz. Set frequency at 5 kHz

static void example_ledc_init(void)
{
    // Prepare and then apply the LEDC PWM timer configuration
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_MODE,
        .timer_num        = LEDC_TIMER,
        .duty_resolution  = LEDC_DUTY_RES,
        .freq_hz          = LEDC_FREQUENCY,  // Set output frequency at 5 kHz
        .clk_cfg          = LEDC_AUTO_CLK
    };
    ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_channel = {
        .speed_mode     = LEDC_MODE,
        .channel        = LEDC_CHANNEL,
        .timer_sel      = LEDC_TIMER,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = LEDC_OUTPUT_IO,
        .duty           = 0, // Set duty to 0%
        .hpoint         = 0
    };
    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}

两路LED以不同频的方式闪烁

拓展:
两路LED以不同频的方式闪烁;代码中不同的GPIO配置不同的定时器和channel,然后设置不同的频率。

现象:
不同频率闪烁


拓展:可以和按键检测结合起来:
短按,实现灯开,再短按一次,实现灯关
长按2s,实现双灯不同频闪烁
长按4s,实现双灯同频闪烁

中断:设置上升沿和下降沿触发,按下按键和抬起按键之间,发消息给消息队列。

中断方式:采用中断的方式, 坏处是必须等按键松开才可以计算按键时间长短,用户体验稍差。 好处是相比定时器的方式,会大大减小CPU的资源。

定时器扫描:开一个线程或者定时器,不断的扫描GPIO的输入状态, 好处是随时扫描到gpio的状态用户体验好。 坏处是浪费cpu资源。

若开一个定时器,本代码未实现,参考资料:[【ESP32—GPIO输入,按键的长按和短按】]
通过添加printf信息打印消息,测试原代码发现,存在时间偏差较大的情况,分析代码发现代码存在以下下问题:
目的是:当按键按下时,开始记录按下的时刻A,按键松开时,记录松开的时刻B,通过 B-A 计算按下的时间。但是源代码中按下按键时,可能多次重新计算了时刻A的值,造成测试不准的现象。
在这里插入图片描述

  • 1
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积跬步、至千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值