使用C的Beaglebone黑色PWM

时间:2015-03-31 13:15:59

标签: c embedded-linux beagleboneblack

我在C中为beaglebone black写了一个示例pwm函数。每当我在其他模块或main()中进行函数调用时,我最终都会出现分段错误。请帮助我犯错误以及如何处理这个问题。 以下是代码。

int trigger_pwm_output(unsigned input_no )
{
    FILE *pwm,*duty,*period,*run;``
    uint16_t input=0;
    uint8_t input_no=0,input_state=0;
    unsigned int duty_cycle =500000;
    pwm = fopen("/sys/devices/bone_capemgr.9/slots", "w");
    fseek(pwm,0,SEEK_SET);
    fprintf(pwm,"am33xx_pwm");
    fflush(pwm);



    switch(input_no)
    {
        case 0:

            fprintf(pwm,"bone_pwm_P8_13");
            fflush(pwm);
            period = fopen("/sys/devices/ocp.3/pwm_test_P8_13.15/period", "w");
            fseek(period,0,SEEK_SET);
            fprintf(period,"%d",500000);
            fflush(period);

            duty = fopen("/sys/devices/ocp.3/pwm_test_P8_13.15/duty", "w");
            fseek(duty,0,SEEK_SET);
            run = fopen("/sys/devices/ocp.3/pwm_test_P8_13.15/run", "w");
            fseek(run,0,SEEK_SET);
            fprintf(run,"%d",0);
            fflush(run);

            fseek(run,0,SEEK_SET);
            count++;
                do 
                {
                    duty_cycle += 10;
                    fprintf(duty,"%d",duty_cycle);
                }while(count > 0) || (count < 10));
                fflush(duty);
                fprintf(run,"%d",1);
                fflush(run);

            fclose(pwm);
            fclose(duty);
            fclose(period);
            fclose(run);
            break;
        case 1:
            fprintf(pwm,"bone_pwm_P8_19");
            fflush(pwm);
            period = fopen("/sys/devices/ocp.3/pwm_test_P8_19.16/period", "w");
            fseek(period,0,SEEK_SET);
            fprintf(period,"%d",500000);
            fflush(period);

            duty = fopen("/sys/devices/ocp.3/pwm_test_P8_19.16/duty", "w");
            fseek(duty,0,SEEK_SET);
            run = fopen("/sys/devices/ocp.3/pwm_test_P8_19.16/run", "w");
            fseek(run,0,SEEK_SET);
            fprintf(run,"%d",0);
            fflush(run);

            fseek(run,0,SEEK_SET);
            --count;
            do 
            {
                duty_cycle += 10;
                fprintf(duty,"%d",duty_cycle);
            }while(count <10);
            fflush(duty);
            fprintf(run,"%d",1);
            fflush(run);



            fclose(pwm);
            fclose(duty);
            fclose(period);
            fclose(run);
            break;



    }
    return 0;
}

`

2 个答案:

答案 0 :(得分:4)

我刚刚使用C在BeagleBone Black上成功启用了4个PWM输出,所以我希望能给你一些合理的建议。

使用/sys/devices/ocp.3/目录下的文件(称为设备树覆盖)进行PWM不是一个好主意,原因有两个:

  • PWM引脚目录名的最后两位是任意的,例如pwm_test_P8_13.xx细分错误的潜在原因,因为您不检查fopen状态。但是,fopen不允许在指定路径中使用通配符。我的解决方法一点都不干净,就是用popen调用echo /sys/devices/ocp.3/pwm_test_P8_13.*/来检索PWM引脚目录的正确完整路径。
  • BeagleBone Black上只有两个PWM模块,DTO可以防止每个模块使用多个PWM引脚。因此,如果您尝试从命令行修改引脚的周期,则可能会返回写入错误。如果您再键入dmesg | tail,则可能会看到以下消息:
      

    [1406.652632] ehrpwm 48304200.ehrpwm:期间值与渠道1冲突
      [1406.660047] pwm_test pwm_test_P8_19.11:pwm_config()失败

因此,我使用了/sys/class/pwm/下的文件。您仍然需要将am33xx_pwm和您计划使用的PWM引脚写入文件/sys/devices/bone_capemgr.9/slots。然后,转到目录/sys/class/pwm/,将数字(0-7)写入文件export,然后在生成的目录pwm?下修改文件,其中?是数字写给export。 下表显示了每个数字及其对应的引脚:

enter image description here

Here是我提到的教程。

希望这有帮助!

答案 1 :(得分:0)

此代码存在一些问题 - 其中一些问题已在评论中进行了描述。

  • 存在变量名称冲突。 input_no既传入函数,也传递给函数中定义。
  • 两个do-while循环都可能是无限的。两个循环都具有依赖于count的结束条件,该结束条件在任一循环的主体中都未被修改。此外,无论count的值如何,第一个循环中的条件始终为真。
  • 永远不会检查所有fopen次调用的返回值。如果这些调用中的任何一个失败,则使用空文件指针调用后续文件操作。
  • count未在此代码中的任何位置定义或初始化。它是全球定义的吗?
  • 您对fopen的一次调用是在switch语句的正文之外进行的 - 最好将其相应的close调用移到外面。