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.

[参考译文] TMS320F2.8377万D:TMS320F2.8377万X上的ADC模块配置问题。

Guru**** 2546020 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/620454/tms320f28377d-the-adc-module-configue-issue-on-tms320f28377x

部件号:TMS320F2.8377万D
主题中讨论的其他部件:controlSUITE

当我在2.8377万D上配置ADC模块时,我希望将A端口配置为16位模式,将B端口配置为12位模式,它能实现吗?

如上所述,我可以从端口结果读取数据...但无法从B端口读取。在这种情况下,AdcbRegs.RESULT0.-15都是零。但为什么?

配置代码如下所示:

void InitADC(void)(无效)

无符号int I;

EALLOW;

//part1:将ADCCLK除法器设置为/4
AdcaRegs.ADCCTL2.bit.prcale =6;
AdcbRegs.ADCCTL2.bit.prcale =6;
ADccRegs.ADCCTL2.bit.prcale =6;
AdcdRegs.ADCCTL2.bit.prescale =6;

//part2:16位差动ADC模式。

AdcSetMode (ADC_ADCA,ADC_Resolution _16BIT,ADC_SIGNALMODE_DIFFERENTIAL);
AdcSetMode (ADC_ADCC,ADC_Resolution _16BIT,ADC_SIGNALMODE_DIFFERENTIAL);
AdcSetMode (ADC_ADCB,ADC_Resolution _12位,ADC_SIGNALMODE_SINGLE);
AdcSetMode (ADC_ADCD,ADC_Resolution _12位,ADC_SIGNALMODE_SINGLE);

//part3:转换ADC后,将有关INTFlag的脉冲位置设置为晚期。
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
ADccRegs.ADCCTL1.bit.INTPULSEPOS = 1;
AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;

//part4:打开ADC的电源
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
ADcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
ADccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;

//part5:延迟时间> 1毫秒,以使ADC有时间开机
对于(i = 0;i < 1000;i++){ASM (" RPT#255 || NOP");}

//part6:为A/B/C/D端口配置SOCx。

AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2;//SOC0将转换adcina0/A1
AdcaRegs.ADCSOC0CTL.bit.ACQPS = ADCACQPS;//采样和保持时间窗口为100个SYSCLK周期
ADcaRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIGSEL;

//A4/5->VoltageUdc
AdcaRegs.ADCSO1CTL.bit.CHSEL = 4;//SOC1将转换adcina2/A3
AdcaRegs.ADCSOC1CTL.bit.ACQPS = ADCACQPS;//采样和保持时间窗口为100个SYSCLK周期
ADcaRegs.ADCSOC1CTL.bit.TRIGSEL = ADCTRIGSEL;

//B:B0/1/2/3->SPD
AdcbRegs.ADCSOC0CTL.bit.CHSEL = 0;//SOC0将转换adcinb0
AdcbRegs.ADCSOC0CTL.bit.ACQPS = ADCACQPS2;//采样和保持时间窗口为100个SYSCLK周期
ADcbRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIGSEL;

//C:C2/3->CurrentW
ADccRegs.ADCSOC0CTL.bit.CHSEL = 2;//SOC0将转换adcin14/15
ADccRegs.ADCSOC0CTL.bit.ACQPS = ADCACQPS;//采样和保持时间窗口为100个SYSCLK周期
ADccRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIGSEL;

AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 1;//SOC1结束时将设置INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用INT1标志
AdcaRegs.ADCINTFLGCLL.bit.ADCINT1 =1;//确保INT1标志已清除

EDIS;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,
    我写这封信是为了告诉您,一位C2000小组成员已被指派担任此职位,应该很快就会回答。

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

    我目前没有发现您的代码有任何问题。 您使用的是什么硬件? controlCARD? 自定义主板?

    您是否能够从controlSUITE运行ADC_SOC_SOFTWARE示例并查看B0上的转换结果?

    Whitney
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这里,当我在16位模式下在端口和C端口上使用16位,但不使用B端口和D端口,时,我可以找到A0/A1/C0的结果,其值正确。
    但是,当我在12位模式下在B端口和D端口上使用12位,但不使用端口和Dport,时,我可以找到Bx和Dx的结果,其值是正确的。
    但当我使用所有端口,例如16位用于端口和Cport,12位用于B端口和D端口,时,我可以找到A0/A1/C0的结果,但不能找到B端口和D端口的值。
    因此,我的意思是,您可以在2.8377万上进行测试,然后等待您的回复。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你好,Kafei:

    您使用什么来触发转换? 您是否使用ISR收集结果? 如果使用ISR,是从每个ADC生成ISR,还是仅从一个ADC生成ISR (通常我们建议并行转换多个ADC,但只触发一个ISR以收集结果)。

    在12位和16位之间分配通道的最佳方法是在同一ADC中,而不是通过选择某些ADC为12位,而选择某些ADC为16位。 这是因为同时运行两个不同的ADC,但具有不同的分辨率将导致ADC不在锁定步骤中运行,因此转换结果中会出现错误(请参阅同步模式与异步模式中指定性能的数据表)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好Devin,首先感谢您的回复!
    对于我提出的问题,今天我用TI的示例《ADC_SOC_SOFTWARE_cpu01》对TMS320F2.8377万D进行了测试,其,路径是C:\controlSUITE\DEVICE_SUPPORT\F2837xD\v190\F2837xD_Examples_CPU1 \ADC_SOC_SOFTWARE\cpu012837 \ADC_SOC_SOFTWARE\cpu01;在此项目中,我按如下所示配置ADC模块,:
    //PART1:
    void配置ADC(void)

    EALLOW;
    AdcaRegs.ADCCTL2.bit.prcale =6; //将ADCCLK除法器设置为/4
    AdcbRegs.ADCCTL2.bit.prcale =6;
    AdcSetMode (ADC_ADCA,ADC_Resolution _16BIT,ADC_SIGNALMODE_DIFFERENTIAL);//16位
    AdcSetMode (ADC_ADCB,ADC_Resolution _12位,ADC_SIGNALMODE_SINGLE); //12位

    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    ADcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    DELAY _US (1000);
    EDIS;
    }
    //Part2:
    void SetupADCSoftware(void)

    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0将转换差动A0/A1
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 63; //样本窗口为63+ 1 SYSCLK周期
    AdcaRegs.ADCSOC1CTL.bit.CHSEL = 2; //SOC1将转换差额A2/A3
    AdcaRegs.ADCSOC1CTL.bit.ACQPS = 63; //样本窗口为63+ 1 SYSCLK周期

    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 0; //SOC0将转换引脚B0
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = 63; //样本窗口为63+ 1 SYSCLK周期
    AdcbRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1将转换引脚B1
    AdcbRegs.ADCSOC1CTL.bit.ACQPS = 63; //样本窗口为63+ 1 SYSCLK周期
    EDIS;
    }
    然后我在主循环中对ADC样本进行三角试验,有些人会延迟主循环,如下所示:
    //Part3:
    执行{
    AdcaRegs.ADCSOCFRC1.ALL = 0x0003;//SOC0和SOC1
    AdcbRegs.ADCSOCFS2 = 0x0003;//SOC0和SOC1
    对于(i = 0;i < delaycount;I++)
    {ASM (" RPT#100 || NOP");}
    }同时(1);

    根据TMS320F2.8377万D的数据表,我们知道在12位采样模式下从S/H结束到vonversion结束到10.5 ADCCLK和16位采样模式下29.5 ADCCLK的转换时间;
    在此项目中,我将SYSCLK配置为200MHz,然后将ADCCLK配置为50MHz;
    因此,,我认为10.5 ,完成B0和B1的样品需要2 *(64*SYSCLK + 10.5 10.5 * ADCCLK)= 2 *(64*5+B1*20)ns=1260ns,而,2 *(64*SYSCLK + 29.5 * ADCCLK)= 2 *(64*5+A3*20)完成A2/16的样品 模式。
    但是,当我把变量delaycount取3,时,B0和B1的结果寄存器将为零值;这对我来说是不可理解的!
    虽然,请验证,等待您的回复!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Kafei:

    为什么要输入确定性延迟来确定ADC转换完成的时间? 这种方式的计时问题有时是,如果编译器认为代码的某些部分不执行任何操作,它就可以优化这些部分。

    如果您不想在转换完成时触发ISR,则检查转换是否完成的更好方法是轮询ADCINTFLG。 在您的情况下,由于要转换SOC0和SOC1,请将ADCINTFLG配置为在EOC1上设置。 这样,SOC0首先转换,SOC1接着转换,然后设置ADCINTFLG。 *转换顺序SOC0->SOC1假定RRPOINTER已重置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,Frank:
    现在,我按如下所示更改主循环中的代码:
    执行{
    //通过软件ADCA立即开始转换
    AdcaRegs.ADCSOCFRC1.ALL = 0x0003;//SOC0和SOC1
    ADCADT0 = CpuTimer0.RegsAddr->TIM.all;
    while (AdcaRegs.ADCCTL1.bit.ADCBSY);
    ADCADT1 = CpuTimer0.RegsAddr->TIM.all;
    ADCADT2 = ADCADT0 - ADCADT1;

    //立即通过软件ADCB开始转换
    AdcbRegs.ADCSOCFS2 = 0x0003;//SOC0和SOC1
    ADCBDT0 = CpuTimer0.RegsAddr->TIM.all;
    while (AdcbRegs.ADCCTL1.bit.ADCBSY);
    ADCBDT1 = CpuTimer0.RegsAddr->TIM.all;
    ADCBDT2 = ADCBDT0 - ADCBDT1;

    CpuTimer0.RegsAddr->TIM.All = 0;
    }同时(1);
    A为16位ADC_SIGNALMODE_DIFFERENTIAL模式,B为12位ADC_SIGNALMODE_SINGLE模式;
    当我按上述方式测试代码时,ADCADT2 = 384和,ADCBDT2 = 10;我不知道为什么???ADCBDT2的值太小,对我来说很难理解!

    但是,当我对主循环中的进行注释时,如下所示:
    执行{
    //立即通过软件ADCB开始转换
    AdcbRegs.ADCSOCFS2 = 0x0003;//SOC0和SOC1
    ADCBDT0 = CpuTimer0.RegsAddr->TIM.all;
    while (AdcbRegs.ADCCTL1.bit.ADCBSY);
    ADCBDT1 = CpuTimer0.RegsAddr->TIM.all;
    ADCBDT2 = ADCBDT0 - ADCBDT1;

    CpuTimer0.RegsAddr->TIM.All = 0;
    }同时(1);
    然后ADCBDT2 = 230;当我将AdcbRegs.ADCSOC0CTL.bit.ACQPS的值从63更改为14时,,ADCBDT2的值从230更改为175;,这意味着两个12位的Sample占用230 sysclks和175 sysclks;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Kafei

    除了在异步操作ADC时出现性能下降之外,它们几乎是独立运行的。 换言之,一个ADC的活动不应影响另一个ADC的计时。

    但是,正如我已经提到的,检查ADC转换是否完成的正确方法是使用ADCINTFLG。 您不应使用ADCBSY检查转换是否完成,因为在S/H完成后,它将清除4个ADCCLK,而不是在转换完成时,这两种模式的转换时间都超过4个ADCCLK。 ADCBSY信号更多用于调试,而不是用于在转换完成时进行检查。 即使您只对S/H完成的时间感兴趣,也可以使用ADCINTFLG并将脉冲生成设置为早期。

    请遵循前面概述的建议:

    将ADCINTSELxNy.INTzSEL源设置为EOC1 (这将导致SOC1完成S/H或转换后中断),将INTPULSEPOS设置为1 (这将导致转换完成后中断),重置RRPOINTER (这将确保SOC0在SOC1之前转换)。

    此外,由于是在循环中执行操作,因此需要清除循环的每次迭代的中断标志。 出于调试目的,我建议不要循环,而只运行一次,以查看您是否得到相同的响应。 如果在将代码更改为使用ADCINTFLG之后仍看到相同的代码,则返回报告。