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万S:第一个样例的ADC问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/575005/tms320f28377s-adc-issue-with-first-sample

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

C2000团队,

我在F2.8377万S Launchpad上以 12位模式运行ADC-A,由ePWM以50 kHz速率触发,采集窗口为100 ns (20个周期@ 200 MHz SYSCLK)。  我正在使用CPU来获取单个50点数据缓冲区。  缓冲50个点后,在ISR中禁用ADC中断,因此我 不再缓冲点。  转换在ADCINA0通道上。

问题就在第一点。  请参见下图。  输入是一个1 kHz的三角形波,从大约0.2 到3.1V。  第一个点总是稍微偏离。  您可以在下面的CCS图中看到它。

我在启用ADC后添加了附加延迟,然后使用ePWM触发ADC。  没有区别。

我尝试了另一个信号发生器,认为这可能是输入的某种负载问题。  没有区别。

我尝试了另一个ADC (ADC-B)。  没有区别。

我将采集窗口增加了一倍,达到200 ns。  没有区别。

我查看了勘误表,没有看到关于第一个示例错误的任何信息。

现在,我使用TMX芯片(修订版B),但这似乎不是问题。  所有其他样本均正常(存在一些明显偏移误差)。

有什么想法  可能导致这种情况?

谢谢,此致,

David

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

    您可以尝试/调查的一些事情:

    A0通道也与缓冲DAC输出进行多路复用。 即使禁用了缓冲DAC,此引脚上也会有50kOhm的寄生负载。 您可以尝试使用不同的ADC输入来查看是否有帮助(A1和B1上也有DAC。 通道B0也略有不同,因为它是DAC参考引脚,因此具有~100pF的额外电容)。

    不确定您在ADC加电和第一组采样之间增加了多少额外延迟,但1毫秒应该是足够的加电时间。

    在B版上,在ADC通道组之间切换时,输入需要更多时间才能稳定(错误“ADC:切换通道组时的12位输入电容”)。 您可以尝试让每个触发器执行A0->A1,以查看在始终切换通道组时A0结果是否始终关闭。

    您在该通道上是否有任何外部电容或串联电阻? 您应该能够使S+H非常长的@~50kHz采样率成为一种简单的健全性检查。

    您看到多少偏移误差? 即使在12位模式下未修整,偏移量也应该相当好(<8 LSB)。 部分偏移错误可能是由于DAC mutxing,因此,如果使用A0以外的通道,则很有兴趣了解这种情况是否有所改善。

    您使用的是controlCARD,Launchpad还是自定义板? 早期版本的F2.8377万x controlCARD上的ADC参考驱动电路存在一些问题。

    ADC是否处于延迟中断模式? 如果不是,则此设备上的CPU足够快,可以进入ISR并在其准备就绪之前读取转换结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Devon:

    [报价用户="Devin Cottier"]
    您使用的是controlCARD,Launchpad还是自定义板? 早期版本的F2.8377万x controlCARD上的ADC参考驱动电路存在一些问题。[/QUOT]

    我正在使用F2.8377万S Launchpad。

    [报价用户="Devin Cottier"]
    A0通道也与缓冲DAC输出进行多路复用。 即使禁用了缓冲DAC,此引脚上也会有50kOhm的寄生负载。 您可以尝试使用不同的ADC输入来查看是否有帮助(A1和B1上也有DAC。 通道B0也略有不同,因为它是DAC参考引脚,因此具有~100pF的额外电容)。[/QUOT]

    我尝试使用ADCINA5。  没有区别。

    [报价用户="Devin Cottier"]
    ADC是否处于延迟中断模式? 如果不是,则此设备上的CPU足够快,可以进入ISR并在其准备就绪之前读取转换结果。[/QUOT]

    是的,ADC处于延迟中断模式。

    [报价用户="Devin Cottier"]

    您看到多少偏移误差? 即使在12位模式下未修整,偏移量也应该相当好(<8 LSB)。 部分偏移错误可能是由于DAC mutxing,因此在使用A0以外的通道时,如果这种情况有所改善,将很有意思。

    如果我使用AA电池作为输入,我可以获得总误差的一些测量值。  蓄电池测量1.488 V。 因此,预期转换值为

    X = 4096*(VIN - VREFFLO)/(VREFHI - VREFFLO)= 4096*(1.488 - 0)/(3.0 - 0)= 2032

    观察到的值大约为0x0809 = 2057。  因此,我有一个组合偏移和增益误差,在中等满刻度范围内,总计约25个LSB。  您可以看到下面的结果非常干净。  有趣的是,我做了几次这个实验。  第一个转换值与其他值相比似乎总是有点高。

    在下方,输入为方波,0V低和2.8V高。  2.8V应理想地转换为0xEEF。

    再次注意,第一个转换值高于其他"高"值。  

    此致,

    David

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

    您是否可以使用DMM测量VREFHI引脚? 它与3.000V的精确距离有多近? 中尺度25个LSB比预期增益和偏移误差稍高(DS中的最大增益为+/-5LSB,偏移为+/-4LSB)。 取消微调/TMX不会对该设备产生太大影响。 在额定条件下,REF3030应在0.2 % 范围内,这相当于8个LSB的满刻度增益误差。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好,Devin,

    我从实验室中获得了更好的DMM (Tektronix DMM912),而不是我在办公桌上拥有的价值10美元的垃圾玩具计。

    REF3030输出为2.9997V (在F2.8377万S Launchpad上U10的引脚2处)。
    VREFHIA为2.9997V (LP上的u11的引脚1处)
    我重新测量了我的AA电池:1.5041 V

    电池应转换为4096*(Vin-Vrefero)/(Vrefhi-Vrefero)= 4096*(1.5041 -0)/(2.9997 -0)= 2054

    使用ADCINA0 通道时实际观察到的转换值为2065 (平均50个样本。 电池连接到LP上的3.27)。
    使用ADCINA12通道的实际观测转换值为2059 (平均50个样本。  电池连接到LP上的3.27)
    使用ADCINA5通道时实际观察到的转换值为2071 (平均50个样本。  电池连接到LP上的7.65)

    记得ADCINA12和ADCINA0都连接到设备上的ADCINA0引脚,所以我没有更改这两个测量的电池与启动板的连接。  我以不同的顺序多次运行上述测量,重新生成代码, 更改连接和运行等。 如果您更改 蓄电池的机械连接,结果可能会有变化。  如果保持连接不变,则结果大部分是一致的。

    以下是每次测量的ADC缓冲器的屏幕截图:

    ADCINA0 (ADCINA0):

    ADCINA12:

    ADCINA5:

    我在代码中逐步执行了AdcSetMode()函数,我的  TMX设备上似乎没有填充ADC偏移和INL微调数据。  没有预料到。

    让我们暂时忘记偏移误差,因为我认为这是可以控制的。  如果查看上面的屏幕截图,您会发现缓冲区中的第一个转换比ADCINA0和ADCINA5中的其它转换要高得多。  由于某种原因,这不适用于ADCINA12。  我将采集窗口从20个SYSCLK周期增加到80个周期,并且第一个值似乎与平均值更一致。  结果好坏参半,似乎对我有点影响。

    David

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

    您好,David:

    我不能说我曾经使用过电池作为ADC输入源。  我猜它没有足够的带宽来正确驱动ADC输入。  要将其用作直流测试源,我建议在ADC引脚上提供一个至少为4096 * 4 * Ch = 4096 * 4 * 14.5pF = 238nF的外部电容器。  

    更好的做法是将函数发生器设置为直流模式。  在10pF - 100pF范围内添加电容器通常是正确信号源的良好做法。

    您也可以使用电源作为直流电源,但您需要在输出中添加一些相当大的电容以降低噪声。  我使用了一个470uF电解电容器和一个1nF陶瓷电容器,这似乎做得很好。  

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

    Devin,

    我增加了300 nF的电容,这似乎有助于第一个样品,也有助于通过较小的采集窗口进行偏移(精度)转换。  当我将采集窗口减少到15个SYSCLK周期(75 ns)时,我得到了相当大的误差。  随着电容的增加,额外的误差似乎消失了。

    现在我将单独讨论这个问题,继续讨论。  但有一个问题:保持电容器的设计是在每次转换之间放电,还是保持其值(并且可能缓慢泄漏放电)?  我认为答案是较晚的(保持其值),这使得很难理解为什么一个小的采集窗口会在保持上限提高后给我带来错误。

    谢谢!

    David

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

    在该设备上,无论何时在偶数和奇数通道之间切换,采样电容器都会完全放电。 连续采样同一通道组时,电荷可能非常接近也可能不是非常接近之前的采样,具体取决于SAR转换顺序。

    最佳做法是始终假定保持电容器可以是设备参考范围内的任何电压。 通常,最简单的建模方法是假设您正在尝试驱动满刻度电压,并且电容器开始完全放电。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好,

    我注意到了同样的问题,想打开一个新的帖子,但David在我之前就这样做了;)

    该问题仅发生在第一次采样和不同采样频率下(分别为2,5kHz,50kHz和100kHz)。

    信号为方波0 - 2V (分别为60Hz,1kHz,5kHz)

    价值406! 这是一个很大的错误

    Paolo

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

    问题与David相同:

    -您的信号源是什么样子的?
    -您在什么硬件/套件上运行此程序?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    嗨,Davin,大家好

    当我绘制除第一个样本以外的方波时,信号看起来像方波。 其他值一般是正确的,即使我认为有一些样品丢失。

    我没有专业的信号发生器,所以我用Ni-Mydaq来生成信号,但我不认为这是问题。 如果是,则其他一些样本应该是错误的。


    可能是ePWM SOC系统的问题?

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

    您好,Paolo:

    如果信号范围是0到2V,并且您以某种方式获得大于400V的计算结果,我不认为问题纯粹是由错误的样品引起的...在计算结果时也必须存在SW问题,因为ADC将在4095的数字输出下饱和 LSB (3.0V范围,2V = 2730 LSB)。  

    如果直接查看原始ADC输出,调试可能会更容易。

    您使用的是什么套件/硬件? 这是controlCARD,launchpad还是自定义板?

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

    你好,Davin,

    是的,我同意,我认为 问题是SW。

    第一个元素的值的可变性非常随机:如果我尝试在debug中运行程序,数字会不同,但有时是正确的。

    我正在使用C2000 Delfino MCU F2.8377万S LaunchPad开发套件。

    当我在家时,我尝试直接调试ADC缓冲器,并将更加精确。

    非常感谢。

    Paolo。

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

    Devin,

    我今天更喜欢这个,我不相信这是电容问题。  今天,我在3.125 MSPS上运行所有四个ADC,结果交错。  因此,有效采样是12.5 MSPS。  ADC触发的顺序如下: A->C->B->D  输入为~1 MHz三角形波。  因此,每个周期应有12.5 样本。  我得到了大约11个,我目前忽略了它,并将其归因于TMX芯片中的一个未校准的内部振荡器。  下面是结果的图解:

    您会注意到第一个样本(来自ADC-A)太高。  如果仔细观察,您会发现样本2,3和4 (分别来自ADC-C,B和D)也不对齐。  之后,样本看起来很好。

    我或许能够说服自己,样品2,3,4误差是由于电容和采集时间,而不是样品1。  如果样品1没有足够的时间为保持电容器充电,为什么转换值过高?

    请注意,我不会在任何ADC上切换信道。  我总是在转换ADCINx12,它连接到所有四个ADC的ADCINA0引脚。

    该数据是在采用TMX Rev.B硅的F2.8377万D实验板套件上获得的。

    此致,

    David

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

    您好,David:

    同意;第一个样本肯定存在根本问题(接下来的三个样本可能有点不正确)。

    这可能是第一组样本的SW计时问题。  我很有信心您可以有效地对此进行调试,但需要快速思考一下:

    确保在ADC和ePWM均已完全配置并准备好采样后启用TBCLKSYNC

    我认为您有两个ePWM与128个周期同步,每个ePWM触发2个ADC?

    -ACQPS应介于 32和14之间?

    对于HW:您已将哪个controlCARD修订版插入实验者的套件中?  某些较旧的controlCARD具有错误的运算放大器驱动ADC参考引脚,这可能不稳定并导致某些奇怪的ADC行为。  您可以通过使用导线绕过参考驱动运算放大器或用正确的运算放大器替换它来解决此问题。  在一些较新的controlCARD修订版上,与ADC参考电容器串联的100 m 欧姆电阻器错误地使用100m欧姆电阻器构建,这会再次导致某些奇怪的ADC行为(可通过用0欧姆或焊接桥替换电阻器来解决此问题)。  

    我可能建议使用外部XTAL与内部振荡器进行高速信号采样...附加抖动将显著影响SNR @ 1MHz (请注意,ADC SNR在12位模式下指定为100KHz,使用外部XTAL)。  我认为所有controlCARD都有一个外部XTAL或时钟源。  

    如果您停止采样过程,然后在第一个样本仍然出现问题时重新开始,我也会感兴趣吗?  如果是,请尝试缩短启动和停止之间的时间...如果错误的幅度随启动/停止之间的时间而变化,则表明存在模拟问题, 但是,如果它始终相同,即使您仅停止几个周期,它也会指出SW问题。  

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

    Devin,

    >>确保在ADC和ePWM均已完全配置并准备好采样后启用TBCLKSYNC

    是的。

    >> ACQPS应介于 32和14之间?

    是的。

    >>如果您停止采样过程,然后在第一个样本仍然出现问题时重新开始,我也会感兴趣吗?

    我或多或少地运行了这个实验。  我又跑了。  我只使用ePWM触发的ADC-A (在带有Rev.B TMX芯片的F2.8377万S Launchpad上运行)恢复到简单代码。  采样率为1 MHz。  输入为8300 Hz三角形波形。  CPU正在收集基于SOC0 EOC中断的ADC结果。

    首先,如果您在重置后读取ADCARESULT0寄存器,但在完成转换之前,您将读取零。  我通过在配置ADC后(但在通过ePWM触发之前)立即读取结果寄存器来测试此情况。  这与TRM SPRUHX5D第1322页显示的此寄存器默认为零一致。

    现在,我的基线代码显示了第一个示例问题。  您可以在示例1中看到错误:

    然后我修改了我的代码,以便在配置过程中,软件触发ADC SOC0。

       AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;    //中断脉冲,与标志状态无关
       ADcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;     // EOC0触发中断
       AdcaRegs.ADCINTSEL1N2.bit.INT1E =0;       //禁用ADC中的中断
       ADcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;         //打开ADC电源
       DelayUs(1000);                             //加电后等待1毫秒,然后再使用ADC
       AdcaRegs.ADCSOCFRC1.bit.SOC0 = 1;          //软件触发器SOC0
       DelayUs(1000);                             //等待足够长的时间以结束转换

       AdcaRegs.ADCINTSEL1N2.bit.INT1E =1;       //在ADC中启用中断
       PieCtrlRegs.PIEIER1.bit.INTx1 =1;//         在PIE组1中启用ADCA1中断
       IER |= 0x0001;                             //在IER中启用INT1以启用PIE组

    然后,我继续像之前一样配置ePWM以进行触发。  问题消失了:

    David

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

    David,

    您可以尝试以下操作:  

    AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1;//中断脉冲,与标志状态无关
    ADcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// EOC0触发中断
    AdcaRegs.ADCINTSEL1N2.bit.INT1E =0;//禁用ADC中的中断
    ADcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;//打开ADC电源
    DelayUs(1000);//加电后等待1毫秒,然后再使用ADC
    AdcaRegs.ADCSOCFRC1.bit.SOC0 = 1;//软件触发器SOC0
    AdcaRegs.ADCSOCFRC1.bit.SOC1 = 1;//软件触发器SOC1
    DelayUs(1000);//等待足够长的时间以结束转换

    AdcaRegs.ADCINTSEL1N2.bit.INT1E =1;//在ADC中启用中断
    PieCtrlRegs.PIEIER1.bit.INTx1 =1;//在PIE组1中启用ADCA1中断
    IER |= 0x0001;

    在什么位置,即使SOC0配置为奇数信道,SOC1配置为奇数信道?如果SOC0配置为偶数信道,SOC0配置为奇数?

    或者,您可以将SOC0配置为使用另一个信道库,然后在软件强制后切换信道配置。

    当您在每个ePWM事件中触发两个转换(其中第二个转换是其他通道)时,会发生什么情况?

    您是否尝试使用ADCIN14/15而不是输入12?  这些输入还可输出到所有信道,但不会遇到寄生DAC负载。  

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

    嗯。  我将SOC1配置为转换ch.1 (奇数通道)。  在SOC0 (通道12)开关触发后,I SW触发SOC1。  第一个样本的问题再次出现。

    这意味着什么?  它听起来就像在交换信道库发生转换错误后,信道库中的首次转换。

    David

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

    有两个勘误表涵盖了这一点。  一个只适用于修订版0和A,另一个适用于0,A和B 。(生产TMS硅应该都是修订版C)。  

    您能否确认哪些勘误表适用于您的套件?

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

    Devin,

    我有Rev.B芯片,因此您展示的两个勘误表中的第二个适用于您。  我已经查看了勘误表,但没有想到会出现此问题,因为我没有切换信道。  显然,ADC的第一个转换被视为一个组交换机。

    这是问题的唯一根源,我对此并不完全满意。  即使我将采集时间从75 ns增加到375 ns,我仍然可能会出现一些初始样本错误(尽管没有以前那么明显)。  此外,错误通常是第一个采样值过高,这是我不会想到的电容问题。

    看来我需要做的是尝试使用Rev.C芯片,不幸的是,我没有这种芯片。  我的两款主板都使用Rev.B芯片。

    我将尝试在这一点上继续。  感谢你的帮助。

    David

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

    大家好,

    我做了一些测试,结果看起来不错。

    我只是用uint16_t RFFTin1Buff [DIM]替换了float32输入缓冲器。

    PWM和ADC的设置 与ADC_SOC_ePWM示例相同。 问题似乎消失了,但需要更多的实验。

    例如,5kHz正弦波,Fsampling = 100kHz,2Vpp,1.1V平均

    我会做更多的测试,让您了解最新情况。

    此致,

    Paolo。

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

    正弦波绝对看起来很好。

    如果基本问题是将未签名的ADC结果转换为适当缩放的浮点值,则可能需要启动有关该主题的新线程。 您也可以通过搜索e2e上的其他帖子来找到有关该主题的一些帮助。

    如果您最终遇到了采样过程本身的问题,则此线程可能仍是发布的好地方。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    啊,伙计们,我做了其他的测试。

    锯齿,2Vpp。

    一切都很好,没有更多的麻烦,即使不是总是无可挑剔,但很好。 我认为问题是缓冲区的类型,它不像float :D:D

    只要我希望能更好地消除残余,并最终就这一论点打开一个新的思路。

    此致

    Paolo

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

    Devin,

    [报价用户="David M. Alter"]

    我有Rev.B芯片,因此您展示的两个勘误表中的第二个适用于您。  我已经查看了勘误表,但没有想到会出现此问题,因为我没有切换信道。  显然,ADC的第一个转换被视为一个组交换机。

    这是问题的唯一根源,我对此并不完全满意。  即使我将采集时间从75 ns增加到375 ns,我仍然可能会出现一些初始样本错误(尽管没有以前那么明显)。  此外,错误通常是第一个采样值过高,这是我不会想到的电容问题。

    看来我需要做的是尝试使用Rev.C芯片,不幸的是,我没有这种芯片。  我的两款主板都使用Rev.B芯片。

    [/引述]

    我已经能够在采用F2.8377万D Rev.C芯片的主板上对其进行测试。  第一个样本的关闭时间总是多于其他样本。  不是很多,但它是可检测的。  以下是使用插槽式FAE板的恒定2.500 V输入,3.315 V参考(均已测量),12位模式,ADC-A ch.12 (连接到ADCINA0),35 SYSCLK周期(175 ns)的采集窗口,50 kHz的采样率的结果。

    正确结果应为4096 *(2.500 / 3.315)= 3089。  您可以看到,第一个结果的错误比其他任何结果都多。  我运行了多次实验,每次都能得到相同的结果。  第一个示例显示更多错误。  这里的问题远比我在Rev.B芯片上看到的要小。  但是,它仍然可以被检测到。  只需记录此处发生的情况。

    此致,

    David

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们都期待着找到一个解决方案:)

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

    问题仍然存在...

    这种行为非常奇怪,现在不仅是第一个样本,还有其他样本。

    此外,还会出现另一个奇怪的错误:

    我不知道是否与主要问题有关。

    但是,我想分享我的程序,以便您更好地了解问题。

    ###############################################################
    //文件:adc_so_ePWM_cpu01.c
    //标题:ADC通过ePWM触发F2837xS。
    ////
    ! \addtogroup cpu01_example_list
    //! <h1>ADC ePWM触发(ADC_SOC_ePWM)</h1>//
    !
    //! 此示例设置ePWM以定期触发ADC。
    //!
    //! 程序运行后,内存将包含:\n
    //! -\b AdcaResults \b:
    来自//的一系列模数转换样本。 针脚A0。 样本之间的时间根据周期
    //! ePWM计时器。
    //
    //###########################################################################
    //$TI发布:F2837xS支持库v191 $//
    发布日期:星期五3月11日15:58:35 CST 2016美元
    //$版权:版权所有(C) 2014-2016 Texas2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ 保留所有权利$//#########################################################################################
    
    
    //文件:Voltmetic_FFT.c
    //标题:ADC通过ePWM触发F2837xS。
    ////
    ! \addtogroup cpu01_example_list
    //! <h1>ADC ePWM触发(ADC_SOC_ePWM)</h1>//
    !
    //! 此示例设置ePWM以定期触发ADC。
    //!
    //! 程序运行后,内存将包含:\n
    //! -\b AdcaResults \b:
    来自//的一系列模数转换样本。 针脚A0。 样本之间的时间根据周期
    //! ePWM计时器。
    //
    //###########################################################################
    //$TI发布:F2837xS支持库v191 $//
    发布日期:星期五3月11日15:58:35 CST 2016美元
    //$版权:版权所有(C) 2014-2016 Texas2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ 保留所有权利$//#########################################################################################
    
    
    #include "F28x_Project.h"// Device Headerfile and examples include File
    #include <FPU_mathy.h>
    #include <FPU_vector.h>
    #include <FPU_filter.h>
    #include <stdlib.h>
    #include <fu_fu_fut_fh_fut#ft#fut_fh"#fp_fut_fut_fh"#fp_fh_fut_fut_fh"
    
    
    #fp_fut_fut_fut_fh_fh"#fp_fp_fh_fh"#fp_fp_fh_fp_fh_fut_fh_fut_fut_fh_fh"
    
    
    
    #fp_fp_fh_fh_fh_fh_fp_fp_fh_fh_#fh_fh_fp_#fp_#fp_#fp_#fp_fp_#fp_#fp_fp_f
    
    
    
    
    
    
    
    
    #define NPP16
    #define UART0_BASE 0x7200
    #define SizeCharDisplay 20
    
    
    
    
    
    //......... FIR滤波器设置..........
    #define FIR_ORDER 511
    #pragma DATA_SECection(firfp,"firfilt")
    FIR_FP FIRFP = FIR_FP_DEFAULTS;
    
    FIR_FP_HANDLE HND_FIRFP =&FIRFP;
    
    #pragma DATA_SECection(dbuffer,"firldb")
    float32 dbuffer[FIR_ORD+1];
    
    //#pragma DATA_SECection(pragma
    #pragma data_section(sigOut,"sigOut");
    //float sigIn[signal_length];
    float32 sigOut[RFFT_size];
    
    #pragma data_section(coeff, "coefffilt");
    float32 const coeffe[FIR_ORIENT+1]= FIR_FP_LPF512;//..................................
    
    
    //RFFT_ADC_F32_struct rfft_adc;
    //RFFT_ADC_F32_strut_handle HND_rfft_adc =&rfft_adc;
    
    RFFT_F32_pragt rfft;RFFT_F32_pragt rfft rfft;
    RFFT_buffa1
    
    
    
    
    
    ;RFabetfabet_fabetfabetfabetfabet;
    
    
    #pragma data_section(RFFTmagBuff,"RFFTdata3");
    float32 RFFTmagBuff[RFFT_size/2];
    
    #pragma data_section(RF32Coef,"RFFTdataa4");
    float32 RFFTF32Coef[RFFT_size];
    
    #pragma data_section(Power,"praga5";
    Float32 Power[RFFT_size/2];
    
    //#pragma data_section(PeakValueFFT,"RFFTdata6");
    //float32 PeakValueFFT[RFFT_size/2];
    
    //#pragma data_section(ADCin1Buff,"RFFTdata7");
    //flat32[FT_Scaled Signalize_Buffer;
    
    #pragma data_section(ADCin1Buff,"RFFTdata7");
    uint16_t ADCin1Buff[RFFT_size];
    
    #pragma data_section(Buffer_Signal_Scaled,"RFFTdata8");
    float32 Buffer_Signal_Scaled[RFFT_size];
    
    //const RECFTWindow[RFureFT_size];RFureFT_2048f_ed/ConfigFTADC;
    
    
    
    
    //ADC,PWM
    void ConfigureEPWM (void);
    void SetupADCEpwm (UINT16通道);
    
    
    //void RFFT_F32_WIN (float *pbuffer,float *pWindow,uint16_t size); //FFT
    //void RFFT_F32_MAG(RFFT_F32_struct*);
    void PowerSpectrumCompute (void);
    void FFT(void);
    
    
    void FloatToString(car *str,float f, 字符大小);//显示
    void PrintFloatOnString (const char *Token1,float measure,char SizeMeasure,const char *Token2);
    void PrintIntegerOnString (const char *Token1,long measure,const char *Token2);
    void Print_Freq (float freq);
    
    //useutuart (void; //UART
    
    中断void adca1_isr (void);//ADC isr
    中断void xint3_isr (void);//GPIO60 isr
    
    静态int max (const float A[],const int dim,const int index);
    
    
    void set_Sample_Frequency (float fs);//获取和详细
    静态float True_RMS (float Signal),const pin,const int[,const int],const int index;void
    (fid)
    静态浮点频率_计算(const float Power_Spectrum [],const float FS,const int FFT_size,const unsigned int Max_Index);
    void AcqueSignal (void);
    void scale_input_buffer (void);
    
    
    void SetFreqUP (void);
    
    
    
    void SetPinLCD(void);// GPIO PIN
    
    UINT16结果Index;
    volatile UINT16 bufferFull;
    
    
    float RMS_value =0;
    float Freq;
    float FSample,FSample_default;
    unsigned int Max_Index =0;
    volatile char state =0;
    
    
    
    //unsigned int msg1UART;//= strlen (msg1);
    
    //初始化。 设置波特率,数据位数,关闭奇偶校验,停止位数和记忆棒模式。
    //UINT32_t param1 =(UINT32_t)&SciaRegs;// 0x0.721万;//UINT32_t
    param2 =(UART_CONFIG_WLEN_8| UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_EZ);
    //UART32_t PARAM3 =5000万;//UINT32_T param1
    ,
    启用
    
    主参数
    1,配置
    
    
    
    1,配置0 初始化系统控制:
    // PLL,看门狗,启用外设时钟
    //此示例功能可在F2837xS_sysctrl.c文件中找到。
    InitSysCtrl();//
    
    步骤2. 初始化GPIO:
    //此示例函数可在F2837xS_GPIO .c文件中找到,
    //说明了如何将GPIO设置为其默认状态。
    此示例跳过InitGpio();//
    
    
    //步骤3. 清除所有中断并初始化PIE矢量表:
    //禁用CPU中断
    dint;
    
    //将PIE控制寄存器初始化为其默认状态。
    //默认状态是禁用所有PIE中断,
    并清除标志//。
    //此函数位于F2837xS_PIECTRL.c文件中。
    InitPieCtrl();
    
    SetPinLCD();//setta i pin per il显示器
    initialize_lcd();
    HOME_LCD();//
    
    禁用CPU中断并清除所有CPU中断标志:
    IER = 0x0000;
    IFR = 0x0000;
    
    //使用指向shell Interrupt
    //服务例程(ISR)的指针初始化PIE矢量表。
    //这将填充整个表,即使在此
    示例中未使用中断//。 这对于调试非常有用。
    // shell ISR例程位于F2837xS_DefaultIsr.C.中
    //此函数位于F2837xS_PieVect.C.中
    InitPieVectorTable();
    
    
    
    
    
    //Map ISR函数
    EALLOW;
    PieVectorTable.ADCA1_INT =&adca1_ISR;// ADCA中断1的函数
    PieVectorTable.XINT3_INT =&xint3_isr;
    EDIS;
    
    //配置ADC并开机
    ConfigureADC();//
    
    配置ePWM
    ConfigureEPWM();
    
    //在通道0上设置ePWM触发转换的ADC
    SetupADCEpwm(0);
    
    
    
    //启用全局中断和较高优先级的实时调试事件:
    IER || M_INT1;//启用组1中断
    EINT;//启用全局中断INTM
    ERTM;//启用全局实时中断DBGM
    
    
    结果索引=0;
    缓冲器全轮= 0;
    
    
    //HND_rfft_ADC->Tail =&(HND_rfft->OutBuf);
    hnd_rfft->FFTSize = RFFT_SIZE;//FFT大小
    hnd_rfft->FFTStages = RFFT_stages;//FFT stages
    
    hnd_rfft->InBuf =&RFFTin1Buff[0];//输入缓冲区(12位ADC)输入
    hnd_rfft->OutBuf =&RFFToutBuff[0];//输出缓冲区
    HND_rfft->CosSinBuf =&RFFTF32Coef[0];//twiddle因子
    hnd_rfft->MagBuf =&RFFTmagBuff[0];//幅值输出缓冲区
    RFFT_F32_Sincostable (HND_rfft);//计算宽度因子
    
    /* FIR通用过滤器初始化*/
    hnd_firfp->order = FIR_ORDER;
    hnd_firfp->dbuffer_ptr = dbuffer;
    hnd_firfp->coeff_ptr =(float *) coeff;
    hnd_firfp->init(Hnd_firfp);
    
    
    //在PIE中启用Xint3:组12中断1
    PieCtrlRegs.PIECTRL.bit.ENPIE =1;//启用PIE块
    PieCtrlRegs.PIEIER12.bit.INTx1= 1;//启用PIE组12 INTx1
    IER || M_INT12;//启用CPU INT12
    EINT;//启用全局中断
    
    
    XintRegs.XINT3CR.bit.POLARITY = 2;//下降边缘
    XintRegs.XINT3CR.bit.enable = 1;//XINT3 interrpt enable
    
    
    GPIO_SetupXINT3Gpio(60);//GPIO60 SU XINT3
    
    
    
    //启用PIE中断
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    
    //sync ePWM
    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    
    
    //无限循环转换
    做
    {
    开关(状态){
    
    案例1:
    
    执行{
    
    IF (GPIO _ReadPin (4)== 0)
    {
    DELAY _US (1万);
    SetFreqUP();}
    
    
    
    IF (GPIO _ReadPin (19)== 0)
    {
    DELAY _US (1万);
    SetFreqDWN();
    
    }
    
    PrintIntegerOnString ("速率:",(长) FSample," Hz);
    HOME_LCD();
    
    }同时(GPIO_ReadPin(61)!=0);
    
    Set_Sample_Frequency (FSample);
    DELAY _US (1万);
    状态= 3;
    中断;
    
    案例2:
    Set_Sample_Frequency (FSample);
    DELAY _US (1万);
    状态= 3;
    中断;
    
    案例3:
    DELAY _US (1万);
    AcquitreSignal();//获取信号
    scale_input_buffer();
    memcpy_fast (Buffer_Signal_Scaled,RFFTin1Buff,RFFT_size*sizeof(Float));
    FFT();//FFT计算
    PowerSpectrumCompute ();//功率谱
    Max_Index =最大值(功率,RFFT_SIZE>>>1,1);//搜索索引最大值起点为1个元素(无DC组件)
    频率=频率计算(功率,FSample,RFFT_Size,Max_Index);
    RMS_Value = True_RMS (Buffer_Signal_Scaled,RFFT_Size,Freq,FSample);
    
    PrintFloatOnString ("VRMS:",RMS_Value,3," V");
    goto_line_lcd (2);
    print_Freq (Freq);
    GOTO LINE_LCD (3);
    PrintIntegerOnString ("速率:",(长) FSample," Hz);
    HOME_LCD();
    中断;
    
    默认:
    FSample = 1万.0 ;//10 KHz默认值
    状态= 2;
    中断;
    }
    ASM (" ESTOP0");
    } While (1);
    
    
    }//
    
    
    
    写入ADC配置,并为ADC A和ADC B
    void ConfigureADC(void){打开ADC的电源
    
    EALLOW;
    
    //写入配置
    AdcaRegs.ADCCTL2.bit.prescale =6;//将ADCCLK除法器设置为/4
    AdcSetMode (ADC_ADCA,ADC_Resolution _12位,ADC_SIGNALMODE_SINGLE);
    
    
    //将脉冲位置设置为延迟
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    
    //打开ADC的电源
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    
    
    //延迟1毫秒,以使ADC有时间开机
    DELAY _US (1000);
    
    EDIS;
    }
    
    void ConfigureEPWM (void)
    {
    EALLOW;
    //假定ePWM时钟已启用
    
    EPwm1Regs.ETSEL.bit.SOCAEN = 0; //禁用组上的SOC
    EPwm1Regs.ETSEL.bit.SOCASEL = 4; //在计数时选择SOC
    EPwm1Regs.ETPS.bit.SOCAPRD = 1; //在第一个事件上生成脉冲
    EPwm1Regs.CMPA.bit.CMPA = 311;
    EPwm1Regs.TBPRD = 624;
    EPwm1Regs.TBCTL.bit.CTRMODE = 3; //冻结计数器
    EDIS;
    }
    
    void SetupADCEpwm (UINT16通道)
    {
    UINT16 acqps;
    
    //根据分辨率确定最小采集窗口(在SYSCLKS中)
    IF ((ADC_Resolution _12bit == AdcaRegs.ADCCTL2.bit.Resolution){
    acqps =14;//75ns
    }
    否则{//分辨率为16位
    acqps =63;//320ns
    }
    
    //选择要转换的通道和转换结束标志
    EALLOW;
    AdcaRegs.ADCSOC0CTL.bit.CHSEL =通道;//SOC0将转换针A0
    
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//样例窗口为100 SYSCLK周期
    
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// ePWM1 SOCA/C上的触发器
    
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;//SOC0的结尾将设置INT1标志
    
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用INT1标志
    
    AdcaRegs.ADCINTFLGCLL.bit.ADCINT1 =1;//确保INT1标志已清除
    }
    
    
    中断无效adca1_ISR(void){
    
    
    ADCin1Buff[resultsIndex+]=(AddaResultRegs.ADCRESULT0);
    IF (RFFT_Size<=resultsIndex)
    {
    结果索引=0;
    缓冲区完全= 1;
    }
    
    ADcaRegs.ADCINTFLGCLL.bit.ADCINT1 = 1;//清除INT1标志
    PieCtrlRegs.PIEACK_ALL = PIEACK_Group1;
    }
    
    
    
    中断无效xint3_ISR(void)
    {
    状态= 1;
    PieCtrlRegs.PIEACK.ALL = PIEACK_Group12;
    
    }
    
    
    void SetPinLCD(void)
    {
    
    GPIO_SetupPinMux(41, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(41, GPIO_OUTP, 0) GPIO_PushPull);
    GPIO设置PinMux (71,GPIO _MUX_CPU1,0);
    GPIO设置PinOptions (71, GPIO输出,GPIO _推送Pull);
    GPIO _设置PinMux (89,GPIO _MUX_CPU1,0);
    GPIO_SetupPinOptions (89,GPIO输出,GPIO _推送);
    GPIO _设置PinMux (90,GPIO _MUX_CPU1, 0);
    GPIO_SetupPinOptions (90,GPIO输出,GPIO PushPull);
    GPIO _SetupPinMux (72, GPIO_MUX_CPU1,0);
    GPIO设置引脚选项(72,GPIO输出,GPIO按钮);
    GPIO_SetupPinMux (78,GPIO _MUX_CPU1,0);
    GPIO _SetupPinOptions (78,GPIO输出, GPIO_PushPull);
    GPIO设置PinMux (65,GPIO _MUX_CPU1,0);
    GPIO设置PinOptions (65, GPIO输出,GPIO _推送Pull);
    GPIO _设置PinMux (43,GPIO _MUX_CPU1,0);
    GPIO_SetupPinOptions (43,GPIO输出,GPIO _推送);
    
    GPIO _设置PinMux (60,GPIO _MUX_CPU1, 0);//usato per cambiare la freq di campionamento
    gPIO_SetupPinOptions (60,gPIO_INPUT,gPIO_PushPull);
    
    gPIO_SetupPinMux (61,gPIO_MUX_CPU1, 0);//confermo la freq di campionamento
    gPIO_SetupPinOptions (61,gPIO_INPUT,gPIO_PushPull);
    
    gPIO_SetupPinMux (4,gPIO_MUX_CPU1, 0);//增量la freq di campionamento
    gPIO_SetupPinOptions (4,gPIO_INPUT,gPIO_PushPull);
    
    gPIO_SetupPinMux (19,gPIO_MUX_CPU1, 0//decimento la freq di campionamento
    gPIO_SetupPinOptions(19, gPIO_INPUT,gPIO_PushPull);
    
    
    
    }
    
    void AcqueSign(void)
    {
    //启动ePWM
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;//启用SOCA
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;//unfreeze,并进入UP计数模式
    
    
    //等待ePWM导致ADC转换,然后导致中断,
    //填充结果缓冲区,最终设置bufferFull
    //标志
    while (!bufferFull);
    bufferFull = 0;//清除缓冲区已满标志
    
    //停止ePWM
    EPwm1Regs.ETSEL.bit.SOCAEN = 0;//禁用SOCA
    EPwm1Regs.TBCTL.bit.CTRMODE =3;//freeze counter
    
    }
    
    void FFT(void)
    {
    
    RFFT_f32u (HND_Rfft);
    RFFT_F32_MAG_TMU0(HND_Rfft);
    }
    
    
    void set_Sample_Frequency(Float FS)
    {
    unsigned int TBPRD =0;
    unsigned int CMPA =0;
    TBPRD =(unsigned int)((rnd_sp_rs (2亿.0 /(4*FS)-1)));
    CMPA =(unsigned int)((rnd_sp_rs ((2.0)-1)));
    EPwm1Regs.CMPA.bit.CMPA = CMPA;
    EPwm1Regs.TBPRD = TBPRD;
    
    }
    
    
    void scale输入缓冲区(void)
    
    {
    
    
    大小_t k;
    对于(k = 0;k <(RFFT_SIZE);k = k+2)
    {
    RFFTin1Buff[k]= 0.0.0732万421875</xmt-block>42.1875万 * ADCin1Buff[k];
    RFFTin1Buff[k+1]= 0.0.0732万421875</xmt-block>42.1875万 * ADCin1Buff[k+1];
    } // 0.0.0732万421875</xmt-block>42.1875万 =3/4096 (3V ADC参考)
    
    
    } 

    该程序是ADC_SOC_ePWM_cpu01示例的修改版本,但设置相同,仅按功能组织。

    也许,表员可以找到并解决问题。

    此致

    Paolo

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

    您好,David:

    当我在模拟VDB上使用OPA2227缓冲器和ADC输入上的10pF电容器,将直流输入电压为0.997V (预期代码=1633)的代码运行到ADC A5时,我得到了很好的结果:

    这是使用直流电源(E3631A),输出端带有470uF音频质量电解电容器和~3ft BNC电缆。  

    如果我移除缓冲器并直接驱动信号,由于布线电感,结果并不是很好。 这里的第一个样本和所有后续样本中都有错误。

    将S+H持续时间吹至500ns (仍无缓冲)主要可以缓解这种情况:

    同样,S+H保持75ns,但在引脚上添加~250nF电容器:

    请注意,为引脚添加大电容可能会导致需要限制具有大电容的引脚上的采样率,以防止由于ADC浪涌电流而逐渐放电。  

    此行为在代码,TI ePWM和连续采样示例中是一致的。  

    我最初在 您的代码和TI示例代码上看到了此行为的夸大版本。  这是由于ADC引脚上的部件电压过低而损坏(我的运算放大器驱动器具有浮动输入,导致它将~Ω-2V驱动到其中一个ADC D通道)。  如果您看到的错误明显大于我上面显示的错误,您可能需要尝试换用新部件,以防您使用的部件因测试或ESD损坏。

    我对您的代码所做的唯一更改是使用TI提供的“InitSysPll”函数来设置时钟。

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

    Devin,

    感谢您的跟进。  我在增加电容或增加采集窗口方面获得了类似的结果。  但是我无法使用缓冲进行测试,这是一个很大的帮助。  转换结果似乎对输入源和电路非常敏感,即使是对DC值也是如此。  使用直流输入时,我得到的结果实际上太高,在某些情况下增加了一些电容。

    以下是没有缓冲的结果,对于2.5005V输入(来自F2837x FAE板上的VREF),3.315 VREFHI ==>3089是理想结果。  15 CYC采集(75 ns),50 ksps:

    如果将 1 UF的电容添加到输入,则看起来更好:

    但如果我加上2个UF,情况就会更糟:

    最后,我添加了3个UF,结果会变得更好:

    显然,3 UF对于动态信号来说电容太大。  如您所见,增加采集窗口(此处为500 ns)可进行补偿,而无需电容:

    考虑到这是DC输入,结果令我惊讶。  但我想他们就是这样!

    此致,

    David