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.

[参考译文] TMS320F28388D:如果配置了 ePWM1、CLB 将不工作

Guru**** 608295 points
Other Parts Discussed in Thread: SYSCONFIG
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1165231/tms320f28388d-clb-will-not-work-if-epwm1-is-configured

器件型号:TMS320F28388D
Thread 中讨论的其他器件:SysConfig

大家好、我遇到了 CLB 和 ePWM 模块的问题。 我已将 CLB 配置为 使用 CLB TILE4创建辅助时钟 、并且可以使用 SysConfig 独立项目在示波器中捕获时钟。 然而、当我将项目集成到一个电机控制程序中、此程序像在以下代码中那样配置 ePWM1模块时、将不再生成时钟。 我发现 第32行中的函数 InitEPwmTcExamples(0)就是原因。 如何解决此问题?

感谢您花时间阅读本文档!

#include <Main.h>

volatile struct EPWM_REGS *ePWM[] ={ &EPwm1Regs,
                                     &EPwm2Regs,
                                     &EPwm3Regs,
                                     &EPwm4Regs,
                                     &EPwm5Regs,
                                     &EPwm6Regs,
                                     &EPwm7Regs,
                                     &EPwm8Regs,
                                     &EPwm9Regs,
                                     &EPwm10Regs,
                                     &EPwm11Regs,
                                     &EPwm12Regs };

void ConfigEPWM(void)
{
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;
    EALLOW;
    ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV = 0;
    EDIS;

    EALLOW;
    EPwm1Regs.TZFRC.bit.OST = 1;
    EPwm2Regs.TZFRC.bit.OST = 1;
    EPwm3Regs.TZFRC.bit.OST = 1;
    EDIS;


    InitEPwmTcExample(0);
    InitEPwmTcExample(1);
    InitEPwmTcExample(2);


    EPwm1Regs.ETSEL.bit.SOCAEN = 1;
    EPwm1Regs.ETSEL.bit.SOCASEL = 1;
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;


    EPWM_disablePhaseShiftLoad(EPWM1_BASE);
    EPWM_setPhaseShift(EPWM1_BASE, 0U);

    EPWM_enableSyncOutPulseSource(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);

    configurePhase(EPWM2_BASE, EPWM1_BASE, 0);
    configurePhase(EPWM3_BASE, EPWM1_BASE, 0);

    EPWM_setSyncInPulseSource(EPWM2_BASE, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
    EPWM_setSyncInPulseSource(EPWM3_BASE, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);

    EPWM_enablePhaseShiftLoad(EPWM2_BASE);
    EPWM_enablePhaseShiftLoad(EPWM3_BASE);

    EALLOW;

    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO4 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1;

    GpioCtrlRegs.GPAPUD.bit.GPIO5 = 1;
    GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1;
    EDIS;

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;

    GPIO_setDirectionMode(84, GPIO_DIR_MODE_OUT); // Enable PWM EN (PWMEN_INV - SN74LVCC3245A) refer to CJ_GPIO.c
    PWM_EN;
}




void InitEPwmTcExample(Uint16 module)
{
    ePWM[module]->TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    ePWM[module]->TBCTL.bit.PHSEN = TB_DISABLE;
    ePWM[module]->TBPHS.bit.TBPHS = 0x0000;
    ePWM[module]->TBCTL.bit.HSPCLKDIV = TB_DIV1;
    ePWM[module]->TBCTL.bit.CLKDIV = TB_DIV1;
    ePWM[module]->TBPRD = 6250;
    ePWM[module]->TBCTR = 0x0000;
    ePWM[module]->AQCTLA.bit.CAU = AQ_CLEAR;
    ePWM[module]->AQCTLA.bit.CAD = AQ_SET;
    ePWM[module]->DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
    ePWM[module]->DBCTL.bit.IN_MODE = DBA_ALL;
    ePWM[module]->DBRED.bit.DBRED = 660;
    ePWM[module]->DBFED.bit.DBFED = 660;
    ePWM[module]->DBCTL.bit.POLSEL = DB_ACTV_LOC;
    ePWM[module]->CMPA.bit.CMPA = 3124;
}


void configurePhase(uint32_t base, uint32_t masterBase, uint16_t phaseVal)
{
    uint32_t readPrdVal, phaseRegVal;

    readPrdVal = EPWM_getTimeBasePeriod(masterBase);

    if((HWREGH(base + EPWM_O_TBCTL) & 0x3U) == EPWM_COUNTER_MODE_UP_DOWN)
    {
        phaseRegVal = (2U * readPrdVal * phaseVal) / 360U;
    }
    else if((HWREGH(base + EPWM_O_TBCTL) & 0x3U) < EPWM_COUNTER_MODE_UP_DOWN)
    {
        phaseRegVal = (readPrdVal * phaseVal) / 360U;
    }

    EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_SYNC);
    EPWM_setPhaseShift(base, phaseRegVal);
    EPWM_setTimeBaseCounter(base, phaseRegVal);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Xin Chao Duc、

    我在 InitEPwmTcExample 函数中看不到会导致初始化 CLB 模块问题的任何内容。 在您的新代码中、CLB 在哪里被实例化和启用? 我在您发布的代码中看不到任何 CLB 调用。 我不认为 EPWM 会阻止 CLB 工作、除非可能存在引脚/GPIO 冲突?

    您是否仍在电机控制程序中使用之前的 SysConfig 文件? 您至少需要在新项目中包含一个 syscfg 文件、因为它包含 CLB 工具配置生成的源文件。 此外、请确保在主代码中启用 CLB

    此致、

    Peter

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Xin Chao Peter、

    感谢您的快速响应!

    以下代码是我对 CLB 的初始化。 因为源代码很长、所以我不会在这里包含所有源代码。 我不在工程中使用 SysConfig 文件、只需将 SysConfig 生成的 CLB_config.c 和 clb_config.h 文件复制到工程并进行编译即可。

    此致、

    #include "driverlib.h"
    #include "device.h"
    #include "clb_config.h"
    #include "clb.h"
    
    void main(void)
     {
        //
        // Initialize device clock and peripherals
        //
        Device_init();
    
        //
        // Turn on the module clock.
        //
        Interrupt_disableMaster();
    
        //
        // Initialize PIE and clear PIE registers. Disables CPU interrupts.
        //
        Interrupt_initModule();
    
        //
        // Disable pin locks and enable internal pull-ups.
        //
        Device_initGPIO();
    
        //
        // Initialize the PIE vector table with pointers to the shell Interrupt
        // Service Routines (ISR).
        //
        Interrupt_initVectorTable();
    
        Interrupt_register(INT_SPIB_RX, &spiRxFIFOISR);
    
        ConfigEPWM();
    
        Interrupt_register(INT_SPIB_RX, &spiRxFIFOISR);
    
        Interrupt_enable(INT_SPIB_RX);
    
        Interrupt_enable(INT_SPIB_RX);
        Interrupt_enableMaster();
    
        init();
    
        DEVICE_DELAY_US(800L);
        
        startOperation();
    
        while(1){}
    }
    
    void init(void)
    {
        SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM4);
    
        configEPWM4();
    
        setupGPIO();
        configXBAR();
    
        setupPeriph();
    
        SPI_disableModule(SPIB_BASE);
        SPI_disableInterrupt(SPIB_BASE, SPI_INT_RXFF);
    
        SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_RXFF);
        SPI_enableInterrupt(SPIB_BASE, SPI_INT_RXFF);
    
        SPI_enableModule(SPIB_BASE);
    
        GPIO_writePin(34, 0);
    
        GPIO_writePin(32, 1);
    
        SysCtl_delay(2000000L);
    }
    
    void setupGPIO(void)
    {
        GPIO_setMasterCore(6, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_6_EPWM4A);
        GPIO_setDirectionMode(6, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(6, GPIO_PIN_TYPE_STD);
    
        GPIO_setMasterCore(7, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_7_EPWM4B);
        GPIO_setDirectionMode(7, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(7, GPIO_PIN_TYPE_STD);
    
        GPIO_setMasterCore(24, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_24_SPIB_SIMO);
        GPIO_setQualificationMode(24, GPIO_QUAL_ASYNC);
    
        GPIO_setMasterCore(25, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_25_SPIB_SOMI);
        GPIO_setQualificationMode(25, GPIO_QUAL_ASYNC);
    
        GPIO_setMasterCore(26, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_26_SPIB_CLK);
        GPIO_setQualificationMode(26, GPIO_QUAL_ASYNC);
    
        GPIO_setMasterCore(27, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_27_SPIB_STEN);
        GPIO_setQualificationMode(27, GPIO_QUAL_ASYNC);
    
        GPIO_setMasterCore(32, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_32_GPIO32);
        GPIO_setDirectionMode(32, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(32, GPIO_PIN_TYPE_STD);
    
        GPIO_setMasterCore(34, GPIO_CORE_CPU1);
        GPIO_setPinConfig(GPIO_34_GPIO34);
        GPIO_setDirectionMode(34, GPIO_DIR_MODE_OUT);
        GPIO_setPadConfig(34, GPIO_PIN_TYPE_STD);
    }
    
    void setupPeriph(void)
    {
        Interrupt_register(INT_CLB4, &clb4ISR);
        Interrupt_enable(INT_CLB4);
    
        resetCLB();
    
        initTILE4(CLB4_BASE);
    
        CLB_enableCLB(CLB4_BASE);
    
        //
        // Select Global input instead of local input for CLB IN
        //
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN0, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN1, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN2, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN3, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN4, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN5, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN6, CLB_LOCAL_IN_MUX_GLOBAL_IN);
        CLB_configLocalInputMux(CLB4_BASE, CLB_IN7, CLB_LOCAL_IN_MUX_GLOBAL_IN);
    
        CLB_configGlobalInputMux(CLB4_BASE, CLB_IN0, CLB_GLOBAL_IN_MUX_EPWM1A);
        CLB_configGlobalInputMux(CLB4_BASE, CLB_IN1, CLB_GLOBAL_IN_MUX_CLB_AUXSIG0);
        CLB_configGlobalInputMux(CLB4_BASE, CLB_IN7, CLB_GLOBAL_IN_MUX_EPWM1A);
    
        CLB_configGPInputMux(CLB4_BASE, CLB_IN0, CLB_GP_IN_MUX_GP_REG);
        CLB_configGPInputMux(CLB4_BASE, CLB_IN1, CLB_GP_IN_MUX_EXTERNAL);
        CLB_configGPInputMux(CLB4_BASE, CLB_IN7, CLB_GP_IN_MUX_GP_REG);
    
        XBAR_setCLBMuxConfig(XBAR_AUXSIG0, XBAR_CLB_MUX01_INPUTXBAR1);
        XBAR_enableCLBMux(XBAR_AUXSIG0, XBAR_MUX01);
    
        CLB_selectInputFilter(CLB4_BASE, CLB_IN0, CLB_FILTER_NONE);
        CLB_selectInputFilter(CLB4_BASE, CLB_IN1, CLB_FILTER_RISING_EDGE);
        CLB_selectInputFilter(CLB4_BASE, CLB_IN7, CLB_FILTER_NONE);
    
        CLB_enableSynchronization(CLB4_BASE, CLB_IN0);
        CLB_enableSynchronization(CLB4_BASE, CLB_IN1);
        CLB_enableSynchronization(CLB4_BASE, CLB_IN7);
    
        //
        // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
        //
        EINT;
        ERTM;
    
        CLB_clearInterruptTag(CLB4_BASE);
    
        //
        // Enable CLB4 OUT0, OUT2
        //
        CLB_setOutputMask(CLB4_BASE, CLB_OUTPUT_00 | CLB_OUTPUT_02, true);
    
        SPI_disableModule(SPIB_BASE);
        SPI_disableLoopback(SPIB_BASE);
    
        SPI_setConfig(SPIB_BASE, DEVICE_LSPCLK_FREQ, SPI_PROT_POL1PHA0,
                      SPI_MODE_SLAVE, 500000, 9);
    
        SPI_clearInterruptStatus(SPIB_BASE, SPI_INT_RX_OVERRUN |
        SPI_INT_RX_DATA_TX_EMPTY | SPI_INT_RXFF |
        SPI_INT_RXFF_OVERFLOW | SPI_INT_TXFF);
        SPI_enableFIFO(SPIB_BASE);
        SPI_setFIFOInterruptLevel(SPIB_BASE, SPI_FIFO_TX3, SPI_FIFO_RX3);
        SPI_setEmulationMode(SPIB_BASE, SPI_EMULATION_FREE_RUN);
        SPI_enableModule(SPIB_BASE);
        SPI_resetTxFIFO(SPIB_BASE);
        SPI_resetRxFIFO(SPIB_BASE);
    
        SPI_enableInterrupt(SPIB_BASE, SPI_INT_RX_OVERRUN |
        SPI_INT_RX_DATA_TX_EMPTY | SPI_INT_RXFF | SPI_INT_RXFF_OVERFLOW);
    }
    
    void startOperation(void)
    {
        EALLOW;
        HWREG(CLB4_BASE + CLB_LOGICCTL + CLB_O_LOAD_EN) |= CLB_LOAD_EN_GLOBAL_EN
                | CLB_LOAD_EN_STOP;
    
        __asm(" RPT #10 || NOP");
        CLB_setOutputMask(CLB4_BASE, CLB_OUTPUT_00 | CLB_OUTPUT_02, true);
        __asm(" RPT #10 || NOP");
        CLB_setGPREG(CLB4_BASE, 0x81);
    
        EALLOW;
    }
    
    void configXBAR(void)
    {
        XBAR_setInputPin(INPUTXBAR_BASE, XBAR_INPUT1, 24);
    }
    
    void configEPWM4(void)
    {
    
        //
        // Set the PWMA and B high as default values of tformat clk.
        // Action on TZ1
        //
        EPWM_setTripZoneAction(EPWM4_BASE, EPWM_TZ_ACTION_EVENT_TZA,
                               EPWM_TZ_ACTION_HIGH);
    
        //
        // Action on TZ1
        //
        EPWM_setTripZoneAction(EPWM4_BASE, EPWM_TZ_ACTION_EVENT_TZB,
                               EPWM_TZ_ACTION_HIGH);
    
        //
        // Forces a Trip Zone event
        //
        EPWM_forceTripZoneEvent(EPWM4_BASE, EPWM_TZ_FORCE_EVENT_OST);
    }
    
    void resetCLB(void)
    {
        CLB_setGPREG(CLB4_BASE, 0);
    
        //
        // Turn OFF the CLB functionality
        //
        EALLOW;
        HWREG(CLB4_BASE + CLB_LOGICCTL + CLB_O_LOAD_EN) = 0;
        EDIS;
    
        //
        // Clear Counters - this will clear counter REGs. Add_shift_on_even_en
        // should be Zero for this to take effect.
        //
        CLB_writeInterface(CLB4_BASE, CLB_ADDR_COUNTER_0_LOAD, 0x0);
        CLB_writeInterface(CLB4_BASE, CLB_ADDR_COUNTER_1_LOAD, 0x0);
        CLB_writeInterface(CLB4_BASE, CLB_ADDR_COUNTER_2_LOAD, 0x0);
    
        CLB_setOutputMask(CLB4_BASE, 0, false);
    
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Duc:

    专题专家已不在办公室 , 将 于11月2日返回。 请等待回复延迟

    最棒的

    Uttam

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    在我使用 CLB 单元时、我得到了这样的经验:如果将 PWM 单元用作 PWM、则不能在 CLB 中使用 PWM 通道。 如果您希望使用 ePWM1模块的通道 B 作为 CLB 逻辑块的输出、则只有在不使用 ePWM1模块作为 PWM 时、该功能才有效。

    在我的项目中、我想使用 ePWM6单元的通道 B 作为 CLB-TILE 6的输出、并且我想使用通道 A 作为 PWM 信号发生器。 CLB 输出仅在我未将 ePWM6用作 PWM 时才起作用。

    因此、如果我答对了、就不能在 CLB 中使用 PWM 通道、也不能在 PWM 应用中使用另一个通道。

    此致、

    Christian

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Xin Chao Duc、

    在您以前能够生成时钟输出的独立代码中、您是否使用了通过生成的 CLB 源文件传输的相同过程、或者您是否直接拥有 SysConfig 文件。 我听说过客户偶尔会遇到类似的构建问题。

    感谢您提供代码。 为了帮助我澄清您的问题、您说您使用 CLB4和 EPWM4正确生成时钟输出? 请参阅 TRM 中的下表、其中显示了 CLB4的外设输出覆盖表。  

    然后、您会说、当您配置 EPWM1时、您无法在最初配置的 EPWM4上看到任何输出。 我的理解是否正确?

    此致、

    Peter

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Christian:

    我看到你说什么。 解决此问题的方法是将使用的 ePWM 模块的两个通道路由到 CLB 中。 对于您只想用作 PWM 的 ePWM 通道、您可以将输入直接连接到 CLB 输出、基本上通过信号。 由于直通会直接输出 ePWM 输出、因此您仍然可以访问 ePWM 子模块

    此致、

    Peter