This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

BLDC例程中PWM模块占空比的计算



各位老师好,这个BLDC3-1例程中,PWM模块这占空比是怎么算的呢?求指导

void F281X_EV1_BDC_PWM_Update(PWMGEN *p)
{

int32 Tmp;
int16 Period, GPR0_BDC_PWM;

// PWM1&4 are enabled (PWM4's forced ON) and PWM2&3 are disabled
if (p->Rotation==0)
EvaRegs.ACTRA.all = 0x00C2;

// PWM2&3 are enabled (PWM2's forced ON) and PWM1&4 are disabled
else if (p->Rotation==1)
EvaRegs.ACTRA.all = 0x002C;

// Otherwise, PWM1-4 are disabled
else
EvaRegs.ACTRA.all = 0x0000;

// Convert "Period" (Q15) modulation function to Q0
Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
Period = (int16)(Tmp>>15); // Q15 -> Q0 (period)

// Check pwm_active setting
if (p->PwmActive==1) // PWM active high
GPR0_BDC_PWM = 0x7FFF - p->DutyFunc;

else if (p->PwmActive==0) // PWM active low
GPR0_BDC_PWM = p->DutyFunc;

// Convert "DutyFunc" or "GPR0_BDC_PWM" (Q15) duty modulation function to Q0
Tmp = (int32)Period*(int32)GPR0_BDC_PWM; // Q15 = Q0*Q15

EvaRegs.CMPR1 = (int16)(Tmp>>15); // Q15 -> Q0
EvaRegs.CMPR2 = (int16)(Tmp>>15); // Q15 -> Q0

}

为什么总是对Tmp进行右移呢?这个0x7FFF是干啥的?速度计算那块就有0x7FFF,解释是周期寄存器的值,但是也找不到哪个周期寄存器的值是0x7FFF.

麻烦老师指导一下。谢谢

  • 求教啊!!十分感谢

  • 为什么总是对Tmp进行右移呢?这个0x7FFF是干啥的?速度计算那块就有0x7FFF,解释是周期寄存器的值,但是也找不到哪个周期寄存器的值是0x7FFF.

    Eric:
    首先你要理解一下Q格式的概念,就是把小数左移多少位变成整数去参与过程运算,因为C28x内核是定点内核,做浮点运算很慢,所以要转换成定点去参与过程运算,到最终再转换回来。
    举例, 0.5 的 Q15格式就是0.5 乘以2的15次方,就是左移15位。
    所以
    Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
    Period = (int16)(Tmp>>15); // Q15 -> Q0 (period)
    上面中的Tmp就是周期值去乘以一个Q15的占空比,计算完之后,再右移回来,变成实际的周期值。
    至于0x7FFF, 你可以自己计算一下嘛,如果要产生多少KHz的PWM,可以算法计数值是多少。
  • 老师,您好,谢谢您的解答。
    实在抱歉,还是没搞明白0x7FFF是怎么来的,pwm1.PeriodMax = (SYSTEM_FREQUENCY/PWM_FREQUENCY)*1000;得出PeriodMax是7500。
    根据以下这段程序,TIPR也是7500, if (p->PwmActive==1) // PWM active high
    GPR0_BLDC_PWM = 0x7FFF - p->DutyFunc;
    那为什么在这两行程序中会用 0x7FFF减去占空比,而不是用7500去减呢?麻烦老师指点,谢谢老师!


    void F281X_EV1_BLDC_PWM_Init(PWMGEN *p)
    {
    EvaRegs.T1PR = p->PeriodMax; // Init Timer 1 Period Register
    EvaRegs.T1CON.all = BLDCPWM_INIT_STATE; // Init PWM Operation
    EvaRegs.ACTRA.all = 0x0000;
    EvaRegs.GPTCONA.all = 0x0000;
    EvaRegs.COMCONA.all = 0xA200;

    EALLOW; // Enable EALLOW
    GpioMuxRegs.GPAMUX.all |= 0x003F; // Setting PWM1-6 as primary output pins
    EDIS; // Disable EALLOW
    }


    void F281X_EV1_BLDC_PWM_Update(PWMGEN *p)
    {

    int32 Tmp;
    int16 Period, GPR0_BLDC_PWM;

    // State s1: current flows to motor windings from phase A->B, de-energized phase = C
    if (p->CmtnPointer==0)
    EvaRegs.ACTRA.all = 0x00C2;

    // State s2: current flows to motor windings from phase A->C, de-energized phase = B
    else if (p->CmtnPointer==1)
    EvaRegs.ACTRA.all = 0x0C02;

    // State s3: current flows to motor windings from phase B->C, de-energized phase = A
    else if (p->CmtnPointer==2)
    EvaRegs.ACTRA.all = 0x0C20;

    // State s4: current flows to motor windings from phase B->A, de-energized phase = C
    else if (p->CmtnPointer==3)
    EvaRegs.ACTRA.all = 0x002C;

    // State s5: current flows to motor windings from phase C->A, de-energized phase = B
    else if (p->CmtnPointer==4)
    EvaRegs.ACTRA.all = 0x020C;

    // State s6: current flows to motor windings from phase C->B, de-energized phase = A
    else if (p->CmtnPointer==5)
    EvaRegs.ACTRA.all = 0x02C0;

    // Convert "Period" (Q15) modulation function to Q0
    Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
    Period = (int16)(Tmp>>15); // Q15 -> Q0 (Period)

    // Check PwmActive setting
    if (p->PwmActive==1) // PWM active high
    GPR0_BLDC_PWM = 0x7FFF - p->DutyFunc;

    else if (p->PwmActive==0) // PWM active low
    GPR0_BLDC_PWM = p->DutyFunc;

    // Convert "DutyFunc" or "GPR0_BLDC_PWM" (Q15) duty modulation function to Q0
    Tmp = (int32)Period*(int32)GPR0_BLDC_PWM; // Q15 = Q0*Q15
    EvaRegs.CMPR1 = (int16)(Tmp>>15); // Q15 -> Q0
    EvaRegs.CMPR2 = (int16)(Tmp>>15); // Q15 -> Q0
    EvaRegs.CMPR3 = (int16)(Tmp>>15); // Q15 -> Q0

    }

  • // Convert "Period" (Q15) modulation function to Q0
    Tmp = (int32)p->PeriodMax*(int32)p->MfuncPeriod; // Q15 = Q0*Q15
    Period = (int16)(Tmp>>15); // Q15 -> Q0 (Period)

    // Check PwmActive setting
    if (p->PwmActive==1) // PWM active high
    GPR0_BLDC_PWM = 0x7FFF - p->DutyFunc;

    else if (p->PwmActive==0) // PWM active low
    GPR0_BLDC_PWM = p->DutyFunc;

    // Convert "DutyFunc" or "GPR0_BLDC_PWM" (Q15) duty modulation function to Q0
    Tmp = (int32)Period*(int32)GPR0_BLDC_PWM; // Q15 = Q0*Q15
    EvaRegs.CMPR1 = (int16)(Tmp>>15); // Q15 -> Q0
    EvaRegs.CMPR2 = (int16)(Tmp>>15); // Q15 -> Q0
    EvaRegs.CMPR3 = (int16)(Tmp>>15); // Q15 -> Q0

    Eric:
    周期值确实是Period 这个变量,由Periodmax乘以一个调制比。也就是7500.
    而0x7FFF是一个Q15格式的1, 即1左移15位。
    如注释,当PWM为active high的时候,占空比= 1 - D, 都为Q15格式。
    当PWM为aictive low 的时候,则占空比= D, 也是Q15格式。
  • 谢谢老师,TI老师真棒,搞懂了!
  • 老师,麻烦您能解释一下BLDC3-1例程中速度计算模块,SpeedScaler = 60/(T*Kp*n*BaseRPM),而程序中给的是SpeedScaler = ISR_FREQ/BaseRPM,这个转换过程是怎样完成的?
    麻烦老师了。谢谢您!
  • 在你的原帖回复你了,你参考一下吧。