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:TMS320F28035 SPI 数据损坏(似乎正在计时17位)

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/749509/tms320f28035-tms320f28035-spi-data-corruption-appears-to-be-clocking-17-bits

器件型号:TMS320F28035
Thread 中讨论的其他器件:controlSUITEC2000WARE

您好!

我正在体验在 SPI 总线上似乎是"17"位的传输。

我有8个 UCS 连接在一起、它们使用菊花链中的 SPI 总线(SPI-b)进行通信。 UC1与 uC2谈判,uC2与 uC3谈判...... UC8返回 UC1。

UC1是主器件。

数据长度为16位(SpibRegs.SPICCR.bit.SPICHAR = 0x1F;)

SPI 时钟速度非常慢、示波器迹线显示出出色的 SPI 时钟任一侧的设置和保持。

问题:

当我简单地通过主虚拟字路由时、它会通过完美的精细纹波、并且每个 uC (以及主器件)接收的内容是正确的。

但是、当我尝试在流中"注入"数据(即我"覆盖 uC 中的内容)时、返回到主设备(UC1)的数据会损坏。

花了一段时间、但我最终意识到数据正在向左移动1位-这表明 UC 正在计时17位!

例如、我注入8345 (1000-0011-0100-0101)、然后返回068B (0000-0110-1000-1011)-左移1位。 我使用了许多不同的数据模式、结果是相同的。

我已经阅读了 SPI 手册封面到封面上的十几次、我尝试了不同的速度(我认为这不可能是因为"虚拟"数据在所有速度下都能完美运行)。

我已经检查以确保没有杂散边沿(时钟"恢复状态"为低电平)

我已检查"勘误表"数据、但与 SPI 无关。

请任何人帮忙-我被骗了

我包括一些与 SPI 设置相关的代码部分

SPI_SET_UP

{

EALLOW;

//将所选引脚的限定条件设置为仅异步*/

//这将为所选引脚选择异步(无限定条件)。

GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3;//异步输入 GPIO12 (SPISIMOB)

GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3;//异步输入 GPIO13 (SPISOMIB) GpioCtrlRegs.GPAQSEL1.bit.GPIO14



= 3;//异步输入 GPIO14 = GPIO14.KB = GPIO3KB;GPIOL.GPIO3/ GPIO1.GPIO1.GPIO1.GPIO3KB = GPIO1.GPIO1.GPIO3KB //异步输入 GPIO14 (!SPISTEB)

//使用 GPIO 寄存器配置 SPI-B 引脚*//

这指定哪些可能的 GPIO 引脚将是 SPI 功能引脚。

GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 3;//将 GPIO12配置为 SPISIMOB

GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 3;//将 GPIO13配置为 SPISOMIB

GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 3;/ GPICl14

= 3;GPICOL = 3;GPICOL = 3;GPICOL = GPO14 = GPICOL = 3;GPICOL = 3 //将 GPIO115配置为 SPISTEB

//为所选引脚启用内部上拉

//用户可以启用或禁用上拉。

//这将启用指定引脚的上拉电阻。

GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0;//启用 GPIO12上的上拉(SPISIMOB)

GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0;//启用 GPIO13上的上拉(SPISOMIB) GpioCtrlRegs.GPAPUD.bit.GPIO13上拉







;//启用 GPIO14上拉(SPIC.SPIC.0KB)/SPICOL = 0KB;GPIO14位/SPIC.GPIO14 = 0KB;GPIO14 = SPIC.SPICR.GPIO14;SPIC.GPIO14 =所有引脚 环回关闭

SpibRegs.SPIBRR = 0x19;//SPI 时钟速度-慢

SpibRegs.SPICTL.ALL = 0x02;//CLK_PHASE = 0、启用数据传输、禁用 SPI 中断(轮询)、// 0 =从器件;

SpibRegs.SPICCR.ALL = 0x8F;//清除 SPI 复位

}

我的代码转至 tranmsit (Master)

void read_spi_Data (void)

{

receive_Count = 0;

dmummy = 0x0F0F;

SpibRegs.SPITXBUF = dmummy;//加载带有第一个字节的 Tx 缓冲区- dmummy -在

(SpibRegs.SPISTS.bit.INT_flag!= 1)//未在缓冲区中接收到字符时启动时钟

;SpibRegs.SpibRegs.spirt.pummy =

//清除标志(读取 Rx 缓冲器)

SpibRegs.SPITXBUF = Command_Message;//使用下一个字加载 TxBuffer (即命令字

)// Command_Message 启用/禁用 O/PS 并设置覆盖等

,而(SpibRegs.SPISTS.bit.INT_flag!=1)//没有收到字符时

,SpibRegs.SpibUrl 缓冲区中的字符

= SpibUrummy 缓冲区 //清除标志(读取 Rx 缓冲器)

虚拟= 0x6789;//

while (Receive_Count < 35) //receive_Count 是预期字数=

{

SpibRegs.SPITXBUF =虚拟; //使用下一个字加载 TxBuffer

//后续行检查是否设置 Rx 标志-表示 SPI 总线已接收到一个字

,同时(SpibRegs.SPISTS.bit.INT_flag !=1)//在缓冲区中没有接收到字符-轮询标志

{}

test = SpibRegs.SPIRXBUF; //清除标志(读取 Rx 缓冲区)

SPI_RxArray[Receive_Count]= test;//将接收到的数据放入 RxArray

Receive_Count++中;//递增到下一个接收到的字

}

Receive_Count = 0;//读取完成

后重置计数器 test = 0;

}

从机读取

void transmit _SPI_Data (void)

{

receive_Count = 0;

//后续注释应用于'first' uC。

//后续 UC 也会收到类似的信息,但有差距!

//第一个接收到的字是虚拟字,用于启动传输

//第二个接收到的字是命令字-当调用此函数

时收到该字(Receive_Count < 37)//Receive_Count 是预期字的数量

{

local_buffer = SpibRegs.SPIRXBUF

local_buffer = 0x8345; // 'this'="" device="" -="" route="" it="" through="" receive_count++;="" while="" (spibregs.spists.bit.int_flag="" !="1)" received="" character="" in="" buffer="" poll="" flag="" {="" }="" function="" resets="" timer="" reset="" everything!="" receive_count="0;" counter="" transmit_count="0;" transmit="" count="" 

 

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

    您好!

    已将这一问题通知有关专家。

    请注意、这是美国的感恩节周、大多数 TI 工程师都不在。

    请预计下周初收到延迟的回复。

     

    此致、

    Sudhakar

    ------------------------------------------------------

    如果帖子回答了您的问题、请使用 "验证答案" 按钮进行标记。

    其他有用链接:

    C2000入门     C2000闪存常见问题/常见问题      仿真常见问题解答

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

    我不是很清楚你为什么会看到这种行为。 如果您有 SPI 线路的示波器迹线、您能否发送我们来更好地了解。 我想查看 SPICLK、SOMI、SIMO 和 STE (如果使用)引脚

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

      您好、Veena、

    我已附上您请求的图片

    为清楚起见、我没有在从器件上使用!SPISTEB 信号、并且我将它们一直绑定到低电平(我认为这不会导致我看到的效果、因为这不会影响 SPICLK 位计数)、并且直接路由时的虚拟数据也不受影响。 只有当我覆盖时、它才会出现问题。

    硬件设计包含8个 uC "菊花链"、其中 uC 1作为主设备。 数据流由两个"控制"字(每个16字节长)组成、后跟虚拟数据、这些虚拟数据使用以下7 uC (uC2 - uC 8)中的真实数据进行覆盖。

    为了实现波形的目的、进入 uC2的所有数据都使用8345进行覆盖。 但是、产生的结果是左舍入的-068B- (建议17位计数)

    在图1中、我尝试显示设置并保持 SPICLK 的任一侧、并显示通过 UC2路由的前16位。

    通道1是时钟(16个"边沿")

    通道2是从 uC 2传输的数据。 该数据应为8345,但会左移1位,因此为068B。

    通道3是 uC2的输入、是"虚拟"数据后的两个控制字(6789 -尽管我尝试了不同的数据模式)

    在图2中、我显示的是相同的东西、但时间更长。

    感谢您(或其他团队成员)在这方面的帮助。

    此致

    j

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

    我将与我的同事讨论这个问题、并与您联系。
    同时、您是否能够在 local_buffer 中看到0x8345? 我希望在写入 TXBUF 之前它没有被移出

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

    您好、Veena、

    不确定如果已经移出了什么内容、如何查看本地缓冲器?

    您能告诉我如何看待它吗?

    j

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

    我的意思是在调试环境中。 您可以在发生写入 TXBUF 的行放置一个断点、并查看 local_buffer 变量的内容

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

    好的、当我进入办公室时、我会让它进入。

    有关信息、我检查了是否有任何可能导致左移的"计算"执行方式(即 x2)。 没有计算。 数据只是从 UC1转移到 uC2、在这里被覆盖。

    j
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好、Veena
    我已经尝试使用调试器来监视 SPITXBUF、SPIRXBUF 和 SPIDAT。
    SPIRXBUF 中包含正确的数据。
    SPITXBUF 中包含正确的数据、
    SPIDAT 中有不正确的数据、即数据被向左移位。

    我承认我并不完全熟悉调试器的子项、因此我可能无法正确使用它。

    但是、在我允许调试器运行多行代码(在读取 SPIRXBUF 循环中)后、数据会自行校正、SPIDAT 寄存器中的数据会变为正确。 然后、如果我断开调试器(红色按钮)、就像对器件进行编程时一样、来自 uC 的数据是正确的(在示波器上读取)。

    我已‘此过程,如果我对 UC 进行编程,请使用“运行到线路”选项执行 SPITXBUF 读取,然后断开调试器连接,数据是正确的。 这是‘一致的,表明 SPI 的“位计数器”(对于 SPI 字符的16位,该计数器为16)现在是正确的。 但是,为什么调试器纠正了这一点我不知道。

    我怀疑 SPI 设置中存在异常。 在允许数据通过之前、SPI 设置中是否有任何需要完成特定数量时钟周期的时间相关设置?

    有什么建议吗?

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

    John、

    几个问题:

    1. F28035器件链上是否有所有 MCU?
    2. 如果所有 MCU 都是同一器件、它们是否都运行相同的软件?
    3. 虽然您捕获的波形看起来很好、但是否有寄生噪声脉冲从 MCU2进入时钟线?
    4. 是否有任何其他可能导致损坏的系统事件? 即相关 MCU 上运行的其他代码?
    5. 通常、我不建议将芯片选择(STE)绑定到0。 我经常看到、如果系统中的任何东西导致伪时钟脉冲、或者传输中的奇数时序问题、那么从器件将失去与主器件的同步。 芯片选择实际上是防止这些类型问题的唯一方法。
    6. 检查 SPIPRI 寄存器中的软和空闲位。 默认情况下、这些设置为0、这意味着任何调试暂停实际上都会停止 SPI。 如果您在代码中有任何断点或正在调试 MCU 2、您可能会以不希望的方式与 SPI 中的位计数器发生混乱。 我建议将其设置为自由运行模式、以允许 SPI 始终运行。
    7. 通常、对于8个 MCU、您如何调试它? 您是否仅连接到该从器件? 是否已连接到所有设备? 我只是想了解你是如何接近这一目标的。
    8. 您能否暂时将从器件的数量减少到仅一个主器件和从器件?  您的传输方案似乎可以处理较少的从器件、而无需过多的工作。 我发现减少变量是一种找到问题根源的好方法。 开始切割、直到问题消失、然后查看重新引入问题的步骤。
    9. 您似乎没有使用 FIFO、因此这应该稍微简化一些操作。 我确实发现、在没有任何关于该词应该是什么或它出错的地方的注释的情况下、很难解读您的示波器捕获...

    很抱歉、我真的不认为有任何位移发生、这可能是您构建软件的方式。 如果您从未在时钟线上看到时钟位、我看不到这种情况会发生。 如果我遗漏了您之前提到的任何内容、请原谅我。

    侧注-请避免将代码粘贴到文本正文中富文本编辑器中有一个带有 此图标的代码格式器工具: 。 默认情况下、您可以折叠代码。 由于代码格式正确、它使线程更易于跟踪和读取。 我继续编辑了您的原始帖子、以显示其外观。

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

    当然、在我键入所有这些内容之后、我更难查看您的从器件发送代码、并发现可能是问题的东西。 进入 while 循环后、您将立即读取 SPIRXBUF。 该循环中的第一个可能是对 INT_FLAG 的轮询。 尤其是在没有芯片选择引脚提供的 SPI 传输门和 SPI 状态机复位的情况下、您可能会被单个位关闭、并且无法恢复。

    此外、我不确定为什么您在 INT_Flag 上使用外部 while 环路来使用主控方 READ_SPI_Data 函数。 该函数的整个结构看起来有点偏。 考虑将第11行操作为:while (int_flag!= 1){}//其余代码。

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

    Mark、您好!

    感谢您回来。

    答案如下:

    1是的、全部为28035

    2主器件运行 S/W_Master、7个从器件运行 S/W_Slave。

    3我回到了信号质量的第一原则。 时钟非常干净(我在发送端包含了一个22R 电阻器以提高信号完整性)、数据也非常干净、示波器显示设置和保持时间非常出色。

    4 S/W 或 H/W 中没有发生其他事件 该设计只需使用从器件的 A/D 启动一系列电压、并通过 SPI 总线将结果传输到主器件。 我正在为每个从器件使用隔离式 SPI 收发器(测量的传播延迟小于5ns、信号质量出色)。 没有可能产生噪声的大电流开关。 在测试中、我目前尚未连接任何要测量的电压、并且正在"模拟"A/D 读数以使 SPI 正常工作。

    5此设计包括重复的"同步"过程、可满足此类需求。

    6个会的

    7我目前正在查看第一个从器件的输出。 这将从主控方接收虚拟和控制字(每个字16 btis)。 在完成的应用程序中,虚拟字和控制字被传送到第二个从器件(然后是第三个....) 以下虚拟数据与 A/D 结果一起被改写。 为了进行测试、我将"尝试"以使用"已饱和"A/D 数据覆盖所有数据。 所发生的情况是、第一个从器件(和其余从器件)输出的仿真数据按照所述的方式(向左移位1位)被损坏。 由于所有从器件代码都是相同的(读取硬件的简单3位代码可使从器件软件确定其在序列中的位置并预加载一系列数据计数器)、因此事实证明这非常简单。

    8我可以减少从器件的数量、但这需要削减和连接-我宁愿避免这样做。 由于我能够监控第一个从器件的输出、因此我有效地对链进行了编辑。 此外、正如我之前的亚发射中提到的、如果我允许虚拟和控制字不受阻碍地通过、数据就不会损坏(这是一个奇怪的位、因为它表明我已经正确设置了所有内容)。

    9我读过 FIFO 使用情况、但看不出有什么理由使用它、因为设计简单且"低"。 我会更好地为任何未来的示波器跟踪做注释、遗憾的是、示波器不是我通常使用的示波器、我仍在学习如何驱动它!

    我正在查看您有关 while 循环的后续电子邮件。 将于今天上午晚些时候提供建议

    感谢您迄今提供的支持

    j

    回复:代码提交-我将使用 对于将来提交的代码、我的 BAD!

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

    您好、Mark。

    嗯、我有一种解决方案。

    SPI 总线出现为17位时钟(左移1位)的问题似乎是围绕着 I 对进入 SPI 输入的数据进行写操作、还是直接传输进入的数据。

    如果我执行以下操作:

    虚拟= SpibRegs.SPIRXBUF;

    虚拟= 0xAFAF;                           //覆盖出现的内容

    SpibRegs.SPITXBUF =虚拟;

    数据损坏、SPI 输出结果为0x5F5F (左移1位)

    执行以下操作

    虚拟= SpibRegs.SPIRXBUF;

    SpibRegs.SPITXBUF =虚拟;

    数据从 SPI 输出中输出、不会损坏。

    显然、我希望有选择性地覆盖传入的数据、以便 在写入数据后立即引入短延迟。

    虚拟= SpibRegs.SPIRXBUF;

    虚拟= 0xAFAF;                           //覆盖出现的内容

    延迟                                                  //延迟几个时钟周期

    SpibRegs.SPITXBUF =虚拟;

    新数据从 SPI 输出中输出、但不会损坏。

    当写入发送给 SPI Txbuffer 的新数据时、似乎需要几个时钟周期。 这很奇怪–TI SPI 手册中没有任何内容表明需要延迟或要检查的任何其他标志。


    必须使用任意延迟似乎并不正确,必须有一个寄存器或标志来指示新数据已准备好传输.....

     

    您能不能对这种奇怪的情况下做出任何说明?

     

    j

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    INT_FLAG 位是确定是否已准备好读取字的正确位。 请参阅我之前的答复。 您似乎立即输入函数、然后写入新值。 您需要在读取 SPIRXBUF 之前轮询 INT_FLAG、然后覆盖该值。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    void transmit _spi_Data (void)
    {
    Transmit _Count = 0;
    Receive_Count = 0;
    
    while (Receive_Count < 37) //receive_Count 是预期字数(37)
    {
    while (SpibRegs.SPISTS.bit.INT_flag!= 1) //等待 SPI 标志指示新消息已到达-轮询该标志!
    {}
    if ((Receive_Count >(Data_Location - 1))和(Receive_Count <(Data_Location + 4)))//简单地确定从数据的放置位置
    {
    Slave_Dummy = SpibRegs.SPIRXBUF; //简单读取以清除标志
    Slave_Data = SPI_TxArray[Transmit _Count];//从 TxArray 获取数据
    非常短的延迟(); //需要这个短暂的延迟!!!!!!!!!!!!
    SpibRegs.SPITXBUF = Slave_Data;//将数据放置在 TxBuffer 中
    Transmit _Count++;//goto the next TxArray location
    }
    否则、如果(Receive_Count = Geographic _Location) //在流中标识'this'位置的'command'字
    {
    Command_Message = SpibRegs.SPIRXBUF; //存储“命令”字。
    //非常短接延迟();
    SpibRegs.SPITXBUF = Command_Message; //将命令 Word 路由到下一个 UC (7个从设备,1个主设备)
    }
    其他
    {
    Slave_Data = SpibRegs.SPIRXBUF;
    //非常短接延迟();
    SpibRegs.SPITXBUF = Slave_Data; //如果数据不适用于“此”设备,则只需将其路由
    到}即可
    Receive_Count++;
    }
    Receive_Count = 0; //重置计数器
    Transmit _Count = 0; //重置发送计数
    }
    
    
    void SPI_Setup (void) //SPI 端口 B
    {
    SpibRegs.SPICCR.bit.SPISWRESET = 0;//强制 SPI 复位
    SpibRegs.SPICCR.bit.SPICHAR = 15;//
    SpibRegs.SPICCR.bit.CLKPOLARITY = 0;//
    SpibRegs.SPICCR.bit.SPILBK = 0;//强制 SPI 复位,16位,时钟极性,环回关闭
    SpibRegs.SPIBRR = 0x0A;//SPI 时钟速度-慢速0x02
    SpibRegs.SPICTL.ALL = 0x02;//CLK_PHASE = 0、启用数据传输、禁用 SPI 中断(轮询)、// 0 =从器件;(0x0A / 0x02)
    EALLOW;
    //仅将所选引脚的限定条件设置为异步
    //这将为所选引脚选择异步(无限定条件)。
    GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 3;//异步输入 GPIO12 (SPISIMOB)
    GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3;//异步输入 GPIO13 (SPISOMIB)
    GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 3;//异步输入 GPIO14 (SPICLKB)
    GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 3;//异步输入 GPIO14 (!SPISTEB)这在 PCB 上连接低电平。
    //使用 GPIO 寄存器配置 SPI-B 引脚
    //这指定哪些可能的 GPIO 引脚将是 SPI 功能引脚。
    GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 3;//将 GPIO12配置为 SPISIMOB
    GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 3;//将 GPIO13配置为 SPISOMIB
    GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 3;//将 GPIO14配置为 SPICLKB
    GpioCtrlRegs.GPAMUX1.bit.GPIO15=3;//将 GPIO115配置为 SPISTEB 在 PCB 上绑定为低
    电平// GpioCtrlRegs.GPAPUD.bit.GPIO14=1;//禁用 GPIO14上的上拉电阻器(SPICLKB).................................. >>><<<
    EDIS;
    SpibRegs.SPICCR.bit.SPISWRESET = 1; //清除 SPI 复位
    GpioDataRegs.GPASET.bit.GPIO6 = 1; //启用 SPI 缓冲
    器}
    
    void set_up_Clock (void)
    {
    EALLOW;
    // LOSPCP 预分频寄存器设置,通常它将设置为默认值
    GpioCtrlRegs.GPAMUX2.bit.GPIO18=0;//关闭 X法规 判例法
    // SysCtrlRegs.LOSPCP。all = 0x0002; // XCLKOUT 与 SYSCLKOUT 之比。 LSPCLK = SYSCLKOUT/4
    SysCtrlRegs.LOSPCP。all = 0x0004; // XCLKOUT 与 SYSCLKOUT 之比。 LSPCLK = SYSCLKOUT/8
    SysCtrlRegs.XCLK.bit.XCLKOUTDIV = 3; //外设时钟启用针对所选外设的设置。 = XCLKOUT 3 =关闭
    SysCtrlRegs.CLKCTL.bit.XTALSCOFF = 1;// Crystal OSC 关闭(内部时钟)
    SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1;//外部时钟输入关闭(内部时钟)
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;//(内部时钟)
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 0;//内部 OSC1选择的 OSCCLK
    
    //关闭不需要的时钟
    SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC --
    SysCtrlRegs.PCLKCR3.bit.COMP1ENCLK = 0;// COMP1
    SysCtrlRegs.PCLKCR3.bit.COMP2ENCLK = 0;// Comp2
    SysCtrlRegs.PCLKCR3.bit.COMP3ENCLK = 0;// Comp3
    SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 0;// eCAP1
    SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 0;// eCAN-A
    SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 0;// eQEP1
    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 0;// ePWM1
    SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 0;// ePWM2
    SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 0;// ePWM3
    SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 0;// ePWM4
    SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 0;// ePWM5
    SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 0;// ePWM6
    SysCtrlRegs.PCLKCR1.bit.EPWM7ENCLK = 0;// ePWM7
    SysCtrlRegs.PCLKCR0.bit.HRPWMENCLK = 0;// HRPWM
    SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0; // I2C
    SysCtrlRegs.PCLKCR0.bit.LINAENCLK = 0; // LIN-A
    SysCtrlRegs.PCLKCR3.bit.CLA1ENCLK = 0; // CLA1
    SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 0; // SCI-A
    SysCtrlRegs.PCLKCR0.bit.SPIANCLK = 0; // SPI-A
    SysCtrlRegs.PCLKCR0.bit.SPIBENCLK = 1; // SPI-B ---
    SysCtrlRegs.PCLKCR2.bit.HRCAP1ENCLK = 0;
    SysCtrlRegs.PCLKCR2.bit.HRCAP2ENCLK = 0;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC=0; //在 ePWM 内启用 TBCLK
    EDIS;
    }
    
    
    

    Mark、您好!

    SPI 总线的问题仍然存在。

    我同意、轮询 INT_FLAG 是检查 RXBUF 是否已满并准备好读取的正确方法。 我之前提交的代码没有强调我已经执行了这项操作、因此我现在已经包含了代码。

    您将注意到、我包含了一个可防止数据损坏的短延迟例程。 但是、在确定 RXBUF 已满(轮询 INT_FLAG)时、应该不需要、我应该能够简单地将我喜欢的任何值写入 TXBUF。 如果我删除延迟例程、则数据会损坏。

    我认为 UC 或代码结构没有任何问题(其他一切都正常),但我真的很损失。

    我还包括了 SPI 总线程序的设置和时钟的设置–我认为问题可能在于其中的一个。

    如果您能提供任何帮助、我将不胜感激

    j

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这非常有趣。 芯片选择信号实际上是同步/复位 SPI 位计数器而不复位整个模块的唯一方法。

    您能不能尝试在主机传输上引入一些延迟。 (aka -将"jor_short_delay"移动到主器件、并调整延迟需要多长时间、直到问题得到解决或变得更糟。
    您能否一次减慢 SPICLK 的一个值、直到问题消失?
    或者、重新引入仅用于调试的芯片选择。 这是否也有帮助。

    INT_FLAG 表示 SPIDAT 中的数据被移动到 SPIRXBUF 的时刻。 根据主器件上的 SPICLK 分频器、在下一个 SPICLK 发生之前、您应该有足够的 SYSCLK 周期来管理这一点。 您能否在对缓冲区的读取和写入前后添加 GPIO 切换? 显示有延迟和无延迟的捕获。 我想了解缓冲区在"死区时间"中的什么位置被读取和写入。

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

    Mark、您好!

    感谢您的再次光临。

    ‘芯片选择引脚可能是问题,因为只有当我覆盖从器件接收到的“进入”时,才会出现问题。 ‘我不覆盖(我只需将接收到的数据放在 Tx 缓冲区中),则数据不会损坏–因此使能引脚不会影响接收到的数据的“我要做什么”。 此外、当我路由数据时不覆盖数据、它将完全通过所有7 uC。

    我已经减慢了主器件的速度–认为可能存在 SPICLK 速度问题、但这没有影响、并且仍然需要非常短的延迟(延迟例程在从器件中–这与直觉相反)。 我已经尝试了许多较慢的主速度、但它无法解决问题。 此外、损坏的性质表明数据在一个位之前(向左移位)随时钟输出。 这使我认为器件会将我写入 Tx 缓冲器的数据保持在移动状态。 如果我在从器件中花费太长的时间将数据放入 TxBuffer、则它将被右移(例如、一个或多个时钟延迟)。

    ‘芯片选择需要相当多的“剪切和链接”(有7个从器件和1个主器件 UC)。 除非我能清楚地看到这是问题,我认为这不是问题,否则我会这样做。 我对时钟和数据有很好的‘re、并且有清晰和独特的时钟边沿(16个关闭)、并且 Δ I sting‘state 很低、可防止任何杂散边沿。

    添加 GPIO 切换以查看事件发生的位置是个好主意(只是希望执行一些 GPIO 切换不会导致问题消失!)。 将在之前提供。

    我们是否有办法加快有关这一问题的信函往来,因为我面临着一些进展的压力?

     

    j

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

    如果可能、请发送简化的主从代码。 我知道您在整个线程中都有副本和粘贴、但只需附加 c 代码即可。 我将看到我明天可以做什么。

    从机可能无法启动自己的传输并提前开始移动数据。 它只是一个由输入主时钟计时的简单可编程移位寄存器。 我很想了解从器件何时接收到新数据并加载该数据的示波器捕获。 如果在读取之前和写入之后进行切换、则不应影响时序(也不应在写入之后立即切换 IO。
    那么、非常短的延迟到底会有多长时间?

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

    Mark、您好!

    我想我已经解决了!

    简而言之、在主微控制器的配置过程中会产生一个杂散 SPICLK 边沿。 我‘s地认为,如果我进行 SPI 复位(SPICCR.7=0 ),它将清除 SPI 计数器,从而允许我通过执行 SPI 复位随时“同步”所有从器件。

    ‘的情况是,复位不会重置 SPI 位计数(请确认这种情况,因为我找不到任何显示“将”重置位计数的内容),因此数据始终为1位输出(向左移位)。

    为了解决这一问题、我现在介绍了一个简单的同步过程、该过程将信号切换至从器件、并且仅在接收到信号后配置了从器件 SPI。 当主器件被配置且时钟已稳定至休眠状态(低电平)后,会‘切换’。 这可防止一个寄生边沿(从高电平到低电平的转换–这是将数据时钟移入从器件的边沿)。

    我已经阅读了无数次应用手册、但在任何地方都找不到真正复位 SPI 位计数器的内容。 是否需要对 SPI 模块执行完整的重新配置以复位计数器?

     

    j

     

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

    SPISWRESET 将复位内部位计数器。 但是、主器件无法将此复位传播到从器件。 如果他们在主器件配置期间看到单次切换、他们不知道这是虚假的。 (因此 STE 信号非常有用)。 我将在寄存器说明中添加此澄清说明、以便将来进行改进。

    在您的方法上我没有任何问题-在从主器件接收到命令之前、保持从器件处于复位或禁用状态。 同样、如果 SPISTE 被驱动而未被绑定为有效、那么这一切将被避免。

    SPISWRESET 和 SPISTE 将复位位位位计数器。 这些是在此器件上执行此操作的唯一方法。

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

    您能否澄清什么是 SPISWRESET?

    我同意!SPISTE 在允许主器件被配置并保持从器件移位寄存器方面是有用的,但是没有任何地方表明它清除了位计数器。 此外、SPIRESET (SPICCR.7=0)不会复位计数器看起来有点奇怪、我是否可以建议 SPRUG71的表7对此进行更明确的描述。

    j
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    SPISWRESET 为 SPICCR.7。 实际上、我不确定您从我们所有文档中获得"SPIRESET"的位置、我已经将 SPICCR.7显示为 SPISWRESET。 您指的是 SPRUG71的哪个版本? controlSUITE 或 C2000Ware 版本如何? 如果你获取最新的、这一切都是 SPISWRESET。

    同意缺少文件。 我已经提到,我将在必要时补充澄清。

    -Mark