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.

TMS320F28379D: ADC与DMA的使用问题

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

您好!

我配置了ADCA的SOC0和ADCB的SOC0来进行同步采样,用DMA进行数据的搬移,目前遇到一个问题:只有一个数据被搬移了,而我需要采样32个数据

配置的代码如下:

#pragma DATA_SECTION(AdcaDataU, "ramgs0");
#pragma DATA_SECTION(AdcbDataI, "ramgs0");
Uint16 AdcaDataU[RESULTS_BUFFER_SIZE] = {100};  // 电压采样值
Uint16 AdcbDataI[RESULTS_BUFFER_SIZE] = {100};  // 电流采样值

// ADCINA0、1-->电压U
// ADCINB2、3-->电流I
void Adc_Init()
{
    EALLOW;
    // Write prescale configurations
    // ADC max clock == 50MHz
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // Set ADCCLK divider to /4
    AdcbRegs.ADCCTL2.bit.PRESCALE = 6; // set ADCCLK divider to /4
    // Set mode(16位差分输入)
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);
    AdcSetMode(ADC_ADCB, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);

    // SOC0 will convert ADCINA0/A1(ADC_CHANNEL_0/ADC_CHANNEL_1)
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = ADC_CHANNEL_0;
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;  // 配置EPWM1A触发
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 39;   // 采样时间40 ADC Clock Cycles, (39 ACQPS plus 1)
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; // Set pulse positions to late

    ////////////////////ADC中断设置////////////////////
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared

    // SOC0 will convert ADCINB2/B3(ADC_CHANNEL_2/ADC_CHANNEL_3)
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = ADC_CHANNEL_2;
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5;  // 配置EPWM1A触发
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = 39;   // 采样时间40 ADC Clock Cycles, (39 ACQPS plus 1)
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;  // Power up the ADC
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    EDIS;
    // Delay for 1ms to allow ADCs time to power up
    DELAY_US(1000);


    ///////////////////////// DMA配置 ///////////////////////
    // DMAInitialize - This function initializes the DMA to a known state.
    DMAInitialize();

    // DMA1
    // 配置目标地址和源地址
    DMACH1AddrConfig(AdcaDataU, &AdcaResultRegs.ADCRESULT0);
    // 每次burst配置成传输1个16bit word,每个word传输完成后,源地址和目标地址都递增0
    DMACH1BurstConfig(0, 0, 0);
    //每次Teransfer传输RESULTS_BUFFER_SIZE-1个burst,每次burst传输完成后源地址和目标地址递增1
    DMACH1TransferConfig((RESULTS_BUFFER_SIZE - 1),1, 1);
    DMACH1ModeConfig(
                        DMA_ADCAINT1,    // Source select
                        PERINT_ENABLE,   // Peripheral interrupt enable
                        ONESHOT_DISABLE, // Oneshot diaable
                        CONT_ENABLE,     // Continuous enable
                        SYNC_DISABLE,
                        SYNC_SRC,
                        OVRFLOW_DISABLE, // Disable the overflow interrupt
                        SIXTEEN_BIT,     // 16-bit data size transfers
                        CHINT_END,       // Generate interrupt to CPU at end of transfer
                        CHINT_DISABLE    // Channel Interrupt to  CPU disable
                     );

    // DMA2
    DMACH2AddrConfig(AdcbDataI, &AdcbResultRegs.ADCRESULT0);
    DMACH2BurstConfig(0, 0, 0);
    DMACH2TransferConfig((RESULTS_BUFFER_SIZE - 1), 1, 1);
    DMACH2ModeConfig(
                        DMA_ADCAINT1,
                        PERINT_ENABLE,
                        ONESHOT_DISABLE,
                        CONT_ENABLE,
                        SYNC_DISABLE,
                        SYNC_SRC,
                        OVRFLOW_DISABLE,
                        SIXTEEN_BIT,
                        CHINT_END,
                        CHINT_ENABLE
                     );

    // ADC采样触发(EPWM1SOCA)
    EALLOW;
    EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;      // Enable SOC on A group
    EPwm1Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate pulse on 1st event
    EDIS;

    // Start DMA
    StartDMACH1();
    StartDMACH2();
}

void dmach2_isr(void)
{
    while(1)
    {
        __asm(" NOP");
    }
    //PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
}

通过调试发现只有第一次的采样结果正确的保存了,如下所示:

我猜是第一次采样后ADC产生中断标志位后,再触发了DMA的数据转移,一个burst后,由于中断的标志位没有给清除,就没进行下次的数据转移了??

我现在的问题就是:怎么样能够再每次的ADC中断后触发后产生DMA的数据搬移呢?

感谢您的回答!