树莓派5 使用硬件PWM

        由于gpiozero或者其他树莓派python库的pwm发生都是软件pwm,当进行cpu占用大的处理代码时会导致pwm发生扰动。这里提供一种树莓派5硬件pwm产生的方式。首先,我们需要创建一个设备树覆盖文件来配置GPIO12, GPIO13, GPIO18和GPIO19为PWM模式并启用pwm0。

1.创建一个新的文件,命名为 pwm-pi5-overlay.dts,内容如下:
/dts-v1/;
/plugin/;

/{
    compatible = "brcm,bcm2712";

    fragment@0 {
        target = <&rp1_gpio>;
        __overlay__ {
            pwm_pins: pwm_pins {
                pins = "gpio12", "gpio13", "gpio18", "gpio19";
                function = "pwm0", "pwm0", "pwm0", "pwm0";
            };
        };
    };

    fragment@1 {
        target = <&rp1_pwm0>;
        frag1: __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <&pwm_pins>;
            status = "okay";
        };
    };
};
2. 使用设备树编译器(dtc)将 .dts 文件编译为 .dtbo 文件:
dtc -I dts -O dtb -o pwm-pi5.dtbo pwm-pi5-overlay.dts
3. 将编译后的 .dtbo 文件复制到 /boot/firmware/overlays/ 目录:
sudo cp pwm-pi5.dtbo /boot/firmware/overlays/
4. 在/boot/firmware/config.txt末尾加上:
dtoverlay=pwm-pi5
5.重启树莓派
6.创建一个脚本文件,pwm_control.sh,并添加以下内容:
#!/bin/bash
NODE=/sys/class/pwm/pwmchip2
PIN="$1"
FUNC="a0"
PERIOD="$2"
DUTY_CYCLE="$3"

function usage {
    printf "Usage: $0 <pin> <period> <duty_cycle>\n"
    printf "    pin - one of 12, 13, 14, 15, 18 or 19\n"
    printf "    period - PWM period in nanoseconds\n"
    printf "    duty_cycle - Duty Cycle (on period) in nanoseconds\n"
    exit 1
}

if [ -d "$NODE/device/consumer:platform:cooling_fan/" ]; then
    echo "Hold your horses, looks like this is pwm1?"
    exit 1
fi

case $PIN in
    "12")
    CHANNEL="0"
    ;;
    "13")
    CHANNEL="1"
    ;;
    "14")
    CHANNEL="2"
    ;;
    "15")
    CHANNEL="3"
    ;;
    "18")
    CHANNEL="2"
    FUNC="a3"
    ;;
    "19")
    CHANNEL="3"
    FUNC="a3"
    ;;
    *)
    echo "Unknown pin $PIN."
    exit 1
esac

function pwmset {
    echo "$2" | sudo tee -a "$NODE/$1" > /dev/null
}

if [[ "$PERIOD" == "off" ]]; then    
    if [ -d "$NODE/pwm$CHANNEL" ]; then
        pinctrl set $PIN no
        pwmset "pwm$CHANNEL/enable" "0"
        pwmset "unexport" "$CHANNEL"
    fi
    exit 0
fi

if [[ ! $PERIOD =~ ^[0-9]+$ ]]; then
    usage
fi

if [[ ! $DUTY_CYCLE =~ ^[0-9]+$ ]]; then
    usage
fi

if [ ! -d "$NODE/pwm$CHANNEL" ]; then
    pwmset "export" "$CHANNEL"
fi

pwmset "pwm$CHANNEL/enable" "0"
pwmset "pwm$CHANNEL/period" "$PERIOD"
if [ $? -ne 0 ]; then
    echo "^ don't worry, handling it!"
    pwmset "pwm$CHANNEL/duty_cycle" "$DUTY_CYCLE"
    pwmset "pwm$CHANNEL/period" "$PERIOD"
else
    pwmset "pwm$CHANNEL/duty_cycle" "$DUTY_CYCLE"
fi
pwmset "pwm$CHANNEL/enable" "1"

pinctrl set $PIN $FUNC

echo "GPIO $PIN (Ch. $CHANNEL, Fn. $FUNC) set to $PERIOD ns, $DUTY_CYCLE."
7.通过以下命令使用PWM控制脚本:
bash pwm_control.sh <pin> <period> <duty_cycle>
8.例如,要在GPIO12上设置周期为20000000ns(20ms),占空比为1500000ns(1.5ms)的PWM信号,可以运行:
bash pwm_control.sh 12 20000000 1500000

9.参考https://gist.github.com/Gadgetoid/b92ad3db06ff8c264eef2abf0e09d569

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
树莓派可以通过GPIO口控制PWM信号,实现对外设的调节。树莓派上有多个GPIO口,其中有些GPIO口可以输出PWM信号,可以用来控制电机、灯光等设备。 树莓派3B+和4B板型上有两个硬件PWM通道,可以直接输出PWM信号。另外,树莓派上的软件PWM也可以输出PWM信号,但是精度较低,不适合一些高精度的应用场合。 下面是使用Python代码控制树莓派三路PWM的示例: ```python import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) # 设置GPIO口 GPIO.setup(12, GPIO.OUT) GPIO.setup(32, GPIO.OUT) GPIO.setup(33, GPIO.OUT) # 创建PWM实例 pwm1 = GPIO.PWM(12, 100) pwm2 = GPIO.PWM(32, 100) pwm3 = GPIO.PWM(33, 100) # 启动PWM pwm1.start(0) pwm2.start(0) pwm3.start(0) try: while True: # 控制PWM占空比 for dc in range(0, 101, 5): pwm1.ChangeDutyCycle(dc) pwm2.ChangeDutyCycle(dc) pwm3.ChangeDutyCycle(dc) time.sleep(0.1) for dc in range(100, -1, -5): pwm1.ChangeDutyCycle(dc) pwm2.ChangeDutyCycle(dc) pwm3.ChangeDutyCycle(dc) time.sleep(0.1) except KeyboardInterrupt: pass pwm1.stop() pwm2.stop() pwm3.stop() GPIO.cleanup() ``` 上述代码中,使用树莓派的GPIO.BOARD模式,指定了GPIO口的编号。其中,12、32、33分别对应GPIO口的12、32、33号,通过GPIO.setup()方法设置为输出模式。然后,使用GPIO.PWM()方法创建PWM实例,并设置PWM频率为100Hz。最后,使用ChangeDutyCycle()方法控制PWM占空比。 这样,就可以控制树莓派上的三路PWM信号了。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值