主题中讨论的其他器件:LAUNCHXL-F2800137
大家好!
我一直在针对特定的电机控制应用使用 LAUNCHXL-F2800137和 BOOSTXL-DRV8323S 进行测试。
现在、一名硬件工程师基于上述板制作了定制 PCB、但来回翻转某些内容。
在 LAUNCHXL 板上、ePWM A 输出进入 DRV8323S 的高侧相位输入。 有关阐释、请参阅下表。
名称 | LAUNCHXL 引脚 |
HIN A | GPIO 0 (EPWM1 A) |
LIN A | GPIO 1 (EPWM1 B) |
HIN B | GPIO 2 (EPWM2 A) |
线 B | GPIO 3 (EPWM2 B) |
HIN C | GPIO 10 (EPWM6 A) |
LIN C | GPIO 11 (EPWM6 B) |
现在、在我们的硬件上、A 和 B 通道被切换(错误)。
问题是、如何在电机控制实验的 hal.c 文件中的 PWM 设置中更改两个通道的极性? 我已将代码放在下面。 我认为它与死区发生器有关。 但我不确定。 有人能说明这两个渠道是如何相互关联的吗? 因为在 PWM 写入函数中、相同的比较值被写入通道 A 和 B。
提前感谢!
PWM 设置功能:
void HAL_setupPWMs(HAL_MTR_Handle handle) { HAL_MTR_Obj *obj = (HAL_MTR_Obj *)handle; uint16_t cnt; uint16_t pwmPeriodCycles = (uint16_t)(MOTORCONFIG_PWM_TBPRD_NUM); uint16_t numPWMTicksPerISRTick = MOTORCONFIG_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); 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); EPWM_enableSyncOutPulseSource(obj->pwmHandle[cnt], EPWM_SYNC_OUT_PULSE_ON_SOFTWARE); EPWM_setClockPrescaler(obj->pwmHandle[cnt], EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); 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); // 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); // 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); // 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); } // 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); // 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); // 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); return; }
写入 PWM 函数:
//! \brief Writes PWM data to the PWM comparators for motor control //! \param[in] handle The hardware abstraction layer (HAL) handle //! \param[in] pPWMData The pointer to the PWM data static inline void HAL_writePWMData(HAL_MTR_Handle handle, HAL_PWMData_t *pPWMData) { HAL_MTR_Obj *obj = (HAL_MTR_Obj *)handle; float32_t period = (float32_t)(EPWM_getTimeBasePeriod(obj->pwmHandle[0])); uint16_t pwmCnt; for(pwmCnt=0; pwmCnt<3; pwmCnt++) { // compute the value float32_t V_pu = -pPWMData->Vabc_pu.value[pwmCnt]; // Negative float32_t V_sat_pu = __fsat(V_pu, 0.5, -0.5); // -0.5~0.5 float32_t V_sat_dc_pu = V_sat_pu + 0.5; // 0~1.0 pPWMData->cmpValue[pwmCnt] = (int16_t)(V_sat_dc_pu * period); // if(pPWMData->cmpValue[pwmCnt] < pPWMData->minCMPValue) { pPWMData->cmpValue[pwmCnt] = pPWMData->minCMPValue; } // write the PWM data value EPWM_setCounterCompareValue(obj->pwmHandle[pwmCnt], EPWM_COUNTER_COMPARE_A, pPWMData->cmpValue[pwmCnt]); EPWM_setCounterCompareValue(obj->pwmHandle[pwmCnt], EPWM_COUNTER_COMPARE_B, pPWMData->cmpValue[pwmCnt]); } return; }