首页 动态 版块 商城 我的
 退出
游客  
等级:
金币:
经验值:

PWM脉冲宽度调制 树莓派Pico与ESP32开发板 MicroPython和C++示例【入门教程】

  8011 
 0
 8
趣    

Image



一:PWM介绍

1. 什么是PWM?

PWM(Pulse Width Modulation,脉冲宽度调制) 是一种通过改变数字信号的“高电平持续时间”来模拟连续电压的技术。由于单片机或微控制器的 GPIO 引脚通常只能输出两种状态高电平1,低电平0,如果想要调节 LED 亮度、电机转速或舵机角度等连续变化的量,直接输出数字信号是无法实现的。PWM 通过极高频率地快速切换高低电平,利用人眼的视觉暂留(或电机的机械惯性),实现等效的“模拟电压”输出。


PWM 通过快速切换引脚的高低电平来工作,周期:完成一次高低电平切换的时间,占空比:在一个周期内高电平所占的百分比,例如:50% 占空比表示高低电平各占一半时间,树莓派 Pico 上几乎所有 GPIO 引脚都可以配置为 PWM 输出,每个引脚都关联到一个 PWM 通道。


2. PWM核心参数

周期(Period, T): 一次完整的“高电平 + 低电平”所持续的时间。

频率(Frequency,  ): 一秒内PWM信号重复次数,公式为 f=T1 在控制LED亮度时,频率通常设置为 100Hz~1000Hz以上,避免感知闪烁

占空比(Duty Cycle): 在一个周期内,高电平持续时间总周期时间的百分比。

0% 占空比:引脚全程输出 0V,LED 熄灭。

50% 占空比:一半时间 3.3V,一半时间 0V,等效平均电压为 $3.3\text{V} \times 50\% = 1.65\text{V}$,LED 半亮

100% 占空比: 引脚全程输出 3.3V,LED 最亮

二:树莓派Pico示例

控制led呼吸示例,可使用 MicroPython 内置的 machine.PWM 和 machine.Pin 类即可轻松实现呼吸灯(LED 亮度逐渐变亮再变暗)。默认对应接线: GPIO 25 是 Pico 板载的 LED,也可以外接 GPIO 其他引脚。占空比范围: MicroPython 的 PWM 占空比设为 16 位精度,数值范围是 0(0%)到 65535(100%)。


1. python代码

import time
from machine import Pin, PWM

# 初始化 PWM,使用板载 LED(GPIO 25)
# 如果使用的是 Pico W,可尝试使用 PWM(Pin("LED")) 或外接 GPIO 引脚
led_pwm = PWM(Pin(25))

# 设置 PWM 频率为 1000Hz (1kHz)
led_pwm.freq(1000)

try:
    while True:
        # 逐渐变亮:占空比从 0 增加到 65535
        for duty in range(0, 65536, 1000):
            led_pwm.duty_u16(duty)
            time.sleep_ms(15)

        # 逐渐变暗:占空比从 65535 减少到 0
        for duty in range(65535, -1, -1000):
            led_pwm.duty_u16(duty)
            time.sleep_ms(15)

except KeyboardInterrupt:
    # 退出时关闭 PWM 输出
    led_pwm.deinit()


三:ESP32示例

ESP32 拥有专用的 LEDC(LED Control) 硬件外设模块,支持高精度的 PWM 输出。在 Arduino ESP32 框架中,使用 ledcSetup、ledcAttachPin 和 ledcWrite 接口。

硬件引脚: 下面代码中使用 GPIO 2引脚来控制LED

分辨率设置: 设置为 8 位分辨率(8-bit),占空比数值范围是 0(0%)到 255(100%)。

1. C++代码

#include <Arduino.h>

// 定义使用的 GPIO 引脚
const int ledPin = 2; // ESP32 开发板板载 LED 通常在 GPIO 2

// PWM 参数配置
const int pwmChannel = 0;    // 使用 PWM 通道 0 (ESP32 有 16 个 independent 通道)
const int freq = 5000;       // 设置 PWM 频率为 5000Hz (5kHz)
const int resolution = 8;    // 设置分辨率为 8 位,即数值范围 0 - 255

void setup() {
  // 配置 PWM 通道、频率和分辨率
  ledcSetup(pwmChannel, freq, resolution);

  // 将 PWM 通道绑定到指定 GPIO 引脚
  ledcAttachPin(ledPin, pwmChannel);
}

void loop() {
  // 逐渐变亮:占空比从 0 增加到 255
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    ledcWrite(pwmChannel, dutyCycle);
    delay(10);
  }

  // 逐渐变暗:占空比从 255 减少到 0
  for (int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
    ledcWrite(pwmChannel, dutyCycle);
    delay(10);
  }
}



作者签名:    楼主  2024-11-29 15:48:21
回复列表
Powered by YDXHUO _VERSION
© 2017-2026 跃动芯火版权
您的IP: 216.73.216.115 , 2026-08-21 23:22:53
Powered by YDXHUO _VERSION
© 2017-2026 跃动芯火版权
(8) 分享
分享

请保存二维码或复制链接进行分享

取消
免责声明
1、本站资源,均来自网络与个人作者,所有资源和文章仅限用于学习和研究目的 。
2、不得用于商业或非法用途,否则,一切责任由该用户承担 !

侵权删除请致信 E-Mail:ydxho@qq.com
已有1次打赏
RASPI打赏给楼主1金币,2026-01-15 23:33:59