class PWM – 脉冲宽度调制

这个类提供了脉冲宽度调制输出的功能。

示例用法:

from machine import PWM

pwm = PWM(pin, freq=50, duty_u16=8192)  # create a PWM object on a pin
                                        # and set freq and duty
pwm.duty_u16(32768)     # set duty to 50%

# reinitialise with a period of 200us, duty of 5us
pwm.init(freq=5000, duty_ns=5000)

pwm.duty_ns(3000)       # set pulse width to 3us

pwm.deinit()

构造函数

class machine.PWM(dest, *, freq, duty_u16, duty_ns, invert)

使用以下参数构造并返回一个新的PWM对象:

  • dest 是PWM输出的实体,通常是一个 machine.Pin 对象,但是某些移植版本可能允许其他值,比如整数。

  • freq 应该是一个整数,用于设置PWM周期的频率(单位为Hz)。

  • duty_u16duty_u16 / 65535 的比例设置占空比。

  • duty_ns 以纳秒为单位设置脉冲宽度。

  • invert 如果值为True,则反转相应的输出

设置 freq 可能会影响其他PWM对象,如果这些对象共享相同的底层PWM生成器(这是硬件特定的)。duty_u16duty_ns 应该一次只指定一个。invert 并不在所有移植版本上都可用。

方法

PWM.init(*, freq, duty_u16, duty_ns)

修改PWM对象的设置。关于参数的详细信息,请参见上面的构造函数文档。

PWM.deinit()

禁用PWM输出。

PWM.freq([value])

获取或设置PWM输出的当前频率。

如果没有参数,则返回以Hz为单位的频率。

使用单个 value 参数时,将频率设置为该值(单位为Hz)。如果频率超出有效范围,方法可能会引发 ValueError

PWM.duty_u16([value])

获取或设置PWM输出的当前占空比,作为一个范围在0到65535(含)之间的无符号16位值。

没有参数时,返回占空比。

使用单个 value 参数时,将占空比设置为该值,以 value / 65535 的比率测量。

PWM.duty_ns([value])

获取或设置PWM输出的当前脉冲宽度,作为纳秒值。

没有参数时返回脉冲宽度(单位为纳秒)。

使用单个 value 参数时,将脉冲宽度设置为该值。

特定PWM类实现

以下具体类实现了对PWM类的增强。

PWM的限制

  • 由于计算硬件的离散性质,并非所有频率都能以绝对精确度生成。通常,PWM频率是通过将某个整数基频除以一个整数分频器获得的。例如,如果基频是80MHz,而所需的PWM频率是300kHz,则分频器必须是一个非整数数值80000000 / 300000 = 266.67。四舍五入后,分频器被设置为267,PWM频率将是80000000 / 267 = 299625.5 Hz,而不是300kHz。如果分频器设置为266,则PWM频率将是80000000 / 266 = 300751.9 Hz,但同样不是300kHz。

    一些移植版本如RP2040使用分数分频器,这允许在较高频率下通过在两个相邻值之间切换PWM脉冲持续时间来实现更细的频率粒度,使得结果平均频率更接近预期值,但以频谱纯度为代价。

  • 占空比也具有相同的离散性质,其绝对精度是无法实现的。在大多数硬件平台上,占空比将在下一个频率周期应用。因此,在测量占空比之前,你应该等待超过“1/频率”的时间。

  • 频率和占空比分辨率通常是相互依赖的。PWM频率越高,可用的占空比分辨率就越低,反之亦然。例如,300kHz的PWM频率可以有8位的占空比分辨率,而不是预期的16位。在这种情况下,duty_u16 的最低8位是无意义的。所以:

    pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2)
    

    和:

    pwm=PWM(Pin(13), freq=300_000, duty_u16=2**16//2 + 255)
    

    将生成具有相同50%占空比的PWM。