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.

[参考译文] TMS320F280025C:数字环路控制

Guru**** 2419530 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1060993/tms320f280025c-digital-loop-control

器件型号:TMS320F280025C

您好!

我想请您就开环中的第一步调节提出意见。首先、我通过 PWM 执行 ADC 的时序、然后通过 EOC 上触发的中断读取 ADC。

我想首先在另一个 ISR 中包含平均值计算。 我看到方法是通过计时器设置中断。 否则、我通过 GPIO 触发另一个中断(在 ADC ISR 中输出输出一个输出、在 XINT ISR 中输入一个输出)。 这是正确的方法吗?

因为如果我使用计时器,如何在 ADC 中断结束时为计时器计时?

之后我将建立 CAN 通信、以便与用户界面进行通信、因此在本例中、我可以使用 CAN 中断。
最后一个问题,平均在周期中非常贪婪,我是否应该进行平均或瞬时处理校正器的滤波和操作? 如果您有建议、您可以看到我的代码。

谢谢、

Damien

#include "config.h"
#include "input_users.h"
#include "driverlib.h"
#include "utils.h"
#include "device.h"
#include "variable.h"
#include "corrector.h"
#include "filter.h"

void epwm_init(uint32_t);
void cmpss_actions();
void cmpss_init();
void µc_config();
void adc_config(uint32_t);
void adc_run(void);
void device_config(void);
void regul();
void init_epwm_soc(uint32_t);
void init_adc_soc(void);
void average(void);

__interrupt void isr_adc(void);
__interrupt void isr_xint1(void);

uint16_t pointer_isr_adc = 0;
uint16_t adc_index_isr = 0;

void main(void)
{
    // Device config
    device_config();

    µc_config();

    // Disable sync and clock to PWM
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    epwm_init(myEPWM1_BASE);
    epwm_init(myEPWM2_BASE);
    epwm_init(myEPWM3_BASE);

    // Configure and actions CMPSS
    cmpss_init(CMPSS1_BASE);
    cmpss_init(CMPSS2_BASE);
    cmpss_init(CMPSS3_BASE);

    cmpss_actions(myEPWM1_BASE);
    cmpss_actions(myEPWM2_BASE);
    cmpss_actions(myEPWM3_BASE);

    // Interrupts that are used (la fonction isr_adc sera appelée dans un contexte d'interruption). See PIE Channel Mapping in Peripheral Interrupts doc
    Interrupt_register(INT_ADCC1, &isr_adc);
    Interrupt_register(INT_XINT1, &isr_xint1);

    // Set up the ADC / ePWM SOC and initialize the end of conversion
    adc_config(ADCA_BASE);
    adc_config(ADCC_BASE);
    init_epwm_soc(myEPWM4_BASE);
    init_adc_soc();

    // Enable interrupt
    Interrupt_enable(INT_ADCC1);
    Interrupt_enable(INT_XINT1);

    // Initialize results buffer
    for(adc_index = 0; adc_index < SAMPLES; adc_index++)
    {
        Vout_samples[adc_index] = 0;
        Vin_samples[adc_index] = 0;
        Is_boost_1[adc_index] = 0;
        Is_boost_2[adc_index] = 0;
        Is_boost_3[adc_index] = 0;
        Drv_u[adc_index] = 0;
        Drv_v[adc_index] = 0;
        Drv_w[adc_index] = 0;
    }

    adc_index = 0;

    // Enable sync and clock to PWM
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);

    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    EINT;
    ERTM;

    while(1)
    {
        // Wait while eWPM4 causes conversion and if trip zone is set shoot down ePWM

        // Trip flag is set when CTRIP signal is asserted
        if((EPWM_getTripZoneFlagStatus(myEPWM1_BASE) & EPWM_TZ_FLAG_DCBEVT1) != 0U || (EPWM_getTripZoneFlagStatus(myEPWM2_BASE) & EPWM_TZ_FLAG_DCBEVT1) != 0U || (EPWM_getTripZoneFlagStatus(myEPWM3_BASE) & EPWM_TZ_FLAG_DCBEVT1) != 0U)
        {
            // Clear trip flags
            EPWM_clearTripZoneFlag(myEPWM1_BASE, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
            EPWM_clearTripZoneFlag(myEPWM2_BASE, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
            EPWM_clearTripZoneFlag(myEPWM3_BASE, EPWM_TZ_FLAG_DCBEVT1 | EPWM_TZ_FLAG_OST);
        }
    }
}

void device_config(void)
{
    // Initialize device clock and peripherals
    Device_init();

    // Disable pin locks and enable internal pullups.
    Device_initGPIO();

    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    Interrupt_initModule();

    // Initialize the PIE vector table with pointers to the shell Interrupt Service Routines (ISR).
    Interrupt_initVectorTable();
}

void epwm_init(uint32_t base)
{
    float PWM_TBPRD_1;
    float PWM_TBPRD_2;
    float PWM_TBPRD_3;
    float PWM_TBPRD_4;
    float PWM_CMPA_1;
    float PWM_CMPA_2;
    float PWM_CMPA_3;
    float PWM_CMPA_4;
    EPWM_ClockDivider PWM_PARAM_PRESCALER;
    EPWM_HSClockDivider PWM_PARAM_HIGHSPEEDPRESCALER;
    float TBCLK;

    if(base == myEPWM1_BASE)
    {
        // Parameters
        EPWM_setTimeBaseCounterMode(base, MODE_COUNT);
        get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_TBPRD_4 ,&PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_CMPA_4 ,&PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
        EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_1);
        EPWM_setTimeBaseCounter(base, 0U);
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_1);
        EPWM_setClockPrescaler(base, PWM_PARAM_PRESCALER, PWM_PARAM_HIGHSPEEDPRESCALER);
        // Set up shadowing
        EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);

        if(MODE_COUNT == EPWM_COUNTER_MODE_UP)
        {
            // Set actions
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        }
        else if(MODE_COUNT == EPWM_COUNTER_MODE_UP_DOWN)
        {
            // Set actions
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        }

        // Configure ePMWs
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setPhaseShift(base, 0U);
        EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
    }

    else if (base == myEPWM2_BASE)
    {
        // Parameters
        EPWM_setTimeBaseCounterMode(base, MODE_COUNT);
        get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_TBPRD_4 ,&PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_CMPA_4 ,&PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
        EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_2);
        EPWM_setTimeBaseCounter(base, 0U);
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_2);
        EPWM_setPhaseShift(base, 0U);
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setClockPrescaler(base, PWM_PARAM_PRESCALER, PWM_PARAM_HIGHSPEEDPRESCALER);
        // Set up shadowing
        EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);

        if(MODE_COUNT == EPWM_COUNTER_MODE_UP)
        {
            // Set actions
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        }
        else if(MODE_COUNT == EPWM_COUNTER_MODE_UP_DOWN)
        {
            // Set actions
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        }

        set_phase(base, myEPWM1_BASE, PHI);
        EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
        EPWM_enablePhaseShiftLoad(base);
    }

    else if(base == myEPWM3_BASE)
    {
        // Parameters
        EPWM_setTimeBaseCounterMode(base, MODE_COUNT);
        get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_TBPRD_4 ,&PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_CMPA_4 ,&PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
        EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_3);
        EPWM_setTimeBaseCounter(base, 0U);
        EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_3);
        EPWM_setPhaseShift(base, 0U);
        EPWM_disablePhaseShiftLoad(base);
        EPWM_setClockPrescaler(base, PWM_PARAM_PRESCALER, PWM_PARAM_HIGHSPEEDPRESCALER);
        // Set up shadowing
        EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);

        if(MODE_COUNT == EPWM_COUNTER_MODE_UP)
        {
            // Set actions
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
        }
        else if(MODE_COUNT == EPWM_COUNTER_MODE_UP_DOWN)
        {
            // Set actions
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
            EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
        }

        set_phase(base, myEPWM1_BASE, PHI);
        EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
        EPWM_enablePhaseShiftLoad(base);
    }
}

void cmpss_init(base)
{
    // Enable CMPSS and configure the negative input signal to come from the DAC
    CMPSS_enableModule(base);

    // Use VDDA as the reference for the DAC and set DAC value to midpoint for arbitrary reference.
    CMPSS_configDAC(base, CMPSS_DACREF_VDDA);

    // Configure the output signals. Both CTRIPH will be fed by the asynchronous comparator output.
    //1
    CMPSS_configHighComparator(base, CMPSS_INSRC_DAC);      // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueHigh(base, 1024);                      // Define threshold
    CMPSS_configOutputsHigh(base, CMPSS_TRIP_SYNC_COMP);    // Set output comparator (synchronous or asynchronous)
    //2
    CMPSS_configLowComparator(base, CMPSS_INSRC_DAC);       // Threshold drive by GPIO or input DAC
    CMPSS_setDACValueLow(base, 1024);                       // Define threshold
    CMPSS_configOutputsLow(base, CMPSS_TRIP_SYNC_COMP);     // Set output comparator (synchronous or asynchronous)
}

void cmpss_actions(base)
{
    // Configure ePWMx to output low on TZx TRIP
    EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_LOW);
    EPWM_setTripZoneAction(base, EPWM_TZ_ACTION_EVENT_TZB, EPWM_TZ_ACTION_LOW);

    // Trigger event when DCBH is high
    EPWM_setTripZoneDigitalCompareEventCondition(base, EPWM_TZ_DC_OUTPUT_B1, EPWM_TZ_EVENT_DCXH_HIGH);

    // Configure DCBH to use TRIP4 as an input
    EPWM_enableDigitalCompareTripCombinationInput(base, EPWM_DC_COMBINATIONAL_TRIPIN4, EPWM_DC_TYPE_DCBH);

    // Enable DCB as OST
    EPWM_enableTripZoneSignals(base, EPWM_TZ_SIGNAL_DCBEVT1);

    //AIO224 -> myAIO0 Pinmux
    GPIO_setPinConfig(GPIO_224_GPIO224);
    //AIO230 -> myAIO1 Pinmux
    GPIO_setPinConfig(GPIO_230_GPIO230);
    //AIO226 -> myAIO2 Pinmux
    GPIO_setPinConfig(GPIO_226_GPIO226);
    // To use CMP1_HP0
    ASysCtl_selectCMPLPMux(ASYSCTL_CMPLPMUX_SELECT_1, 0);
    // To use CMP2_HP3
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_2, 3);
    // To use CMP3_HP0
    ASysCtl_selectCMPHPMux(ASYSCTL_CMPHPMUX_SELECT_3, 0);

    // Configure TRIP4 to be CTRIP1H using the ePWM X-BAR. Attach CMPSS output to TRIPINx via EPWMXBAR module
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX01_CMPSS1_CTRIPL);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX02_CMPSS2_CTRIPH);
    XBAR_setEPWMMuxConfig(XBAR_TRIP4, XBAR_EPWM_MUX04_CMPSS3_CTRIPH);

    // See the ePWM X-BAR Mux configuration table, see Crossbar(X-BAR) doc for more informations
    XBAR_enableEPWMMux(XBAR_TRIP4, XBAR_MUX01 | XBAR_MUX02 | XBAR_MUX04);

    // Clear trip flags
    EPWM_clearTripZoneFlag(base, EPWM_TZ_FLAG_DCBEVT1);
}

void µc_config()
{
    EALLOW;

    //EPWM1 -> myEPWM1 Pinmux
    GPIO_setPinConfig(GPIO_0_EPWM1_A);
    GPIO_setPinConfig(GPIO_1_EPWM1_B);
    //EPWM2 -> myEPWM2 Pinmux
    GPIO_setPinConfig(GPIO_2_EPWM2_A);
    GPIO_setPinConfig(GPIO_3_EPWM2_B);
    //EPWM3 -> myEPWM3 Pinmux
    GPIO_setPinConfig(GPIO_4_EPWM3_A);
    GPIO_setPinConfig(GPIO_15_EPWM3_B);
    //EPWM4 -> myEPWM4 Pinmux
    GPIO_setPinConfig(GPIO_6_EPWM4_A);

    // level pin to enter in isr_adc (level 0 to enter in isr_xint1)
    GPIO_setPinConfig(GPIO_40_GPIO40);
    GPIO_setDirectionMode(40, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(40, GPIO_PIN_TYPE_STD);

    // input pin (connect GPIO40 to GPIO42)
    GPIO_setPinConfig(GPIO_42_GPIO42);
    GPIO_setDirectionMode(42, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(42, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(42, GPIO_QUAL_SYNC);
    GPIO_setInterruptPin(42,GPIO_INT_XINT1);
    // Falling edge interrupt
    GPIO_setInterruptType(GPIO_INT_XINT1, GPIO_INT_TYPE_FALLING_EDGE);
    // Enable XINT1
    GPIO_enableInterrupt(GPIO_INT_XINT1);

    // To visualize isr_xint1 with toggle pin
    GPIO_setPinConfig(GPIO_27_GPIO27);
    GPIO_setDirectionMode(27, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(27, GPIO_PIN_TYPE_STD);

    EDIS;
}

void adc_config(uint32_t adc_base)
{
    // Enable ADC
    ADC_setVREF(adc_base, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    ADC_setPrescaler(adc_base, ADC_CLK_DIV_1_0);

    // Set pulse ADCINTx at the end of conversion
    ADC_setInterruptPulseMode(adc_base, ADC_PULSE_END_OF_CONV);

    ADC_enableConverter(adc_base);

    //Delay to allow ADC time to power up
    DEVICE_DELAY_US(ADC_POWERUP_US);
}

void init_epwm_soc(uint32_t base)
{
    float PWM_TBPRD_1;
    float PWM_TBPRD_2;
    float PWM_TBPRD_3;
    float PWM_TBPRD_4;
    float PWM_CMPA_1;
    float PWM_CMPA_2;
    float PWM_CMPA_3;
    float PWM_CMPA_4;
    EPWM_ClockDivider PWM_PARAM_PRESCALER;
    EPWM_HSClockDivider PWM_PARAM_HIGHSPEEDPRESCALER;
    float TBCLK;

    // Disable SOCA
    EPWM_disableADCTrigger(base, EPWM_SOC_A);

    // Configure the SOC to occur on the first up-count event
    EPWM_setADCTriggerSource(base, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);

    // To set ADCCLK
    EPWM_setADCTriggerEventPrescale(base, EPWM_SOC_A, ADC_SOC_COUNT);

    // Parameters
    get_pwm_clock_from_freq(base , &PWM_TBPRD_1 , &PWM_TBPRD_2 , &PWM_TBPRD_3 , &PWM_TBPRD_4 ,&PWM_CMPA_1 , &PWM_CMPA_2 , &PWM_CMPA_3 , &PWM_CMPA_4 ,&PWM_PARAM_PRESCALER , &PWM_PARAM_HIGHSPEEDPRESCALER, &TBCLK);
    EPWM_setTimeBasePeriod(base, (uint16_t)PWM_TBPRD_4);
    EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, (uint16_t)PWM_CMPA_4);
    EPWM_setPhaseShift(base, 0U);
    EPWM_disablePhaseShiftLoad(base);
    EPWM_setClockPrescaler(base, PWM_PARAM_PRESCALER, PWM_PARAM_HIGHSPEEDPRESCALER);

    // Set actions
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(base, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);

    // Set in phase with ePWM1
    set_phase(base, myEPWM1_BASE, 0);
    EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
    EPWM_enablePhaseShiftLoad(base);

    // Start ePWM4, enabling SOCA and putting the counter in up-count mode
    EPWM_setTimeBaseCounterMode(base, MODE_COUNT_SOC);

    EPWM_enableADCTrigger(base, EPWM_SOC_A);
}

void init_adc_soc(void)
{
    // Corresponding module ADCx -> SOC -> pin. Enchainement des SOC une fois la conversion terminée sur un SOC.SOC0 will start at 1 / PWM_SOC_FREQ and an another SOC0 at 1 / PWM_SOC_FREQ after.
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM4_SOCA, VOUT_ADC_PIN, VOUT_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM4_SOCA, VIN_ADC_PIN, VIN_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM4_SOCA, IS_BOOST_1_ADC_PIN, IS_BOOST_1_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM4_SOCA, IS_BOOST_2_ADC_PIN, IS_BOOST_2_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM4_SOCA, IS_BOOST_3_ADC_PIN, IS_BOOST_3_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM4_SOCA, DRV_U_ADC_PIN, DRV_U_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM4_SOCA, DRV_V_ADC_PIN, DRV_V_ADC_ACQPS_WINDOW);
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM4_SOCA, DRV_W_ADC_PIN, DRV_W_ADC_ACQPS_WINDOW);

    // Corresponding EOC to ADCINTX pulse to enter on interrupt for read ADCRESULTx registers. Refer to ADCINTSEL1N2 and ADCRESULTx registers.
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);

    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);

    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
}

__interrupt void isr_adc(void) // Enter on interrupt when SOC3 on ADCC will end. Enter on interrupt when EOC3 is set 1 / PWM_SOC_FREQ
{
    // Set GPIO type output
    GPIO_writePin(40, 1);

    // Circular buffer
    pointer_isr_adc = (SAMPLES - adc_index_isr) % SAMPLES;

    Vout_samples[pointer_isr_adc] = Vout_read();
    Vin_samples[pointer_isr_adc] = Vin_read();
    Is_boost_1[pointer_isr_adc] = Is_boost_1_read();
    Is_boost_2[pointer_isr_adc] = Is_boost_2_read();
    Is_boost_3[pointer_isr_adc] = Is_boost_3_read();
    Drv_u[pointer_isr_adc] = Drv_u_read();
    Drv_v[pointer_isr_adc] = Drv_v_read();
    Drv_w[pointer_isr_adc] = Drv_w_read();

    adc_index_isr = (adc_index_isr + 1) % SAMPLES;

    // Clear the interrupt flag
    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);

    // Check if overflow has occurred
    if(ADC_getInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1) == true)
    {
        ADC_clearInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
    }

    // Acknowledge the interrupt, see PIE Interrupt Vectors table
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);

    GPIO_writePin(40, 0);
}

__interrupt void isr_xint1(void)
{
    GPIO_writePin(27, 1);

    average();
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);

    GPIO_writePin(27, 0);
}

void average(void)
{
    Vout_average = average_Vout(Vout_samples);
    Vin_average = average_Vin(Vin_samples);
    Is_boost_1_average = average_Is_boost_1(Is_boost_1);
    Is_boost_2_average = average_Is_boost_2(Is_boost_2);
    Is_boost_3_average = average_Is_boost_3(Is_boost_3);
    Drv_u_average = average_Drv_u(Drv_u);
    Drv_v_average = average_Drv_v(Drv_v);
    Drv_w_average = average_Drv_w(Drv_w);
}

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

    尊敬的 Damien:

    我无法从您的代码中得知信号采样的速度是多快、或者 ePWM 触发的速度是多快。  抱歉、我在 ePWM 设置中有一点迷路、但 我可以从 ADC 设置中看出、您正在对8个信号/通道进行采样、并且在 ADCA 和 ADCC 上为每个信号分配了一个 SOC (基本上每个 ADC 分配了4个信号)。  每个 ADC 模块有16个可用的 SOC、因此一个快速建议是将 SOC 扩展到您要采样的所有信号、例如:

          VOUT_ADC_PIN->分配给 ADCC SOC0-3

          VIN_ADC_PIN->分配给 ADCC SOC4-7

          是_BOOST_1_ADC_PIN->分配给 ADCC SOC8-11

          IT_BOOST_2_ADC_PIN->分配给 ADCC SOC12-15

          IT_BOOST_3_ADC_PIN->分配给 ADCA SOC0-3

          DRV_U_ADC_PIN->分配给 ADCA SOC4-7

          DRV_V_ADC_PIN->分配给 ADCA SOC8-11

          DRV_W_ADC_PIN->分配给 ADCA SOC12-15

    此时、这些信号上的转换触发器仅来自 ADC_TRIGGER_EPWM4_SOCA。  您可能可以修改 ePWM 设置以触发这些信号或成组的独立转换、具体取决于您希望采样的速度。  将样本分布到可用 SOC 的点是为了获取每个信号的更多样本(过采样)、例如、 来自上述 SOC 分配的 VOUT_ADC_PIN 的转换触发器将会将 ADC 结果填充到相应的 ADCC ADRESULT0-3中、您可以在其中对结果进行汇总并将其向右移动2、然后获得4的平均值(过采样)。  您可以在 ISR 中处理结果并提高其效率。  代码中似乎还使用了一个 ADC ISR。  您还可以向每个 ADC 添加独立的 ISR、以提高处理效率。  请告诉我这是否有帮助。

    此致、

    Joseph