主题中讨论的其他器件: C2000WARE
您好!
该实验示例使用了 PWM 时间周期数宏、我认为这是用于使用 LAUNCHXL-F280025C 的100Mhz 系统时钟。
#define USER_M1_PWM_TBPRD_NUM (uint16_t)(USER_SYSTEM_FREQ_MHz * 1000.0f / USER_M1_PWM_FREQ_kHz / 2.0f)
HAL_setupPWMs ()正在使用该宏设置 pwmPeriodCycles。
uint16_t pwmPeriodCycles =(uint16_t)(USER_M1_PWM_TBPRD_NUM);
我计划在定制电路板上以50kHz PWM 和200MHz 的系统时钟运行。 对于200MHz 系统时钟、这个宏的建议值是多少? 我尝试了几种组合。 例如、如果我在宏中除以4以补偿系统时钟加倍、那么 我的 PWM 输出为 50Hz、但示例未运行。 TBPRD 为1000、CMPA 为500。
如果我尝试将 TBPRD 设置为2500、将 CMPA 设置为1250 (除以1.6)、则我的 输出 PWM 为20kHz、而目标 PWM 为50kHz。
void HAL_setupPWMs(HAL_MTR_Handle handle) { HAL_MTR_Obj *obj = (HAL_MTR_Obj *)handle; uint16_t cnt; uint16_t pwmPeriodCycles = (uint16_t)(USER_M1_PWM_TBPRD_NUM); uint16_t numPWMTicksPerISRTick = USER_M1_NUM_PWM_TICKS_PER_ISR_TICK; // disable the ePWM module time base clock sync signal // to synchronize all of the PWMs SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // turns off the outputs of the EPWM peripherals which will put the power // switches into a high impedance state. EPWM_forceTripZoneEvent(obj->pwmHandle[0], EPWM_TZ_FORCE_EVENT_OST); EPWM_forceTripZoneEvent(obj->pwmHandle[1], EPWM_TZ_FORCE_EVENT_OST); EPWM_forceTripZoneEvent(obj->pwmHandle[2], EPWM_TZ_FORCE_EVENT_OST); #if defined(BSXL8323RS_REVA) || defined(BSXL8323RH_REVB) || \ defined(BSXL8353RS_REVA) || defined(BSXL8316RT_REVA) || \ defined(BSXL3PHGAN_REVA) || defined(HVMTRPFC_REV1P1) || \ defined(DRV8329AEVM_REVA) for(cnt=0; cnt<3; cnt++) { // setup the Time-Base Control Register (TBCTL) EPWM_setTimeBaseCounterMode(obj->pwmHandle[cnt], EPWM_COUNTER_MODE_UP_DOWN); EPWM_disablePhaseShiftLoad(obj->pwmHandle[cnt]); EPWM_setPeriodLoadMode(obj->pwmHandle[cnt], EPWM_PERIOD_DIRECT_LOAD); /* Commented JS EPWM_enableSyncOutPulseSource(obj->pwmHandle[cnt], EPWM_SYNC_OUT_PULSE_ON_SOFTWARE); */ EPWM_setClockPrescaler(obj->pwmHandle[cnt], EPWM_CLOCK_DIVIDER_2, EPWM_HSCLOCK_DIVIDER_2); EPWM_setCountModeAfterSync(obj->pwmHandle[cnt], EPWM_COUNT_MODE_UP_AFTER_SYNC); EPWM_setEmulationMode(obj->pwmHandle[cnt], EPWM_EMULATION_FREE_RUN); // setup the Timer-Based Phase Register (TBPHS) EPWM_setPhaseShift(obj->pwmHandle[cnt], 0); // setup the Time-Base Counter Register (TBCTR) EPWM_setTimeBaseCounter(obj->pwmHandle[cnt], 0); // setup the Time-Base Period Register (TBPRD) // set to zero initially EPWM_setTimeBasePeriod(obj->pwmHandle[cnt], 0); // setup the Counter-Compare Control Register (CMPCTL) EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[cnt], EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[cnt], EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[cnt], EPWM_COUNTER_COMPARE_C, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(obj->pwmHandle[cnt], EPWM_COUNTER_COMPARE_D, EPWM_COMP_LOAD_ON_CNTR_ZERO); #if defined(MOTOR1_ISBLDC) // setup the Action-Qualifier Output A Register (AQCTLA) EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); // setup the Action-qualifier Continuous Software Force Register (AQCSFRC) EPWM_setActionQualifierContSWForceAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_B, EPWM_AQ_SW_OUTPUT_LOW); // setup the Dead-Band Generator Control Register (DBCTL) EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_RED, false); EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_FED, false); #else //!MOTOR1_ISBLDC #if defined(MOTOR1_DCLINKSS) // setup the Action-Qualifier Output A Register (AQCTLA) EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); #else // !(MOTOR1_DCLINKSS) // setup the Action-Qualifier Output A Register (AQCTLA) EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(obj->pwmHandle[cnt], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); #endif // !(MOTOR1_DCLINKSS) // setup the Dead-Band Generator Control Register (DBCTL) EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_RED, true); EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_FED, true); // select EPWMA as the input to the dead band generator EPWM_setRisingEdgeDeadBandDelayInput(obj->pwmHandle[cnt], EPWM_DB_INPUT_EPWMA); // configure the right polarity for active high complementary config. EPWM_setDeadBandDelayPolarity(obj->pwmHandle[cnt], EPWM_DB_RED, EPWM_DB_POLARITY_ACTIVE_HIGH); EPWM_setDeadBandDelayPolarity(obj->pwmHandle[cnt], EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); // setup the Dead-Band Rising Edge Delay Register (DBRED) EPWM_setRisingEdgeDelayCount(obj->pwmHandle[cnt], MTR1_PWM_DBRED_CNT); // setup the Dead-Band Falling Edge Delay Register (DBFED) EPWM_setFallingEdgeDelayCount(obj->pwmHandle[cnt], MTR1_PWM_DBFED_CNT); #endif //!MOTOR1_ISBLDC // setup the PWM-Chopper Control Register (PCCTL) EPWM_disableChopper(obj->pwmHandle[cnt]); // setup the Trip Zone Select Register (TZSEL) EPWM_disableTripZoneSignals(obj->pwmHandle[cnt], HAL_TZSEL_SIGNALS_ALL); } // BSXL8323RS_REVA || BSXL8323RH_REVB || BSXL8353RS_REVA || \ // BSXL8316RT_REVA || BSXL3PHGAN_REVA || HVMTRPFC_REV1P1 || \ // DRV8329AEVM_REVA #else #error The PWM is not configured for motor_1 control #endif // boards #if defined(MOTOR1_ISBLDC) // setup the Event Trigger Selection Register (ETSEL) EPWM_setInterruptSource(obj->pwmHandle[0], EPWM_INT_TBCTR_ZERO); EPWM_disableInterrupt(obj->pwmHandle[0]); EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO); EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A); EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_B, EPWM_SOC_TBCTR_U_CMPB); EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_B); #elif defined(MOTOR1_DCLINKSS) // setup the Event Trigger Selection Register (ETSEL) EPWM_setInterruptSource(obj->pwmHandle[0], EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(obj->pwmHandle[0]); EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_A, EPWM_SOC_TBCTR_D_CMPC); EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A); // ADC SOC trigger for the 1st dc-link current sampling EPWM_setADCTriggerSource(obj->pwmHandle[1], EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPC); EPWM_enableADCTrigger(obj->pwmHandle[1], EPWM_SOC_A); // ADC SOC trigger for the 2nd dc-link current sampling EPWM_setADCTriggerSource(obj->pwmHandle[1], EPWM_SOC_B, EPWM_SOC_TBCTR_U_CMPD); EPWM_enableADCTrigger(obj->pwmHandle[1], EPWM_SOC_B); // ADC SOC trigger for the 3rd dc-link current sampling EPWM_setADCTriggerSource(obj->pwmHandle[2], EPWM_SOC_A, EPWM_SOC_TBCTR_D_CMPC); EPWM_enableADCTrigger(obj->pwmHandle[2], EPWM_SOC_A); // ADC SOC trigger for the 4th dc-link current sampling EPWM_setADCTriggerSource(obj->pwmHandle[2], EPWM_SOC_B, EPWM_SOC_TBCTR_D_CMPD); EPWM_enableADCTrigger(obj->pwmHandle[2], EPWM_SOC_B); #else //!(MOTOR1_ISBLDC || MOTOR1_DCLINKSS) // setup the Event Trigger Selection Register (ETSEL) EPWM_setInterruptSource(obj->pwmHandle[0], EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(obj->pwmHandle[0]); EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_A, EPWM_SOC_TBCTR_D_CMPC); EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A); #endif // !(MOTOR1_ISBLDC || MOTOR1_DCLINKSS) // setup the Event Trigger Prescale Register (ETPS) if(numPWMTicksPerISRTick > 15) { numPWMTicksPerISRTick = 15; } else if(numPWMTicksPerISRTick < 1) { numPWMTicksPerISRTick = 1; } EPWM_setInterruptEventCount(obj->pwmHandle[0], numPWMTicksPerISRTick); EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0], EPWM_SOC_A, numPWMTicksPerISRTick); EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0], EPWM_SOC_B, numPWMTicksPerISRTick); #if defined(MOTOR1_DCLINKSS) EPWM_setADCTriggerEventPrescale(obj->pwmHandle[1], EPWM_SOC_A, numPWMTicksPerISRTick); EPWM_setADCTriggerEventPrescale(obj->pwmHandle[1], EPWM_SOC_B, numPWMTicksPerISRTick); EPWM_setADCTriggerEventPrescale(obj->pwmHandle[2], EPWM_SOC_A, numPWMTicksPerISRTick); EPWM_setADCTriggerEventPrescale(obj->pwmHandle[2], EPWM_SOC_B, numPWMTicksPerISRTick); #endif //MOTOR1_DCLINKSS // setup the Event Trigger Clear Register (ETCLR) EPWM_clearEventTriggerInterruptFlag(obj->pwmHandle[0]); EPWM_clearADCTriggerFlag(obj->pwmHandle[0], EPWM_SOC_A); EPWM_clearADCTriggerFlag(obj->pwmHandle[0], EPWM_SOC_B); // since the PWM is configured as an up/down counter, the period register is // set to one-half of the desired PWM period EPWM_setTimeBasePeriod(obj->pwmHandle[0], pwmPeriodCycles); EPWM_setTimeBasePeriod(obj->pwmHandle[1], pwmPeriodCycles); EPWM_setTimeBasePeriod(obj->pwmHandle[2], pwmPeriodCycles); // write the PWM data value for ADC trigger EPWM_setCounterCompareValue(obj->pwmHandle[0], EPWM_COUNTER_COMPARE_C, 10); // write the PWM data value for ADC trigger #if defined(MOTOR1_DCLINKSS) EPWM_clearADCTriggerFlag(obj->pwmHandle[1], EPWM_SOC_A); EPWM_clearADCTriggerFlag(obj->pwmHandle[1], EPWM_SOC_B); EPWM_clearADCTriggerFlag(obj->pwmHandle[2], EPWM_SOC_A); EPWM_clearADCTriggerFlag(obj->pwmHandle[2], EPWM_SOC_B); EPWM_setCounterCompareValue(obj->pwmHandle[1], EPWM_COUNTER_COMPARE_C, pwmPeriodCycles>>1); EPWM_setCounterCompareValue(obj->pwmHandle[1], EPWM_COUNTER_COMPARE_D, pwmPeriodCycles>>1); EPWM_setCounterCompareValue(obj->pwmHandle[2], EPWM_COUNTER_COMPARE_C, pwmPeriodCycles>>1); EPWM_setCounterCompareValue(obj->pwmHandle[2], EPWM_COUNTER_COMPARE_D, pwmPeriodCycles>>1); #endif //MOTOR1_DCLINKSS // enable the ePWM module time base clock sync signal SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); return; } // end of HAL_setupPWMs() function