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.

[参考译文] TMS320F280025:FCL -使用 OC 关断

Guru**** 2540510 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1265647/tms320f280025-fcl---use-oc-shutdown

器件型号:TMS320F280025

您好!

这里有一个电机控制器、基于 F280025微控制器(评估板)。 我成功使用了它  

UniversalMotorControl SDK 和引脚映射的通用软件。

今天、我尝试了 FCL、引脚映射 与  UniversalMotorControl SDK 中不同、

所以我试图将 FCL 示例中的所有内容更改为 UniversalMotorControl SDK 中的 GPIO 映射

到目前为止它的工作原理、我可以使用位置控制并可以触发 INPUT_XBAR1上的关断。

只有过流触发不起作用、我真的不明白、什么与 UniversalMotorControl SDK 中的不同。

查看 F280025的数据表时、我无法真正了解 ADC 是如何连接到比较器模块的、  

我认为可能会出现问题。 我尝试通过将 motorVars.currentLimit 设置得足够低来主动触发 OC、并以足够高的电流阻止电机进行速度控制、这在通用电机控制 SDK 项目中可行、但在 FCL 项目中无效。  我有任何想法、哪里会出错、以及在哪里可以找到 ADC 连接的多路复用器、

比较器模块 CMPSS?

我在 FCL 项目中进行了以下设置:

motor_drive_user.h:

#define M_IU_ADC_BASE         ADCA_BASE //ADCC_BASE           //C2,  S  Set up based board
#define M_IV_ADC_BASE         ADCC_BASE //ADCA_BASE           //A2,  L: Set up based board
#define M_IW_ADC_BASE         ADCC_BASE //ADCC_BASE           //C4,  L: Set up based board
#define M_VDC_ADC_BASE        ADCC_BASE //ADCA_BASE           //A11, S: Set up based board

#define M_IU_ADCRESULT_BASE   ADCARESULT_BASE     //C2,  S: Set up based board
#define M_IV_ADCRESULT_BASE   ADCCRESULT_BASE     //A2,  L: Set up based board
#define M_IW_ADCRESULT_BASE   ADCCRESULT_BASE     //C4,  L: Set up based board
#define M_VDC_ADCRESULT_BASE  ADCCRESULT_BASE //ADCARESULT_BASE     //A11, S: Set up based board

#define M_IU_ADC_CH_NUM       ADC_CH_ADCIN11 //ADC_CH_ADCIN2       //C2,  S: Set up based board
#define M_IV_ADC_CH_NUM       ADC_CH_ADCIN4 //ADC_CH_ADCIN2       //A2,  L: Set up based board
#define M_IW_ADC_CH_NUM       ADC_CH_ADCIN7 //ADC_CH_ADCIN4       //C4,  L: Set up based board
#define M_VDC_ADC_CH_NUM      ADC_CH_ADCIN6 //ADC_CH_ADCIN11      //A11, S: Set up based board

#define M_IU_ADC_SOC_NUM      ADC_SOC_NUMBER1 //ADC_SOC_NUMBER1     //C2,  S: Set up based board
#define M_IV_ADC_SOC_NUM      ADC_SOC_NUMBER1 //ADC_SOC_NUMBER0     //A2,  L: Set up based board
#define M_IW_ADC_SOC_NUM      ADC_SOC_NUMBER2 //ADC_SOC_NUMBER0     //C4,  L: Set up based board
#define M_VDC_ADC_SOC_NUM     ADC_SOC_NUMBER6 //ADC_SOC_NUMBER1     //A11, S: Set up based board

#define M_IU_ADC_PPB_NUM      ADC_PPB_NUMBER1 //ADC_PPB_NUMBER2     // S: Set up based board
#define M_IV_ADC_PPB_NUM      ADC_PPB_NUMBER1 //ADC_PPB_NUMBER1     // L: Set up based board
#define M_IW_ADC_PPB_NUM      ADC_PPB_NUMBER2 //ADC_PPB_NUMBER1     // L: Set up based board
#define M_VDC_ADC_PPB_NUM     ADC_PPB_NUMBER3     // S: Set up based board //SHOULD NOT BE THE SAME AS IV, SINCE OTHERWISE IT IS OVERWRITEN!

#define M_U_CMPSS_BASE        CMPSS1_BASE         // S: Set up based board
#define M_V_CMPSS_BASE        CMPSS3_BASE //CMPSS1_BASE         // L: Set up based board
#define M_W_CMPSS_BASE        CMPSS1_BASE //CMPSS3_BASE         // L: Set up based board
#define M_VDC_CMPSS_BASE      CMPSS2_BASE         // S: Set up based board

#define M_ADC_SAMPLE_WINDOW   12                  // ADC Sample window

#define M_ADC_TRIGGER_SOC     ADC_TRIGGER_EPWM1_SOCA //ADC_TRIGGER_EPWM1_SOCA  // M: Set up based board

sensored_foc_hal.c:

//
// Configure ADC
//
void HAL_setupADCs(HAL_Handle handle)
{
    HAL_Obj *obj = (HAL_Obj *)handle;

    // Enable internal voltage reference
    ADC_setVREF(obj->adcHandle[0], ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
    ADC_setVREF(obj->adcHandle[1], ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    // setup ADC modules A, B
    // Set main clock scaling factor (50MHz max clock for the ADC module)
    ADC_setPrescaler(obj->adcHandle[0], ADC_CLK_DIV_2_0);
    ADC_setPrescaler(obj->adcHandle[1], ADC_CLK_DIV_2_0);

    // set the ADC interrupt pulse generation to end of conversion
    ADC_setInterruptPulseMode(obj->adcHandle[0], ADC_PULSE_END_OF_CONV);
    ADC_setInterruptPulseMode(obj->adcHandle[1], ADC_PULSE_END_OF_CONV);

    // set priority of SOCs
    ADC_setSOCPriority(obj->adcHandle[0], ADC_PRI_ALL_HIPRI);
    ADC_setSOCPriority(obj->adcHandle[1], ADC_PRI_ALL_HIPRI);

    // enable the ADC
    ADC_enableConverter(obj->adcHandle[0]);
    ADC_enableConverter(obj->adcHandle[1]);

    // delay to allow ADCs to power up
    SysCtl_delay(1000U);

    //
    // Shunt Motor Currents (M1-Iu) @ B2->SOCB0
    // SOC0 will convert pin B2, sample window in SYSCLK cycles
    // trigger on ePWM6 SOCA/C
    ADC_setupSOC(M_IU_ADC_BASE, M_IU_ADC_SOC_NUM,
                 M_ADC_TRIGGER_SOC, M_IU_ADC_CH_NUM, M_ADC_SAMPLE_WINDOW);

    // Configure PPB to eliminate subtraction related calculation
    // PPB is associated with SOC0
    ADC_setupPPB(M_IU_ADC_BASE, M_IU_ADC_PPB_NUM, M_IU_ADC_SOC_NUM);

    // Write zero to this for now till offset ISR is run
    ADC_setPPBCalibrationOffset(M_IU_ADC_BASE, M_IU_ADC_PPB_NUM, 0);

    // Shunt Motor Currents (M1-Iv) @ C0->SOCC0
    // SOC0 will convert pin C0, sample window in SYSCLK cycles
    // trigger on ePWM6 SOCA/C
    ADC_setupSOC(M_IV_ADC_BASE, M_IV_ADC_SOC_NUM,
                 M_ADC_TRIGGER_SOC, M_IV_ADC_CH_NUM, M_ADC_SAMPLE_WINDOW);

    // Configure PPB to eliminate subtraction related calculation
    // PPB is associated with SOC0
    ADC_setupPPB(M_IV_ADC_BASE, M_IV_ADC_PPB_NUM, M_IV_ADC_SOC_NUM);

    // Write zero to this for now till offset ISR is run
    ADC_setPPBCalibrationOffset(M_IV_ADC_BASE, M_IV_ADC_PPB_NUM, 0);

    // Shunt Motor Currents (M1-Iw) @ A9->SOCA0
    // SOC0 will convert pin A9, sample window in SYSCLK cycles
    // trigger on ePWM6 SOCA/C
    ADC_setupSOC(M_IW_ADC_BASE, M_IW_ADC_SOC_NUM,
                 M_ADC_TRIGGER_SOC, M_IW_ADC_CH_NUM, M_ADC_SAMPLE_WINDOW);

    // Configure PPB to eliminate subtraction related calculation
    // PPB is associated with SOC0
    ADC_setupPPB(M_IW_ADC_BASE, M_IW_ADC_PPB_NUM, M_IW_ADC_SOC_NUM);

    // Write zero to this for now till offset ISR is run
    ADC_setPPBCalibrationOffset(M_IW_ADC_BASE, M_IW_ADC_PPB_NUM, 0);

    // Phase Voltage (M1-Vfb-dc) @ A5->SOCA1
    // SOC1 will convert pin A5, sample window in SYSCLK cycles
    // trigger on ePWM1 SOCA/C
    ADC_setupSOC(M_VDC_ADC_BASE, M_VDC_ADC_SOC_NUM,
                 M_ADC_TRIGGER_SOC, M_VDC_ADC_CH_NUM, M_ADC_SAMPLE_WINDOW);

    // Configure PPB to eliminate subtraction related calculation
    // PPB is associated with SOC1
    ADC_setupPPB(M_VDC_ADC_BASE, M_VDC_ADC_PPB_NUM, M_VDC_ADC_SOC_NUM);

    // Write zero to this for now till offset ISR is run
    ADC_setPPBCalibrationOffset(M_VDC_ADC_BASE, M_VDC_ADC_PPB_NUM, 0);

    return;
}

//
// setup CMPSS
//
void HAL_setupCMPSS(HAL_Handle handle)
{
    HAL_Obj *obj = (HAL_Obj *)handle;

    uint16_t cnt;

    for(cnt = 0; cnt < 3; cnt++)
    {
        // Set up COMPCTL register
        // NEG signal from DAC for COMP-H
        CMPSS_configHighComparator(obj->cmpssHandle[cnt], CMPSS_INSRC_DAC);

        // NEG signal from DAC for COMP-L, COMP-L output is inverted
        CMPSS_configLowComparator(obj->cmpssHandle[cnt], CMPSS_INSRC_DAC);
//                                  (CMPSS_INSRC_DAC | CMPSS_INV_INVERTED)) ;

        // Dig filter output ==> CTRIPH, Dig filter output ==> CTRIPOUTH
        CMPSS_configOutputsHigh(obj->cmpssHandle[cnt],
                                (CMPSS_TRIP_FILTER | CMPSS_TRIPOUT_FILTER));

        // Dig filter output ==> CTRIPL, Dig filter output ==> CTRIPOUTL
        CMPSS_configOutputsLow(obj->cmpssHandle[cnt],
                               (CMPSS_TRIP_FILTER | CMPSS_TRIPOUT_FILTER | CMPSS_INV_INVERTED));

        // Set up COMPHYSCTL register
        // COMP hysteresis set to 2x typical value
        CMPSS_setHysteresis(obj->cmpssHandle[cnt], 1); //2

        // set up COMPDACCTL register
        // VDDA is REF for CMPSS DACs, DAC updated on sysclock, Ramp bypassed
        CMPSS_configDAC(obj->cmpssHandle[cnt],
                (CMPSS_DACREF_VDDA | CMPSS_DACVAL_SYSCLK | CMPSS_DACSRC_SHDW));

        // Load DACs - High and Low
        // Set DAC-H to allowed MAX +ve current
        CMPSS_setDACValueHigh(obj->cmpssHandle[cnt], 2048+1024+512); //1024

        // Set DAC-L to allowed MAX -ve current
        CMPSS_setDACValueLow(obj->cmpssHandle[cnt], 2048-1024-512); //1024

        // digital filter settings - HIGH side
        // set time between samples, max : 1023, # of samples in window,
        // max : 31, recommended : thresh > sampWin/2
        // Init samples to filter input value
        CMPSS_configFilterHigh(obj->cmpssHandle[cnt], 20, 30, 18);
        CMPSS_initFilterHigh(obj->cmpssHandle[cnt]);

        // digital filter settings - LOW side
        // set time between samples, max : 1023, # of samples in window,
        // max : 31, recommended : thresh > sampWin/2
        // Init samples to filter input value
        CMPSS_configFilterLow(obj->cmpssHandle[cnt], 20, 30, 18);
        CMPSS_initFilterLow(obj->cmpssHandle[cnt]);

        // Clear the status register for latched comparator events
        CMPSS_clearFilterLatchHigh(obj->cmpssHandle[cnt]);
        CMPSS_clearFilterLatchLow(obj->cmpssHandle[cnt]);

        // Enable CMPSS
        CMPSS_enableModule(obj->cmpssHandle[cnt]);
    }

    //
    // Refer to the Figure 14-1 and Table 14-1 in Chapter 14 of TMS320F28002x
    // Technical Reference Manual (SPRUIN7)
    //
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_1, 1);   //CMP1P_H //IU
    ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_1, 1);   //CMP1P_L

    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_3, 4);   //CMP1P_H //IV
    ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_3, 4);   //CMP1P_L

    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_1, 3);   //CMP3P_H //IW
    ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_1, 3);   //CMP3P_L

    DEVICE_DELAY_US(500);

    return;
}

// Sets up the PWMs (Pulse Width Modulators) for motor
void HAL_setupMotorPWMs(HAL_Handle handle)
{
    HAL_Obj *obj = (HAL_Obj *)handle;

    uint16_t  cnt;
    uint16_t  halfPeriod = 0;

    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    // *****************************************
    // Inverter PWM configuration - PWM 1, 2, 3
    // *****************************************
    for(cnt = 0; cnt < 3; cnt++)
    {
        // Time Base SubModule Registers
        // setup the Time-Base Control Register (TBCTL)
        EPWM_setTimeBaseCounterMode(obj->pwmHandle[cnt],
                                    EPWM_COUNTER_MODE_UP_DOWN);

        EPWM_setClockPrescaler(obj->pwmHandle[cnt], EPWM_CLOCK_DIVIDER_1,
                               EPWM_HSCLOCK_DIVIDER_1);

        EPWM_setPeriodLoadMode(obj->pwmHandle[cnt], EPWM_PERIOD_DIRECT_LOAD);


        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 Period Register (TBPRD)
        // set to zero initially
        EPWM_setTimeBasePeriod(obj->pwmHandle[cnt], 0);

        // setup the Time-Base Counter Register (TBCTR)
        EPWM_setTimeBaseCounter(obj->pwmHandle[cnt], 0);

        // Counter Compare Submodule Registers
        // set duty 0% initially
        EPWM_setCounterCompareValue(obj->pwmHandle[cnt],
                                    EPWM_COUNTER_COMPARE_A, 0);

        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_disableCounterCompareShadowLoadMode(obj->pwmHandle[cnt],
                                             EPWM_COUNTER_COMPARE_C);

        EPWM_disableCounterCompareShadowLoadMode(obj->pwmHandle[cnt],
                                             EPWM_COUNTER_COMPARE_D);

        // Action Qualifier SubModule Registers
        EPWM_setActionQualifierActionComplete(obj->pwmHandle[cnt],
                                              EPWM_AQ_OUTPUT_A,
                (EPWM_ActionQualifierEventAction)(EPWM_AQ_OUTPUT_LOW_UP_CMPA |
                                               EPWM_AQ_OUTPUT_HIGH_DOWN_CMPA));

        // Active high complementary PWMs - Set up the deadband
        EPWM_setRisingEdgeDeadBandDelayInput(obj->pwmHandle[cnt],
                                             EPWM_DB_INPUT_EPWMA);
        EPWM_setFallingEdgeDeadBandDelayInput(obj->pwmHandle[cnt],
                                              EPWM_DB_INPUT_EPWMA);

        EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_RED, true);
        EPWM_setDeadBandDelayMode(obj->pwmHandle[cnt], EPWM_DB_FED, true);
        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_HIGH); //For Inverted IC --> EPWM_DB_POLARITY_ACTIVE_HIGH

        EPWM_setRisingEdgeDelayCount(obj->pwmHandle[cnt], EPWM_DB_DELAY_RISE);
        EPWM_setFallingEdgeDelayCount(obj->pwmHandle[cnt], EPWM_DB_DELAY_FALL);
    }

    halfPeriod = M_INV_PWM_TICKS / 2;     // 100MHz EPWMCLK

    EPWM_disablePhaseShiftLoad(obj->pwmHandle[0]);
    EPWM_enablePhaseShiftLoad(obj->pwmHandle[1]);
    EPWM_enablePhaseShiftLoad(obj->pwmHandle[2]);

    EPWM_enableSyncOutPulseSource(obj->pwmHandle[0],
                                  EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);

    EPWM_enableSyncOutPulseSource(obj->pwmHandle[1],
                                  EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);

    EPWM_disableSyncOutPulseSource(obj->pwmHandle[2],
                                  EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);

    EPWM_setPhaseShift(obj->pwmHandle[0], 0);     //EPWM1
    EPWM_setPhaseShift(obj->pwmHandle[1], 2);     //EPWM2
    EPWM_setPhaseShift(obj->pwmHandle[2], 4);     //EPWM3

    EPWM_setTimeBasePeriod(obj->pwmHandle[0], halfPeriod);
    EPWM_setTimeBasePeriod(obj->pwmHandle[1], halfPeriod);
    EPWM_setTimeBasePeriod(obj->pwmHandle[2], halfPeriod);

    // Setting up link from EPWM to ADC
    // EPWM1/EPWM4 - Inverter currents at sampling frequency
    //               (@ PRD or @ (PRD&ZRO) )
#if(SAMPLING_METHOD == SINGLE_SAMPLING)
    // Select SOC from counter at ctr = prd
    EPWM_setADCTriggerSource(obj->pwmHandle[0],
                             EPWM_SOC_A, EPWM_SOC_TBCTR_ZERO);
#elif(SAMPLING_METHOD == DOUBLE_SAMPLING)
    // Select SOC from counter at ctr = 0 or ctr = prd
    EPWM_setADCTriggerSource(obj->pwmHandle[0], EPWM_SOC_A,
                             EPWM_SOC_TBCTR_ZERO_OR_PERIOD);
#endif

    // Generate pulse on 1st event
    EPWM_setADCTriggerEventPrescale(obj->pwmHandle[0], EPWM_SOC_A, 1);

    // Enable SOC on A group
    EPWM_enableADCTrigger(obj->pwmHandle[0], EPWM_SOC_A);

    // enable the ePWM module time base clock sync signal
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    return;
}

//
// Configure Motor Fault Protection Against Over Current
//
void HAL_setupMotorFaultProtection(HAL_Handle handle,
                                   const float32_t currentLimit)
{
    HAL_Obj *obj = (HAL_Obj *)handle;

    uint16_t  cnt;

    EPWM_DigitalCompareTripInput tripInSet = EPWM_DC_TRIP_TRIPIN7; //EPWM_DC_TRIP_TRIPIN4;

    // High and Low Compare event trips
    uint16_t curHi = 0;
    uint16_t curLo = 0;

    tripInSet = EPWM_DC_TRIP_TRIPIN7; //EPWM_DC_TRIP_TRIPIN4;

    curHi = 2048 + M_CURRENT_SCALE(currentLimit);
    curLo = 2048 - M_CURRENT_SCALE(currentLimit);

    //Select GPIO34 as INPUTXBAR1
    XBAR_setInputPin(INPUTXBAR_BASE, XBAR_INPUT1, M_XBAR_INPUT_GPIO);
    XBAR_lockInput(INPUTXBAR_BASE, XBAR_INPUT1);

    XBAR_setOutputLatchMode(OUTPUTXBAR_BASE, XBAR_OUTPUT1, false); //STO FB --> INPUT 1 XBAR as trigger !!! STO only triggerable over STO PINS, NOT over FlagEnableANdRun!!!
    XBAR_invertOutputSignal(OUTPUTXBAR_BASE, XBAR_OUTPUT1, false);
    XBAR_setOutputMuxConfig(OUTPUTXBAR_BASE, XBAR_OUTPUT1, XBAR_OUT_MUX01_INPUTXBAR1); //Watch out that MUX matches --> MUX01
    XBAR_enableOutputMux(OUTPUTXBAR_BASE, XBAR_OUTPUT1, XBAR_MUX01); //-> MUX01

    // Configure TRIP 4 to OR the High and Low trips from both
    // comparator 1 & 3, clear everything first
    EALLOW;
    HWREG(XBAR_EPWM_CFG_REG_BASE + XBAR_O_TRIP7MUX0TO15CFG) = 0;
    HWREG(XBAR_EPWM_CFG_REG_BASE + XBAR_O_TRIP7MUX16TO31CFG) = 0;
    EDIS;

    // Enable Muxes for ored input of CMPSS1H and 1L, mux for Mux0x
    //cmpss1 - tripH or tripL
    XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX00_CMPSS1_CTRIPH); //XBAR_EPWM_MUX00_CMPSS1_CTRIPH_OR_L

    //cmpss1 - tripH or tripL
    XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX04_CMPSS3_CTRIPH_OR_L); //XBAR_EPWM_MUX00_CMPSS1_CTRIPH_OR_L

    //cmpss3 - tripH or tripL
    XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX01_CMPSS1_CTRIPL); //XBAR_EPWM_MUX04_CMPSS3_CTRIPH_OR_L

    //inputxbar1 trip
    XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX01_INPUTXBAR1);

    // Disable all the muxes first
    XBAR_disableEPWMMux(XBAR_TRIP7, 0xFFFF);

    // Enable Mux 0, Mux 1 or Mux 4 to generate TRIP4
    XBAR_enableEPWMMux(XBAR_TRIP7, XBAR_MUX00 | XBAR_MUX04 | XBAR_MUX01);


    //
    // Configure TRIP for motor inverter phases
    //
    for(cnt = 0; cnt < 3; cnt++)
    {
        // comparator references
        // Set DAC-H to allowed MAX +ve current
        CMPSS_setDACValueHigh(obj->cmpssHandle[cnt], curHi);

        // Set DAC-L to allowed MAX -ve current
        CMPSS_setDACValueLow(obj->cmpssHandle[cnt], curLo);

        //Trip 4 is the input to the DCAHCOMPSEL
        EPWM_selectDigitalCompareTripInput(obj->pwmHandle[cnt],
                                           tripInSet,
                                           EPWM_DC_TYPE_DCAH);

        EPWM_setTripZoneDigitalCompareEventCondition(obj->pwmHandle[cnt],
                                                     EPWM_TZ_DC_OUTPUT_A1,
                                                     EPWM_TZ_EVENT_DCXH_LOW);  //LOW for STO needs HIGH to deactivate

        EPWM_setDigitalCompareEventSource(obj->pwmHandle[cnt],
                                          EPWM_DC_MODULE_A,
                                          EPWM_DC_EVENT_1,
                                          EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);

        EPWM_setDigitalCompareEventSyncMode(obj->pwmHandle[cnt],
                                            EPWM_DC_MODULE_A,
                                            EPWM_DC_EVENT_1,
                                            EPWM_DC_EVENT_INPUT_NOT_SYNCED);


        EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_DCAEVT1);

        // Emulator Stop
        EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_CBC6);

        // What do we want the OST/CBC events to do?
        // TZA events can force EPWMxA
        // TZB events can force EPWMxB

        // EPWMxA will go low
        // EPWMxB will go low
        EPWM_setTripZoneAction(obj->pwmHandle[cnt],
                               EPWM_TZ_ACTION_EVENT_TZA,
                               EPWM_TZ_ACTION_LOW);

        EPWM_setTripZoneAction(obj->pwmHandle[cnt],
                               EPWM_TZ_ACTION_EVENT_TZB,
                               EPWM_TZ_ACTION_HIGH); //EPWM_TZ_ACTION_HIGH for inverted, EPWM_TZ_ACTION_LOW non-inverting
    }

    // clear EPWM trip flags
    DEVICE_DELAY_US(1L);

    for(cnt = 0; cnt < 3; cnt++)
    {
        // clear any spurious  OST & DCAEVT1 flags
        EPWM_clearTripZoneFlag(obj->pwmHandle[cnt], (EPWM_TZ_FLAG_OST |
                                                     EPWM_TZ_FLAG_DCAEVT1 |
                                                     EPWM_TZ_FLAG_CBC ));

        // clear any spurious  HLATCH - (not in TRIP gen path)
        CMPSS_clearFilterLatchHigh(obj->cmpssHandle[cnt]);

        // clear any spurious  LLATCH - (not in TRIP gen path)
        CMPSS_clearFilterLatchLow(obj->cmpssHandle[cnt]);
    }

    DEVICE_DELAY_US(1L);

    return;
}

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

    您可以查看 TMS320F28002x 实时 微控制器 技术参考手册中的第14章"模拟子系统"和第16章"比较器子系统(CMPSS)"。

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

    尊敬的 Luo:

    我进一步调查第14章,我真的不明白我缺少什么。 在1499页查看 F280025C 时、可以看到模拟子系统方框图。 我的电流通过 A11/C0、A14/C4和 A15/C7进行测量、如下图所示:

    现在,在 HAL_setupCMPSS ()中,我按照上图设置了正确的配置(正确的比较器和正确的 MUX):

        ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_1, 1);   //CMP1P_H //IU
        ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_1, 1);   //CMP1P_L
    
        ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_3, 4);   //CMP3P_H //IV
        ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_3, 4);   //CMP3P_L
    
        ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_1, 3);   //CMP1P_H 
        ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_1, 3);   //CMP1P_L //IW

    到目前为止、正比较器输入应进行正确配置。

    对于负比较器输入、我使用 DAC、从而根据三个最大电流更新阈值。

    现在、比较器句柄的定义如模拟子系统方框图中所示:

        //
        // initialize CMPSS handle
        //
        obj->cmpssHandle[0] = CMPSS1_BASE;
        obj->cmpssHandle[1] = CMPSS3_BASE;
        obj->cmpssHandle[2] = CMPSS1_BASE;

    DAC 应通过以下代码正确设置(为跳闸设置正确的比较器):

        for(cnt = 0; cnt < 3; cnt++)
        {
            // Set up COMPCTL register
            // NEG signal from DAC for COMP-H
            CMPSS_configHighComparator(obj->cmpssHandle[cnt], CMPSS_INSRC_DAC); //CMPSS_INSRC_DAC == internal DAC
    
            // NEG signal from DAC for COMP-L
            CMPSS_configLowComparator(obj->cmpssHandle[cnt], CMPSS_INSRC_DAC);
    
            // Dig filter output ==> CTRIPH, Dig filter output ==> CTRIPOUTH
            CMPSS_configOutputsHigh(obj->cmpssHandle[cnt], (CMPSS_TRIP_FILTER | CMPSS_TRIPOUT_FILTER));
    
            // Dig filter output ==> CTRIPL, Dig filter output ==> CTRIPOUTL
            CMPSS_configOutputsLow(obj->cmpssHandle[cnt], (CMPSS_TRIP_FILTER | CMPSS_TRIPOUT_FILTER)); //CMPSS_TRIPOUT_FILTER == filter drives trip out
    
            // Set up COMPHYSCTL register
            CMPSS_setHysteresis(obj->cmpssHandle[cnt], 1); //1 = typical hysteresis
    
            // set up COMPDACCTL register
            // VDDA is REF for CMPSS DACs, DAC updated on sysclock, Ramp bypassed
            CMPSS_configDAC(obj->cmpssHandle[cnt], (CMPSS_DACREF_VDDA | CMPSS_DACVAL_SYSCLK | CMPSS_DACSRC_SHDW)); //CMPSS_DACSRC_SHDW == use shadow register for update
    
            // Load DACs - High and Low
            // Set DAC-H to allowed MAX +ve current
            CMPSS_setDACValueHigh(obj->cmpssHandle[cnt], 2048+1024+512); //initial values, will be update later dependent on current
    
            // Set DAC-L to allowed MAX -ve current
            CMPSS_setDACValueLow(obj->cmpssHandle[cnt], 2048-1024-512); //initial values, will be update later dependent on current
    
            // digital filter settings - HIGH side
            // set time between samples, max : 1023, # of samples in window,
            // max : 31, recommended : thresh > sampWin/2
            // Init samples to filter input value
            CMPSS_configFilterHigh(obj->cmpssHandle[cnt], 20, 30, 18);
            CMPSS_initFilterHigh(obj->cmpssHandle[cnt]);
    
            // digital filter settings - LOW side
            // set time between samples, max : 1023, # of samples in window,
            // max : 31, recommended : thresh > sampWin/2
            // Init samples to filter input value
            CMPSS_configFilterLow(obj->cmpssHandle[cnt], 20, 30, 18);
            CMPSS_initFilterLow(obj->cmpssHandle[cnt]);
    
            // Clear the status register for latched comparator events
            CMPSS_clearFilterLatchHigh(obj->cmpssHandle[cnt]);
            CMPSS_clearFilterLatchLow(obj->cmpssHandle[cnt]);
    
            // Enable CMPSS
            CMPSS_enableModule(obj->cmpssHandle[cnt]);
        }

    遵循以下函数进行 DAC 更新:

    //
    // Setup OCP limits and digital filter parameters of CMPSS
    //
    void HAL_setupCMPSS_DACValue(HAL_Handle handle,
                                 const uint16_t curHi, const uint16_t curLo)
    {
        HAL_Obj *obj = (HAL_Obj *)handle;
    
        uint16_t cnt;
    
        for(cnt = 0; cnt < 3; cnt++)
        {
            // comparator references
            // Set DAC-H to allowed MAX +ve current
            CMPSS_setDACValueHigh(obj->cmpssHandle[cnt], curHi);
    
            // Set DAC-L to allowed MAX -ve current
            CMPSS_setDACValueLow(obj->cmpssHandle[cnt], curLo);
        }
    
        return;
    }

    您能告诉我缺少什么吗? 电机在位置控制模式下与 FCL 完美配合、并且我可以正确触发 GPIO 跳闸、但不会触发 OC 事件、此外、当我将 DAC 阈值缩小到接近2048时、应该会立即触发任何电流、就像在通用电机控制库中一样。

    使用 XBAR 的配置如下完成:

    //
    // Configure Motor Fault Protection Against Over Current
    //
    void HAL_setupMotorFaultProtection(HAL_Handle handle,
                                       const float32_t currentLimit)
    {
        HAL_Obj *obj = (HAL_Obj *)handle;
    
        uint16_t  cnt;
    
        EPWM_DigitalCompareTripInput tripInSet = EPWM_DC_TRIP_TRIPIN7; //The MUX for a input for a GPIO STO trigger
    
        // High and Low Compare event trips
        uint16_t curHi = 0;
        uint16_t curLo = 0;
    
        tripInSet = EPWM_DC_TRIP_TRIPIN7;
    
        curHi = 2048 + M_CURRENT_SCALE(currentLimit);
        curLo = 2048 - M_CURRENT_SCALE(currentLimit);
    
        //Select GPIO34 as INPUTXBAR1
        XBAR_setInputPin(INPUTXBAR_BASE, XBAR_INPUT1, M_XBAR_INPUT_GPIO);
        XBAR_lockInput(INPUTXBAR_BASE, XBAR_INPUT1);
    
        XBAR_setOutputLatchMode(OUTPUTXBAR_BASE, XBAR_OUTPUT1, false); //STO FB --> INPUT 1 XBAR as trigger
        XBAR_invertOutputSignal(OUTPUTXBAR_BASE, XBAR_OUTPUT1, false);
        XBAR_setOutputMuxConfig(OUTPUTXBAR_BASE, XBAR_OUTPUT1, XBAR_OUT_MUX01_INPUTXBAR1); //Watch out that MUX matches --> MUX01
        XBAR_enableOutputMux(OUTPUTXBAR_BASE, XBAR_OUTPUT1, XBAR_MUX01); //-> MUX01
    
        // Configure TRIP 7 to OR the High and Low trips from both
        // comparator 1 & 3, clear everything first
        EALLOW;
        HWREG(XBAR_EPWM_CFG_REG_BASE + XBAR_O_TRIP7MUX0TO15CFG) = 0;
        HWREG(XBAR_EPWM_CFG_REG_BASE + XBAR_O_TRIP7MUX16TO31CFG) = 0;
        EDIS;
    
        // Enable Muxes for ored input of CMPSS1H and 1L, mux for Mux0x
        //cmpss1 - tripH
        XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX00_CMPSS1_CTRIPH); //IU OC trip
    
        //cmpss3 - tripH or tripL
        XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX04_CMPSS3_CTRIPH_OR_L); //IV OC trip
    
        //cmpss1 - tripL
        XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX01_CMPSS1_CTRIPL); //IW OC trip
    
        //inputxbar1 trip
        XBAR_setEPWMMuxConfig(XBAR_TRIP7, XBAR_EPWM_MUX01_INPUTXBAR1); //INPUT from GPIO34 TRIP
    
        // Disable all the muxes first
        XBAR_disableEPWMMux(XBAR_TRIP7, 0xFFFF);
    
        // Enable Mux 0, Mux 1 or Mux 4 to generate TRIP4
        XBAR_enableEPWMMux(XBAR_TRIP7, XBAR_MUX00 | XBAR_MUX04 | XBAR_MUX01);
    
    
        //
        // Configure TRIP for motor inverter phases
        //
        for(cnt = 0; cnt < 3; cnt++)
        {
            // comparator references
            // Set DAC-H to allowed MAX +ve current
            CMPSS_setDACValueHigh(obj->cmpssHandle[cnt], curHi);
    
            // Set DAC-L to allowed MAX -ve current
            CMPSS_setDACValueLow(obj->cmpssHandle[cnt], curLo);
    
            //Trip 4 is the input to the DCAHCOMPSEL
            EPWM_selectDigitalCompareTripInput(obj->pwmHandle[cnt],
                                               tripInSet,
                                               EPWM_DC_TYPE_DCAH);
    
            EPWM_setTripZoneDigitalCompareEventCondition(obj->pwmHandle[cnt],
                                                         EPWM_TZ_DC_OUTPUT_A1,
                                                         EPWM_TZ_EVENT_DCXH_LOW);  //LOW for STO needs HIGH to deactivate
    
            EPWM_setDigitalCompareEventSource(obj->pwmHandle[cnt],
                                              EPWM_DC_MODULE_A,
                                              EPWM_DC_EVENT_1,
                                              EPWM_DC_EVENT_SOURCE_ORIG_SIGNAL);
    
            EPWM_setDigitalCompareEventSyncMode(obj->pwmHandle[cnt],
                                                EPWM_DC_MODULE_A,
                                                EPWM_DC_EVENT_1,
                                                EPWM_DC_EVENT_INPUT_NOT_SYNCED);
    
    
            EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_DCAEVT1);
    
            // Emulator Stop
            EPWM_enableTripZoneSignals(obj->pwmHandle[cnt], EPWM_TZ_SIGNAL_CBC6);
    
            // What do we want the OST/CBC events to do?
            // TZA events can force EPWMxA
            // TZB events can force EPWMxB
    
            // EPWMxA will go low
            // EPWMxB will go low
            EPWM_setTripZoneAction(obj->pwmHandle[cnt],
                                   EPWM_TZ_ACTION_EVENT_TZA,
                                   EPWM_TZ_ACTION_LOW);
    
            EPWM_setTripZoneAction(obj->pwmHandle[cnt],
                                   EPWM_TZ_ACTION_EVENT_TZB,
                                   EPWM_TZ_ACTION_HIGH); //EPWM_TZ_ACTION_HIGH for inverted, EPWM_TZ_ACTION_LOW non-inverting
        }
    
        // clear EPWM trip flags
        DEVICE_DELAY_US(1L);
    
        for(cnt = 0; cnt < 3; cnt++)
        {
            // clear any spurious  OST & DCAEVT1 flags
            EPWM_clearTripZoneFlag(obj->pwmHandle[cnt], (EPWM_TZ_FLAG_OST |
                                                         EPWM_TZ_FLAG_DCAEVT1 |
                                                         EPWM_TZ_FLAG_CBC ));
    
            // clear any spurious  HLATCH - (not in TRIP gen path)
            CMPSS_clearFilterLatchHigh(obj->cmpssHandle[cnt]);
    
            // clear any spurious  LLATCH - (not in TRIP gen path)
            CMPSS_clearFilterLatchLow(obj->cmpssHandle[cnt]);
        }
    
        DEVICE_DELAY_US(1L);
    
        return;
    }

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

    如 表14-2所示、您可以参考该示例、只需更改 CMPSS 配置以将其输入链接到相关的 ADC 输入。    TMS320F28002x 实时 微控制器 技术参考手册第14章"模拟子系统"中的"模拟引脚和内部连接"。