Raspberry Pi GPIO 教程(3)PWM

PWM(脉冲宽度调制)是一种调制技术,通过该技术,脉冲宽度会发生变化,同时保持频率不变。

通过 PWM 技术,我们可以使用 ON-OFF 信号控制输送到负载的功率。

PWM 信号可用于控制直流电机的速度、改变 LED 的强度、控制伺服电机等应用。

下面显示的 GIF 描述了如何使用 PWM 来控制 LED 的强度。

Raspberry Pi PWM

Raspberry Pi 有两个 PWM 通道,即 PWM0 和 PWM1。

40 针 P1 接头上的两个 PWM 通道的 PWM 引脚如下:

GPIO PinPWM0/PWM1
GPIO12PWM0
GPIO18PWM0
GPIO13PWM1
GPIO19PWM1

Raspberry Pi 40 针 P1Header 上的 PWM 引脚如下图所示,

Image

Python 中的 PWM 函数

创建 PWM 对象

创建 PWM 类的对象,它是 RPi.GPIO 库的一部分。在这里,我们创建了名为 pi_pwm 的对象。我们可以为对象提供任何名称。

例如:

pi_pwm = GPIO.PWM (Pin no., frequency)

其中,

Pin no. – 将在其上生成 PWM 的 PWM 引脚号。

frequency – PWM 的频率

现在,我们可以使用 PWM 对象调用 RPi.GPIO 库的 PWM 函数。

注意:此处生成的 PWM 是软件 PWM,可以在任何 GPIO 引脚上生成。

start (DutyCycle)

它用于启动指定占空比的 PWM 生成。

ChangeDutyCycle(DutyCycle)

此函数用于更改信号的占空比。我们必须提供 0-100 范围内的占空比。

ChangeFrequency(frequency)

此函数用于更改 PWM 的频率(单位为 Hz)。我们在上面的程序中没有使用过此函数。但是,我们可以使用它来更改频率。

stop()

此函数用于停止 PWM 生成。

在Proteus中建立以下电路:

Image

在源代码中输入以下程序:

# Modules
import RPi.GPIO as GPIO
pwm_Pin = 12

# Main function
def main():
    # Setup
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(pwm_Pin, GPIO.OUT)
    myPWM = GPIO.PWM(pwm_Pin, 100)

    # Infinite loop
    while 1:
        myPWM.start(50)

# Command line execution
if __name__ == '__main__':
    main()

该程序应生成一个频率为100,占空比为50的PWM方波。运行模拟,查看示波器波形:

Image

改变占空比为25,查看波形:

Image

下面这段程序通过改变PWM的占空比来调节LED灯的亮度:

import RPi.GPIO as GPIO
from time import sleep

def main():
    ledpin = 12               # PWM pin connected to LED
    GPIO.setwarnings(False)   # disable warnings
    GPIO.setmode(GPIO.BOARD)  # set pin numbering system
    GPIO.setup(ledpin,GPIO.OUT)
    pi_pwm = GPIO.PWM(ledpin,1000)
    pi_pwm.start(0)

    try:
        while True:
            for duty in range(0,101,1):
                pi_pwm.ChangeDutyCycle(duty)
                sleep(0.01)
            sleep(0.5)

            for duty in range(100,-1,-1):
                pi_pwm.ChangeDutyCycle(duty)
                sleep(0.01)
            sleep(0.5)

    except KeyboardInterrupt:
        print("\nProgram stopped by user")
    finally:
        GPIO.cleanup()

if __name__ == '__main__':
    main()

演示动画: