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.

[参考译文] TMS320F28377D:SPI ADC DAQ 中的抖动

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/663707/tms320f28377d-jitter-in-spi-adc-daq

器件型号:TMS320F28377D

我使用的是 F28377D 'elfino' DSC。  我使用外部 ADC (AD7986)来获取18位样本。  ADC 将执行2MSPS、但这需要100MHz 的时钟频率。  DSC 有50MHz SPI 端口、但我无法使用它们、我正在使用 EMIF 的引脚。  因此、我将 PLLSYSCLK 设置为25MHz (40ns 周期)。  由于位宽限制为16、SPI 端口正在传输两个9位值。

我可以获取并存储以下数据和代码。  当我查看样本之间的时间时、它从3.76us 到3.84us 不等。  这相当于+/-1个时钟周期(40ns)。  

是否可以使时间更短到一致的值?  我目前没有使用中断或 CPU 时钟计时器、这两种方法是否有帮助?

uint32 read_spi (){

int i;
uint32 vsread

//发送 ADC 虚拟数据
for (i=0;i<2;i++){
SpibRegs.SPITXBUF = 0; //SPI-B
}

//等待数据被接收
while (SpibRegs.SPIFFRX.bit.RXFFST!=2){}

//转换 SPI-B 数据
Vsread = SpibRegs.SPIRXBUF; //加载 MS 9b
Vsread <= 9; //向左移位9位
vsread |= SpibRegs.SPIRXBUF; //加载并合并 LS 9b
Vsread = Vsread ^ 0x20000; //从二进制补码转换
返回 vsread
;}

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

    尊敬的 John:

    我想这里的主要问题是、您将 PLLSYSCLK 降低至25MHz。  这会减慢整个系统的速度。  每个 SPI 都有一个波特率寄存器、可用于降低仅用于外设的频率并使系统以最大速度运行。  请看一下 SPIBRR 寄存器。

    此致、

    Kris

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

    很抱歉、我写了错误的时钟。  

    我更改了 LOSPCP 寄存器中的低速外设时钟(LSPCLK)。

    这些位配置相对于 CPU1和 CPU2的 SYSCLK 的低速外设时钟(LSPCLK)速率。

    000、LSPCLK =/ 1
    001、LSPCLK =/ 2
    010、LSPCLK =/ 4 (复位时的默认值)
    011、LSPCLK =/ 6
    100、LSPCLK =/ 8
    101、LSPCLK =/ 10
    110、LSPCLK =/ 12
    111、LSPCLK =/ 14
    注:
    [1]该时钟用作 SCI 和 SPI 模块的选通。

    默认值为200/4 = 50MHz、我将其从4更改为2、因此200/2 = 100MHz。

    SPI 波特率控制
    这些位决定了位传输速率

    对于 SPIBRR = 3至127:SPI 波特率= LSPCLK /(SPIBRR + 1)
    如果 SPIBRR = 0、1或2、则 SPI 波特率= LSPCLK / 4

    设置 SPI 波特率的最快速度是 LSPCLK /4。  默认 LSPCLK 为50/4 = 12.5MHz、当 LSPCLK 为100MHz 时、波特率为25MHz (40ns)

      

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

    感谢您的澄清。 听起来更好。

    如何调用 read_spi()? 如果我正确理解了这个问题,您会发现 Read_SPI()每次迭代之间的变化问题(不一定是导致时序变化的函数本身),这是正确的吗?

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

    Kris、

    我有一个控制环路、使用配置为 SPI 的 McBSP-A 写入 SPI 输出值、然后读取 SPI 端口并将时间戳和数据值写入文件

    //数据循环
    for (y=0;y 
    

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

    John、

    感谢您提供详细信息。 为了实现精确的计时、我认为这是您的最佳选择:

    -使用 CPU 定时器触发 DMA 通道

    -让 DMA 复制 SPI TX 寄存器中的两段数据。 在您的情况下、这些值听起来可以是任意值、但您可以始终将一些未使用的 RAM 位置专用于原因。

    我选择这种方法而不是 ISR 的原因是、有许多因素会导致 ISR 时序发生变化。 这种方法应确保在精确的时序下采集样本。  如果您正确计时、您可能会对它进行计时、以便在到达读取函数时数据准备就绪、并且您不必终止任何周期。

    您可以使用另一个 DMA 通道将 RX 数据复制到特定的存储器位置来进一步推进此操作。 在代码中、您可以始终读取这些位置以获取最新数据。

    此致、

    Kris