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.

TMS320F28035: ADC采样设置多个触发源来触发不同SOC时,采样结果会出错

Part Number: TMS320F28035


EPWM模块产生两个SOC信号,分别是EPWM2的ZERO和PRD,分别为EPWM2SOCA和EPWM2SOCB。如果把所有16路ADC的触发源TRIGSEL都配为EPWM2SOCA或都配为EPWM2SOCB就能正常进行采样;但其中某几个SOC的触发源配为EPWM2SOCB,其他配为EPWM2SOCA,那几个通道采样结果就会出错。PWM是60kHz的Up-Down计数。

代码如下:把第42行ADCTRIG_EPWM2_SOCB改为ADCTRIG_EPWM2_SOCA或者所有都用ADCTRIG_EPWM2_SOCB就能正常采样,但是下面的代码12号ADC结果寄存器的值就会有问题

void sInitADC(void)
{
    extern void DSP28x_usDelay(Uint32 Count);

    int     ChSel[16] =   {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int     TrigSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    int     ACQPS[16] =   {7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};

    int IntChSel = 15;
    int mode = 2;
    // ADC Channel Selection for Configuring the ADC
    //Map channel to ADC Pin
    ChSel[0] =  1;
    ChSel[1] =  2;
    ChSel[2] =  3;
    ChSel[3] =  4;
    ChSel[4] =  5;
    ChSel[5] =  6;
    ChSel[6] =  7;
    ChSel[7] =  8;
    ChSel[8] =  9;
    ChSel[9] =  10;
    ChSel[10] =  11;
    ChSel[11] =  12;
    ChSel[12] =  13;
    ChSel[13] =  14;
    ChSel[14] =  15;
    ChSel[15] =  16;


    TrigSel[0] = ADCTRIG_EPWM2_SOCA;
    TrigSel[1] = ADCTRIG_EPWM2_SOCA;
    TrigSel[2] = ADCTRIG_EPWM2_SOCA;
    TrigSel[3] = ADCTRIG_EPWM2_SOCA;
    TrigSel[4] = ADCTRIG_EPWM2_SOCA;
    TrigSel[5] = ADCTRIG_EPWM2_SOCA;
    TrigSel[6] = ADCTRIG_EPWM2_SOCA;
    TrigSel[7] = ADCTRIG_EPWM2_SOCA;
    TrigSel[8] = ADCTRIG_EPWM2_SOCA;
    TrigSel[9] = ADCTRIG_EPWM2_SOCA;
    TrigSel[10] = ADCTRIG_EPWM2_SOCA;
    TrigSel[11] = ADCTRIG_EPWM2_SOCB;//
    TrigSel[12] = ADCTRIG_EPWM2_SOCA;//
    TrigSel[13] = ADCTRIG_EPWM2_SOCA;
    TrigSel[14] = ADCTRIG_EPWM2_SOCA;
    TrigSel[15] = ADCTRIG_EPWM2_SOCA;

    EALLOW;
    AdcRegs.ADCCTL1.bit.ADCREFSEL   = 1;// Nick 20220715 select internal reference 3.3V,external reference is 3.0V
    AdcRegs.ADCCTL1.bit.ADCBGPWD    = 1;    // Power up band gap
    AdcRegs.ADCCTL1.bit.ADCREFPWD   = 1;    // Power up reference
    AdcRegs.ADCCTL1.bit.ADCPWDN     = 1;    // Power up rest of ADC
    AdcRegs.ADCCTL1.bit.ADCENABLE   = 1;    // Enable ADC

    DSP28x_usDelay(1000);         // Delay before converting ADC channels
    AdcRegs.ADCSAMPLEMODE.all = 0;
    AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    AdcRegs.ADCSOC0CTL.bit.ACQPS = ACQPS[0];
    AdcRegs.ADCSOC1CTL.bit.ACQPS = ACQPS[1];
    AdcRegs.ADCSOC2CTL.bit.ACQPS = ACQPS[2];
    AdcRegs.ADCSOC3CTL.bit.ACQPS = ACQPS[3];
    AdcRegs.ADCSOC4CTL.bit.ACQPS = ACQPS[4];
    AdcRegs.ADCSOC5CTL.bit.ACQPS = ACQPS[5];
    AdcRegs.ADCSOC6CTL.bit.ACQPS = ACQPS[6];
    AdcRegs.ADCSOC7CTL.bit.ACQPS = ACQPS[7];
    AdcRegs.ADCSOC8CTL.bit.ACQPS = ACQPS[8];
    AdcRegs.ADCSOC9CTL.bit.ACQPS = ACQPS[9];
    AdcRegs.ADCSOC10CTL.bit.ACQPS = ACQPS[10];
    AdcRegs.ADCSOC11CTL.bit.ACQPS = ACQPS[11];
    AdcRegs.ADCSOC12CTL.bit.ACQPS = ACQPS[12];
    AdcRegs.ADCSOC13CTL.bit.ACQPS = ACQPS[13];
    AdcRegs.ADCSOC14CTL.bit.ACQPS = ACQPS[14];
    AdcRegs.ADCSOC15CTL.bit.ACQPS = ACQPS[15];

    AdcRegs.INTSEL1N2.bit.INT1SEL = IntChSel;       // IntChSel causes ADCInterrupt 1

    AdcRegs.ADCINTFLG.bit.ADCINT1 = 0;  // clear interrupt flag for ADCINT1
    AdcRegs.INTSEL1N2.bit.INT1CONT = 1; // set ADCInterrupt 1 to auto clr
    AdcRegs.ADCINTSOCSEL1.all=0x0000;   // No ADCInterrupt will trigger SOCx
    AdcRegs.ADCINTSOCSEL2.all=0x0000;


    if(IntChSel <= 15)
        AdcRegs.INTSEL1N2.bit.INT1E = 1;        // enable ADC interrupt 1
    else
        AdcRegs.INTSEL1N2.bit.INT1E = 0;        // disable the ADC interrupt 1

// Select the channel to be converted when SOCx is received
    AdcRegs.ADCSOC0CTL.bit.CHSEL= ChSel[0];
    AdcRegs.ADCSOC1CTL.bit.CHSEL= ChSel[1];
    AdcRegs.ADCSOC2CTL.bit.CHSEL= ChSel[2];
    AdcRegs.ADCSOC3CTL.bit.CHSEL= ChSel[3];
    AdcRegs.ADCSOC4CTL.bit.CHSEL= ChSel[4];
    AdcRegs.ADCSOC5CTL.bit.CHSEL= ChSel[5];
    AdcRegs.ADCSOC6CTL.bit.CHSEL= ChSel[6];
    AdcRegs.ADCSOC7CTL.bit.CHSEL= ChSel[7];
    AdcRegs.ADCSOC8CTL.bit.CHSEL= ChSel[8];
    AdcRegs.ADCSOC9CTL.bit.CHSEL= ChSel[9];
    AdcRegs.ADCSOC10CTL.bit.CHSEL= ChSel[10];
    AdcRegs.ADCSOC11CTL.bit.CHSEL= ChSel[11];
    AdcRegs.ADCSOC12CTL.bit.CHSEL= ChSel[12];
    AdcRegs.ADCSOC13CTL.bit.CHSEL= ChSel[13];
    AdcRegs.ADCSOC14CTL.bit.CHSEL= ChSel[14];
    AdcRegs.ADCSOC15CTL.bit.CHSEL= ChSel[15];


    AdcRegs.ADCSOC0CTL.bit.TRIGSEL= TrigSel[0];
    AdcRegs.ADCSOC1CTL.bit.TRIGSEL= TrigSel[1];
    AdcRegs.ADCSOC2CTL.bit.TRIGSEL= TrigSel[2];
    AdcRegs.ADCSOC3CTL.bit.TRIGSEL= TrigSel[3];
    AdcRegs.ADCSOC4CTL.bit.TRIGSEL= TrigSel[4];
    AdcRegs.ADCSOC5CTL.bit.TRIGSEL= TrigSel[5];
    AdcRegs.ADCSOC6CTL.bit.TRIGSEL= TrigSel[6];
    AdcRegs.ADCSOC7CTL.bit.TRIGSEL= TrigSel[7];
    AdcRegs.ADCSOC8CTL.bit.TRIGSEL= TrigSel[8];
    AdcRegs.ADCSOC9CTL.bit.TRIGSEL= TrigSel[9];
    AdcRegs.ADCSOC10CTL.bit.TRIGSEL= TrigSel[10];
    AdcRegs.ADCSOC11CTL.bit.TRIGSEL= TrigSel[11];
    AdcRegs.ADCSOC12CTL.bit.TRIGSEL= TrigSel[12];
    AdcRegs.ADCSOC13CTL.bit.TRIGSEL= TrigSel[13];
    AdcRegs.ADCSOC14CTL.bit.TRIGSEL= TrigSel[14];
    AdcRegs.ADCSOC15CTL.bit.TRIGSEL= TrigSel[15];
    EDIS;

    AdcRegs.ADCSOCFRC1.all = 0xFFFF;        // kick-start ADC

}

  • 您好,

    那几个通道采样结果就会出错
    下面的代码12号ADC结果寄存器的值就会有问题

    您是怎么判断出错的?

    我不知道您的时钟配置和PWM周期。当16个SOC全部都被触发时,它们会按照从SOC0-15的顺序来进行转换(round robin),当这16个SOC全部被同一触发源触发时,我们可以很轻易的判断出转换顺序就是SOC0-15;但如果把其中之一配置为由另外一个触发源进行触发时,以您的情况为例,被EPWM2SOCA触发的那些SOC首先处于round robin的序列中,先执行SOC0的转换,其它SOC处于pending状态;而SOC11此时未被触发。

    SOC11的触发顺序取决于,EPWM2SOCB触发SOC11时,RRPOINTER所指向的位置(SOCx),即当前是哪个SOC处于转换状态。如果x小于11,则SOC11被添加到本轮转换之中;若大于11,则添加到下一轮转换之中。

    综上所述,转换结果与您的时钟配置、PWM周期配置是有关系的。

    建议您在调试过程中加入断点,结合一些标志位,观察整个ADC的运行状态。

  • 使用另一块开发板测试程序没有问题,这个问题可能是芯片引起的。

    理论上采样结果应该是2048左右,但是配置为不同触发源的那个SOC采样结果会变成4090左右。且进一步测试发现两个SOC触发时间比较接近时采样才会出错,例如我的两个PWM模块相互之间移相了180°,一个在zero采一个在prd采则会出问题,如果都是zero就没有问题,目前问题是暂时性通过在两个zero采跳过了,感谢您的解答