当前位置: 首页 > news >正文

04_ESP32 脉冲宽度调制 (PWM)

04_ESP32 脉冲宽度调制 (PWM)

1. 什么是 PWM?

PWM(Pulse Width Modulation,脉冲宽度调制) 是一种数字信号调制技术,可以用来“模拟”出连续变化的电压。

当需要控制设备输出的“强度”(例如调节 LED 亮度或电机转速),而不仅仅是简单的开/关状态时,PWM (Pulse Width Modulation,脉冲宽度调制) 技术是一种有效的解决方案。

PWM 信号本质上仍然是数字信号,只有 HIGH 和 LOW 两种状态,但通过控制高电平持续的时间比例,可以实现类似模拟输出的效果。

PWM

PWM 的核心概念包括:

  • 占空比 (Duty Cycle): 在一个 PWM 周期内,高电平(信号为 HIGH)持续的时间占整个周期的百分比。占空比直接影响输出的平均功率或强度。

    不同占空比产生不同的平均电压效果:

    • 占空比 0%:平均电压 ≈ 0V
    • 占空比 25%:平均电压 ≈ 0.825V (3.3V * 0.25)
    • 占空比 50%:平均电压 ≈ 1.65V (3.3V * 0.50)
    • 占空比 75%:平均电压 ≈ 2.475V (3.3V * 0.75)
    • 占空比 100%:平均电压 ≈ 3.3V
  • 频率 (Frequency): PWM 信号每秒钟重复一个完整周期的次数,单位是赫兹 (Hz)。选择合适的频率对于应用至关重要:对于 LED 调光,频率需足够高以避免人眼察觉闪烁;对于电机控制,频率会影响效率和噪音。

2. ESP32 上的 PWM 实现

ESP32 集成了专门的硬件模块用于生成 PWM 信号:

  • LEDC (LED Control) 外设: ESP32 的主要 PWM 生成器。虽然名为 LED 控制,但可产生通用的 PWM 信号。根据具体芯片型号,拥有 6 到 16 个独立通道,频率范围 1Hz-40MHz。
  • MCPWM (Motor Control PWM) 外设: 专门用于电机控制,包含死区控制等高级功能。其接口未被包含在标准的 Arduino ESP32 核心库中。

在 Arduino ESP32 编程环境中,主要通过以下两种方式来利用 LEDC 外设产生 PWM 信号:

  1. analogWrite(pin, value) 函数: 这是 Arduino 平台的标准 PWM 函数,ESP32 对其提供了良好支持,使用便捷。
  2. LEDC API 函数: 一系列如 ledcAttach(), ledcWrite(), ledcAttachChannel() 的函数,允许对 PWM 参数进行更细致和灵活的配置。

示例通过控制外部 LED 的亮度来演示这两种 PWM 实现方法。

3. 搭建电路

image-20260519184228457

4. 使用 analogWrite() 的 ESP32 PWM 示例代码

const int ledPin = 7;  // LED 连接的引脚号void setup(){
}void loop(){// 亮度增加(占空比值从 0 到 255)for(int dutyCycle = 0; dutyCycle <= 255;dutyCycle++){analogWrite(ledPin,dutyCycle);   // 设置 PWM 占空比值delay(10);                       // 延时以控制变化速度}// 亮度减少(占空比值从 255 到 0)for(int dutyCycle = 255; dutyCycle >= 0;dutyCycle--){analogWrite(ledPin,dutyCycle);   // 设置 PWM 占空比值delay(10);                       // 延时以控制变化速度}
}

代码解析

  1. 对于 analogWrite(),ESP32 的实现会自动处理引脚的 PWM 初始化,因此通常不需要显式调用 pinMode()

  2. loop() 函数:

    • 第一个 for 循环:

      for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++): 变量 dutyCycle 从 0 递增至 255。

    • 第二个 for 循环:

      for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) 变量 dutyCycle 从 255 递减至 0,使 LED 亮度逐渐减弱。

    • analogWrite(ledPin, dutyCycle);:

      将当前 dutyCycle 值(0-255)设为 ledPin 的 PWM 占空比,使 LED 亮度逐渐增加。

    • delay(10);:

​ 短暂延时,用于控制亮度变化速率

注意:在使用 analogWrite() 时,ESP32 会自动管理 LEDC 通道的分配,并设置默认的频率 和 8 位分辨率。

5. 使用 LEDC API 的 ESP32 PWM 示例代码

const int ledPin = 7;         // LED 连接的 GPIO 引脚const int frequency = 5000;   // PWM 频率 5kHz
const int resolution = 8;     // PWM 分辨率 8 位(0-255)
const int ledChannel = 0;     // PWM 通道号void setup(){// 初始化 LED PWM 功能ledcAttach(ledPin,frequency,resolution);// 如果想指定通道// ledcAttach(ledPin,frequency,resolution,ledChannel)
}void loop(){// 亮度增加(占空比值从 0 到 255)for(int dutyCycle = 0; dutyCycle <= 255;dutyCycle++){analogWrite(ledPin,dutyCycle);   // 设置 PWM 占空比值delay(10);                       // 延时以控制变化速度}// 亮度减少(占空比值从 255 到 0)for(int dutyCycle = 255; dutyCycle >= 0;dutyCycle--){analogWrite(ledPin,dutyCycle);   // 设置 PWM 占空比值delay(10);                       // 延时以控制变化速度}
}

代码解析

  1. ledcAttach(ledPin, frequency, resolution);
    • ledPin:指定要用作 PWM 输出的 GPIO 引脚
    • frequency:PWM 信号的频率,单位为赫兹 (Hz)
    • resolution:分辨率位数,决定占空比的精度
  2. ledcWrite(ledPin, dutyCycle);:
    • 设置 LEDC 引脚 ledPin 的占空比为 dutyCycle
    • 数值范围取决于分辨率设置:8 位为 0-255(2⁸-1)

6.电位器控制LED亮度代码示例

通过调节电位器旋钮来控制 LED 灯的亮度,使旋钮位置与灯光亮度相对应

image-20260519190907844
const int ledPin = 7;             // LED 连接的引脚
const int potentiometerPin = 8;   // 电位器连接的引脚int potentiometerValue;  // 存储电位器读取值
int brightness;          // 存储映射后的亮度值void setup() {
}void loop() {// 1. 读取电位器的模拟值 (范围 0-4095)potentiometerValue = analogRead(potentiometerPin);// 2. 将 ADC 读数映射到 PWM 的范围 (0-255)brightness = map(potentiometerValue, 0, 4095, 0, 255);// 3. 用映射后的值设置 LED 亮度analogWrite(ledPin, brightness);delay(20);
}

代码解析:

  1. map(potValue, 0, 4095, 0, 255);:

    将电位器的 0-4095 范围线性映射到 PWM 的 0-255 范围,实现电位器旋转角度与 LED 亮度的对应关系。

    语法为:

    map(value, fromLow, fromHigh, toLow, toHigh)
    
    • value:要转换的输入值(这里是电位器读数)
    • fromLow, fromHigh:输入范围(0 到 4095)
    • toLow, toHigh:输出范围(0 到 255)

    工作原理:

    map() 函数按比例转换数值。例如:

    • 电位器值 0(0%位置)→ LED 亮度 0(0% 亮度)
    • 电位器值 2047(50%位置)→ LED 亮度 127(50% 亮度)
    • 电位器值 4095(100%位置)→ LED 亮度 255(100% 亮度)

    简单来说,电位器转到哪个位置,LED 就对应那个亮度。

http://www.jsqmd.com/news/846706/

相关文章:

  • 告别手动改表!用ArcGIS Pro SDK批量修改属性字段的保姆级教程(附完整C#代码)
  • 通过curl命令直接测试Taotoken聊天补全接口的配置与排错指南
  • 通过Nodejs快速集成Taotoken实现AI对话功能
  • 学术人必藏的Perplexity图书推荐查询技巧,解锁被隐藏的冷门神书与前沿译本
  • 2026 年上海黄金回收服务测评|口碑品牌大盘点 - 奢侈品回收测评
  • 【免费下载】 YOLOv8 源代码(未改动)
  • VPU与NPU协同:智能视觉芯片的架构演进与实战解析
  • 告别Colab限流:手把手教你将Kaggle打造成你的主力免费GPU开发环境(含包管理避坑)
  • 设计师私藏的Perplexity搜索黑箱(仅限内部团队流通):含Figma组件库/Design Token/可访问性规范专属指令集
  • 靠谱省心 2026深圳优质小程序定制服务商推荐 - 软件测评师
  • 终极Zotero Style插件指南:让文献管理从枯燥变高效
  • Nodejs后端服务接入Taotoken多模型API的详细步骤
  • 用 content-length 长度确定后端返回的是不是真实的文件流
  • 3分钟上手Zotero翻译插件:零基础搞定外文文献阅读
  • 2026年COD预制试剂非标定制服务解析:技术实力派生产厂家与品牌选择 - 品牌推荐大师1
  • Winhance:让Windows系统优化变得简单高效的5个实用技巧
  • 【免费下载】 Microsoft Visual C++ Redistributable for Visual Studio 2019 资源文件
  • 2026北京新评定包包回收榜单:三级平台推荐 + 核心区门店布局 - 奢侈品回收测评
  • 【免费下载】 探索三维世界的利器:Qt+OpenGL三维地形显示项目
  • NVIDIA Profile Inspector完整指南:如何快速优化游戏性能并解决兼容性问题
  • Gordon性能优化秘籍:提升Flash运行时效率的10个技巧
  • LangChain三剑客:揭秘AI智能体开发背后的生态力量!
  • 用 fetch 下载文件并在页面上显示多个下载进度条
  • Gemini API多模态接入陷阱大全,图像+文本联合推理失败的6类元数据校验盲区
  • 保姆级教程:在Ubuntu 20.04上用RealSense D435i和RTAB-Map搞定3D建图(附避坑点)
  • Tower.js 资源管理完全指南:掌握 resource、query 和 adapter 的终极教程
  • Royal TSX 终极中文汉化包:让专业远程管理工具说中文的完整解决方案
  • 力扣新成就
  • 2026 上海黄金回收品牌推荐|正规靠谱商家全盘点 - 奢侈品回收测评
  • Bifrost三星固件下载器:跨平台免费获取官方固件的终极指南