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.

TMS320F28377D: EPWM1无法输出高精度PWM(hrpwm)

Part Number: TMS320F28377D
Other Parts Discussed in Thread: SYSCONFIG

工程师们好,我最近试图使用EPWM1输出60kHz左右的高精度PWM,根据数据手册进行配置,但是使用频率计测试发现实际输出并非高精度(步长大概70hz)。以下是我的EPWM相关的代码,麻烦工程师们帮我看看哪里有问题:

void EPwm1_Gpio_Init(void)
{
    EALLOW;

    //
    // Disable internal pull-up for the selected output pins
    // for reduced power consumption
    // Pull-ups can be enabled or disabled by the user.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;    // Disable pull-up on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;    // Disable pull-up on GPIO1 (EPWM1B)

    //
    // Configure EPWM-1 pins using GPIO regs
    // This specifies which of the possible GPIO pins will be EPWM1 functional
    // pins.
    // Comment out other unwanted lines.
    //
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B

    EDIS;

    // Control signal
    GPIO_SetupPinMux(90, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(90, GPIO_OUTPUT, GPIO_PULLUP);
    EPWM1_OUTPUT = 0;

}


void HRPWM_Config(float fre, float duty)
{

    float deadband;
    deadband = 2 * (0.5 - duty) * 1.0/(2*fre)/(1.0/TB_CLK/2.0);

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;   // Disable TBCLK within the EPWM
    EDIS;

    PWM_status = SFO_INCOMPLETE;

    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;                  // TBPRD and CC registers must be configured for shadow loads
    EPwm1Regs.TBPRD = TB_CLK/(2*fre);                       // Set timer period
    EPwm1Regs.CMPA.bit.CMPA = (TB_CLK/(2*fre))*0.5;        // Set Compare
    EPwm1Regs.CMPA.bit.CMPAHR = (1 << 8);                   // Set MEP
    EPwm1Regs.CMPB.bit.CMPB = (TB_CLK/(2*fre))*0.5;        // Set Compare
    EPwm1Regs.CMPB.all |= 1;
    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;                     // Phase is 0
    EPwm1Regs.TBCTR = 0x0000;                               // Clear counter

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;          // Count Mode

    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;                // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 2;

    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO_PRD;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;             // TBPRD and CC registers must be configured for shadow loads
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;             // TBPRD and CC registers must be configured for shadow loads

//    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;                      // Set actions
//    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;                    // Set actions
    EPwm1Regs.AQCTLA.bit.CAU = AQ_NO_ACTION;                      // Set actions
    EPwm1Regs.AQCTLA.bit.CAD = AQ_NO_ACTION;                    // Set actions

    EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;                      // Set actions
    EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;                    // Set actions

    EPwm1Regs.TBCTL.bit.SYNCOSEL = 3;                       // CAP signal
    EPwm1Regs.TBCTL2.bit.SYNCOSELX = 3;                     // CAP signal

    EALLOW;
    EPwm1Regs.HRCNFG.all = 0x0;
    EPwm1Regs.HRCNFG.bit.EDGMODE = 3;                       // MEP control on both edges
    EPwm1Regs.HRCNFG.bit.CTLMODE = 0;
    EPwm1Regs.HRCNFG.bit.HRLOAD = 2;                        // Load on either CTR = Zero or CTR = PRD
    EPwm1Regs.HRCNFG.bit.EDGMODEB = 3;                      // MEP control on both edges
    EPwm1Regs.HRCNFG.bit.CTLMODEB = 0;
    EPwm1Regs.HRCNFG.bit.HRLOADB = 2;                       // Load on either CTR = Zero or CTR = PRD
    EPwm1Regs.HRCNFG.bit.AUTOCONV = 1;                      // The SFO library function automatically updates the HRMSTEP register with the appropriate MEP scale factor

    EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 0;
    EPwm1Regs.HRPCTL.bit.HRPE = 1;                          // High resolution period enabled
    EPwm1Regs.TBCTL.bit.SWFSYNC = 1;


//    // test
//    EPwm1Regs.HRCNFG.all = 0x0040;
//    EPwm1Regs.HRPWR.all = 0x0000;
//    EPwm1Regs.HRMSTEP.all = 0x0000;
//    EPwm1Regs.HRCNFG2.all = 0x0000;
//    EPwm1Regs.HRPCTL.all = 0x0005;


    // Active Low PWMs - Setup Deadband
    EPwm1Regs.DBCTL.bit.OUT_MODE = 3;
    EPwm1Regs.DBCTL.bit.POLSEL = 2;
    EPwm1Regs.DBCTL.bit.IN_MODE = 0;
    EPwm1Regs.DBCTL.bit.DEDB_MODE = 0;
    EPwm1Regs.DBCTL.bit.OUTSWAP = 0;
    EPwm1Regs.DBCTL.bit.SHDWDBREDMODE = 1;
    EPwm1Regs.DBCTL.bit.SHDWDBFEDMODE = 1;
    EPwm1Regs.DBCTL.bit.LOADFEDMODE = 1;
    EPwm1Regs.DBCTL.bit.LOADREDMODE = 1;
    EPwm1Regs.DBCTL.bit.HALFCYCLE = 1;
    EPwm1Regs.DBRED.bit.DBRED = (int)deadband;
    EPwm1Regs.DBREDHR.bit.DBREDHR = (int)((deadband - (int)deadband) * 55 + 0.5) << 8;
    EPwm1Regs.DBFED.bit.DBFED = (int)deadband;
    EPwm1Regs.DBFEDHR.bit.DBFEDHR = (int)((deadband - (int)deadband) * 55 + 0.5) << 8;

    EPwm1Regs.HRCNFG2.bit.EDGMODEDB = 3;                    // MEP control of both edges
    EPwm1Regs.HRCNFG2.bit.CTLMODEDBFED = 0;                 // Load on ZERO
    EPwm1Regs.HRCNFG2.bit.CTLMODEDBRED = 0;                 // Load on ZERO

    EDIS;

}


void HRPWM_setting(float fre,float duty)
{

    float deadband;
    deadband = 2 * (0.5 - duty) * 1.0/(2*fre)/(1.0/TB_CLK/2.0);

    PWM_status = SFO(); // in background, MEP calibration module continuously updates MEP_ScaleFactor

    if(PWM_status == SFO_ERROR)
    {
        error();   // SFO function returns 2 if an error occurs & # of
    }

    EPwm1Regs.TBPRD = TB_CLK/(2*fre);                       // Set timer period
    EPwm1Regs.CMPA.bit.CMPA = (TB_CLK/(2*fre))*0.5;        // Setup compare

    EPwm1Regs.DBRED.bit.DBRED = (int)deadband;
    EPwm1Regs.DBFED.bit.DBFED = (int)deadband;

}

EPWM模块初始化完成之后寄存器的值如下:

此外,我还尝试使用sysconfig进行配置,奇怪的是只要使能HRPWM功能就无法选择引脚GPIO0和GPIO1(EPWM1A和EPWM1B)。通过数据手册我确认了EPWM1是支持HRPWM的。

未开启HRPWM,EPWM1正常选择,如下图所示

开启HRPWM,EPWM1不能被选择,如下图所示