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

树莓派WiringPI多线程生成softPWM异常求助:无法稳定输出指定PWM

问题分析与解决方案

核心错误

你代码里的softPwmCreate调用存在致命的复制粘贴错误:除第一个引脚外,后续的softPwmCreate都错误传入了PWM_pin1,导致只有引脚22被正确初始化softPWM,其他引脚根本没创建对应的softPWM实例——这是大部分引脚不工作的直接原因。

另外,主线程完成线程join后立即退出,而WiringPi的softPWM依赖后台线程维持信号,程序退出后所有softPWM信号会立即终止,这也会导致PWM无法持续输出。同时你提到需要5路PWM,但当前代码只定义了4个引脚的参数,需补充第5路配置。

修正后的代码

#include <wiringPi.h> 
#include <stdio.h>    
#include <softPwm.h> 
#include <stdlib.h>
#include <pthread.h>

#define THREAD_NUM 5  // 对应5路PWM,每个线程负责一路

// 单个引脚的线程参数结构
struct thArg{
    int pwmPin;
    int dutyCycle;
};

// 5路PWM配置:引脚、占空比(可自行修改)
struct thArg pwmConfigs[] = {
    {22, 20},
    {23, 40},
    {24, 80},
    {25, 60},
    {26, 50}  // 补充第5路引脚与占空比
};

void* pwmRoutine(void* args){
    struct thArg* config = (struct thArg*)args;
    
    // 初始化引脚并创建softPWM实例
    pinMode(config->pwmPin, OUTPUT);
    if(softPwmCreate(config->pwmPin, 0, 100) != 0){
        printf("Failed to create softPWM for pin %d\n", config->pwmPin);
        pthread_exit(NULL);
    }
    
    // 设置目标占空比
    softPwmWrite(config->pwmPin, config->dutyCycle);
    
    // 线程保持存活,避免softPWM后台线程被终止
    while(1){
        delay(1000);
    }
    
    free(args);
    pthread_exit(NULL);
}

int main(int argc, char** argv)
{
    if(wiringPiSetup() == -1){
        printf("WiringPi setup failed!\n");
        exit(EXIT_FAILURE);
    }
    
    pthread_t threads[THREAD_NUM];
    for(int i=0; i<THREAD_NUM; i++){
        // 复制参数到堆内存,避免线程访问栈变量
        struct thArg* arg = malloc(sizeof(struct thArg));
        *arg = pwmConfigs[i];
        
        if(pthread_create(&threads[i], NULL, pwmRoutine, arg) != 0){
            perror("Failed to create thread");
            free(arg);
            exit(EXIT_FAILURE);
        } 
    }

    // 主线程保持运行,防止程序退出导致softPWM终止
    while(1){
        delay(3000);
    }
    
    // 实际不会执行到此处,如需优雅退出可添加信号处理逻辑
    for(int i = 0; i<THREAD_NUM; i++){
        pthread_join(threads[i], NULL);
    }
    
    return EXIT_SUCCESS;
}

关键修改点

  • 修复softPwmCreate的引脚参数错误,确保每个引脚对应独立的softPWM实例
  • 改为每个PWM引脚对应一个线程,实现真正的多线程处理
  • 补充第5路PWM配置,适配你的需求
  • 线程内添加循环保持存活,主线程也添加循环避免程序退出,确保softPWM信号持续输出
  • 增加WiringPi初始化失败、softPWM创建失败的错误提示

其他注意事项

  • WiringPi的softPWM是软件模拟实现,过多路数会导致CPU占用过高,建议不超过8路
  • 确保树莓派系统无其他进程占用目标GPIO引脚
  • 编译时需链接pthread和wiringPi库,命令示例:gcc pwm_threads.c -o pwm_threads -lwiringPi -lpthread

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 01:50:25