You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

树莓派4B中降低软件PWM的CPU占用率方案咨询

问题描述

我在树莓派4B上使用C语言的pigpio库,在GPIO引脚5、6、19、26上生成4路8kHz的软件PWM信号,用于控制连接执行器的BTS7960 43A大功率电机驱动模块。目前已成功实现电机的可变占空比控制,但即使控制器无动作时CPU占用率仍高达107%。

软件启动时仅初始化gpioSetPWMfrequency和gpioSetPWMrange函数,在需要改变引脚占空比的循环中调用gpioPWM函数。根据pigpio文档,其采用DMA访问,现寻求降低CPU占用率的方法,以及更合适的替代库。

伪代码如下:

#include <pigpio.h>
// 电机1引脚定义
static const int kiShieldFwdPWMIOPin = 5;//21;     // 前进PWM引脚
static const int kiShieldBackPWMPin = 6;//22;      // 后退PWM引脚
static const int kiShieldENIOPin = 13;//23;        // 使能引脚

// 电机2引脚定义
static const int kiColumnFwdPWMIOPin = 19;//24;    // 前进PWM引脚
static const int kiColumnBackPWMIOPin = 26;//25;   // 后退PWM引脚
static const int kiColumnENIOPin = 12;//26;         // 使能引脚

void setup(){
    // 初始化PWM频率为8kHz
    gpioSetPWMfrequency(kiShieldFwdPWMIOPin,8000);
    gpioSetPWMfrequency(kiShieldBackPWMPin,8000);
    gpioSetPWMfrequency(kiColumnFwdPWMIOPin,8000);
    gpioSetPWMfrequency(kiColumnBackPWMIOPin,8000);
   
    // 设置PWM范围为0-100(对应占空比0%-100%)
    gpioSetPWMrange(kiShieldFwdPWMIOPin, 100);
    gpioSetPWMrange(kiShieldBackPWMPin, 100);
    gpioSetPWMrange(kiColumnFwdPWMIOPin, 100);
    gpioSetPWMrange(kiColumnBackPWMIOPin, 100);
}

void BerryController::move(STATE state, DIRECTION direction, const int &pwmValue){
    switch (state)
    {
    case STATE::Shield:
        switch (direction)
        {
        case DIRECTION::Open:
            gpioPWM(kiShieldBackPWMPin,PI_LOW);
            gpioPWM(kiShieldFwdPWMIOPin,pwmValue);
            break;
        case DIRECTION::Close:
            gpioPWM(kiShieldBackPWMPin,pwmValue);
            gpioPWM(kiShieldFwdPWMIOPin,PI_LOW);
            break;
        case DIRECTION::Stop:        
            gpioPWM(kiShieldFwdPWMIOPin,PI_LOW);
            gpioPWM(kiShieldBackPWMPin,PI_LOW);
            break;
        default:
            break;
        }
        break;
    case STATE::Column:
        switch (direction)
        {
        case DIRECTION::Open:                     
            gpioPWM(kiColumnBackPWMPin,PI_LOW);
            gpioPWM(kiColumnFwdPWMIOPin, pwmValue);
            break;
        case DIRECTION::Close:                    
            gpioPWM(kiColumnFwdPWMIOPin,PI_LOW);
            gpioPWM(kiColumnBackPWMPin, pwmValue);
            break;
        case DIRECTION::Stop:
            gpioPWM(kiColumnFwdPWMIOPin,PI_LOW);
            gpioPWM(kiColumnBackPWMPin,PI_LOW);
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }
}

当前CPU占用率为107%

解决方案

降低CPU占用率的方法

1. 切换到硬件PWM引脚

树莓派4B的硬件PWM由片上硬件生成,无需CPU持续干预,占用率极低。你当前使用的引脚中仅GPIO19是硬件PWM引脚,其余5、6、26均为软件模拟PWM。建议更换为以下硬件PWM引脚:

  • GPIO12(PWM通道0)
  • GPIO13(PWM通道1)
  • GPIO18(PWM通道0)
  • GPIO19(PWM通道1)

更换引脚后,pigpio会自动使用硬件PWM模式,CPU占用率会大幅下降。

2. 优化pigpio调用逻辑

  • 避免重复调用gpioPWM:如果循环中频繁调用gpioPWM(即使占空比未变化),会产生不必要的开销。可以为每个引脚维护一个当前占空比的缓存变量,仅当新值与缓存值不同时才调用gpioPWM。示例修改:
// 新增缓存变量
static int currentShieldFwdPWM = PI_LOW;
static int currentShieldBackPWM = PI_LOW;
static int currentColumnFwdPWM = PI_LOW;
static int currentColumnBackPWM = PI_LOW;

void BerryController::move(STATE state, DIRECTION direction, const int &pwmValue){
    switch (state)
    {
    case STATE::Shield:
        switch (direction)
        {
        case DIRECTION::Open:
            if (currentShieldBackPWM != PI_LOW) {
                currentShieldBackPWM = PI_LOW;
                gpioPWM(kiShieldBackPWMPin, PI_LOW);
            }
            if (currentShieldFwdPWM != pwmValue) {
                currentShieldFwdPWM = pwmValue;
                gpioPWM(kiShieldFwdPWMIOPin, pwmValue);
            }
            break;
        // 其余case同理修改
        }
        break;
    // 其余state同理修改
    }
}
  • 使用pigpio守护进程模式:通过pigpiod启动守护进程,程序通过socket与守护进程通信,而非直接操作硬件,能进一步降低CPU占用。编译时链接pigpio库改为链接pigpiod_if2库,调用相关接口。

3. 调整PWM参数

8kHz的频率对于软件PWM来说较高,若业务允许,可适当降低PWM频率(比如降至2kHz-5kHz),能减少软件模拟的CPU开销。

替代库推荐

1. bcm2835库

直接操作BCM2835芯片寄存器,底层高效,支持硬件PWM配置,几乎无CPU占用,适合对性能要求极高的场景。

2. libgpiod

Linux官方推荐的GPIO操作库,基于字符设备接口,支持硬件PWM,API规范且现代,适配最新树莓派系统。

3. wiringPi

虽然已停止维护,但对树莓派4B兼容性良好,硬件PWM调用简单,CPU占用低,适合快速开发。


内容的提问来源于stack exchange,提问作者BhavinT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:50:01