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.

[参考译文] CCS/TMS320F2.8377万D:稳定的SPI,不考虑固定的CPU中断

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/577273/ccs-tms320f28377d-stable-spi-regardless-fixed-cpu-interrupts

部件号:TMS320F2.8377万D

工具/软件:Code Composer Studio

尊敬的:

我有两个Delfino微控制器(MC)通过SPI通信进行通信。 一个是主服务器,另一个是从属服务器。 SPI通信被置于每个MC的CPU1上的主环路内。 两个MC还固定了1毫秒ISR_Timer0中断例程。 一个已启动,SPI按预期在主从之间传输32位浮点,但其他一些时间传输不是应有的(浮点不是应有的)。 我想从/主控制器中的固定中断有时会在MC之间交换'制动'连续SPI浮点数。

您能否告诉我您如何在不考虑固定CPU中断的情况下获得稳定的SPI传输?

谢谢!

Tihomir Zilic

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

    很遗憾听到您在使用SPI时遇到问题。 您能否更清楚地描述您遇到的问题? 数据是仅以一个方向发送还是全双工发送? 哪一端似乎有问题? 您是否使用示波器检查数据是否传输正确?
    对于SPI模块,一旦将数据写入SPI数据缓冲区,SPI模块将在没有CPU干扰的情况下处理传输,因此计时器中断应导致活动传输出现问题。 但是,如果SPI模块在主循环中,是否可能从未调用传输下一个数据的代码? 如果您不断中断CPU并将所有时间都花在ISR上,则可能永远无法到达主环路。

    您可以尝试以下几种方法。 首先,以简化的状态尝试代码。 卸下计时器ISR,并确保SPI能够在没有任何其它系统干扰的情况下正常通信。 您是否正在使用SPISTE信号? 这有助于保持模块同步。

    如果您可以分享到目前为止您为调试此问题所做的更多工作,这将有助于我更有效地为您提供支持。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    标记,
    感谢您的支持。

    数据是双向发送的。 主服务器和从属服务器有时接收错误的数据,但有时会接收到错误的数据。 我没有使用示波器进行额外检查。
    但是,正如您所提到的:“如果您不断中断CPU并将所有时间都花在ISR上,那么您可能永远无法到达主环路”,这意味着这样将SPI与ISR计时器一起放在主环路上是不好的,您同意吗? 我需要一种稳定的SPI,在这种情况下永远不会出现。 此外,我需要为某些电机控制任务提供固定间隔ISR计时器0,读取传感器...
    以下代码是主从之间的SPI,发送32位浮点作为16位的两个部分(因为SPI缓冲区是16位):

    从属:

       对于(;;)
       {

       // SPI BEGIN,通过具有16位移位寄存器的SPI传输数据32位浮点
              联合mytypeSend data_sent;
              联合mytypeReceivive data_reci;

              data_send.fl=s;//发送浮点数-编码器读数

              //传输数据的前16位为32位浮点数
              SPI_xmit (data_send.ui[0]);
              //等待直到收到数据
              while (SpiaRegs.SPIFFRX.bit.RXFFST !=1){}// 1字=16位
              //对照已发送的数据进行检查
              rdata1 = SpiaRegs.SPIRXBUF;
              data_reci.ui[0]=rdata1;

              //第二个传输数据,16位,32位浮点数
              SPI_xmit (data_send.ui[1]);
              //等待直到收到数据
              while (SpiaRegs.SPIFFRX.bit.RXFFST !=1){}// 1字=16位
              //对照已发送的数据进行检查
              rdata2 = SpiaRegs.SPIRXBUF;
              data_reci.ui[1]=rdata2;
              am=data_reci.fl;//32位浮点,包含两个16位部分
              SpiaRegs.SPIFFTX.Bit.TXFFINTCLR=1; //清除中断标志
              SpiaRegs.SPIFFRX.Bit.RXFFOVFCLR=1; //清除溢出标志
              SpiaRegs.SPIFFRX.Bit.RXFFINTCLR=1; //清除中断标志

       // SPI结束

       }

    主:

    对于(;;)
       {
       // SPI BEGIN,通过具有16位移位寄存器的SPI传输数据32位浮点
              联合mytypeSend data_sent;
              联合mytypeReceivive data_reci;

              DATA_SENT_Fl=BM+BM; 1111.12345 //浮动增加

              //传输数据的前16位为32位浮点数
              SPI_xmit (data_send.ui[0]);
              //等待直到收到数据
              while (SpiaRegs.SPIFFRX.bit.RXFFST !=1){}// 1字=16位
              //对照已发送的数据进行检查
              rdata1 = SpiaRegs.SPIRXBUF;
              data_reci.ui[0]=rdata1;

              //第二个传输数据,16位,32位浮点数
              SPI_xmit (data_send.ui[1]);
              //等待直到收到数据
              while (SpiaRegs.SPIFFRX.bit.RXFFST !=1){}// 1字=16位
              //对照已发送的数据进行检查
              rdata2 = SpiaRegs.SPIRXBUF;

              data_reci.ui[1]=rdata2;
              am=data_reci.fl;//32位浮点,包含两个16位部分
              0.001 ;

              SpiaRegs.SPIFFTX.Bit.TXFFINTCLR=1; //清除中断标志
              SpiaRegs.SPIFFRX.Bit.RXFFOVFCLR=1; //清除溢出标志
              SpiaRegs.SPIFFRX.Bit.RXFFINTCLR=1; //清除中断标志

       // SPI结束
       }

    是否有其他方法可以将稳定的SPI与CPU固定ISR Timer0一起使用?
    将SPI置于ISR timer0中断内部的主控制器和从控制器上,而不是主环路中,这是否是一个好主意?

    再次感谢,
    Tihomir

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

    Tihomir,

    您是否能够解决您的问题?

    Tihomir Zilic 说:
    这意味着主环路中的SPI与ISR计时器一起使用不是很好,您同意吗?[/QUOT]

    我部分同意你的发言。 这真的取决于控制循环的结构,以及您是否可以将其加入主循环。 您需要设计您的系统,以便您可以捕获测量值,计算任务,然后在控制循环的每个周期中以可预测的方式对其执行操作。 如果您的控制循环任务没有留出足够的时间来管理您的内务管理任务(通信,数据记录等),您需要在某处优化您的系统。 通过降低循环时间或优化控制循环时间。  

    您似乎是以非常手动,动手的方式使用SPI,这需要大量的CPU交互。 如果启用FIFO,则可以将两个16位字写入SPI,并等待SPI收到这两个字后再与数据交互。 这将释放CPU以执行其他操作。这可能会缩短SPI循环的时间。  

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

    我还没有解决。
    现在,我尝试使用CPU2仅用于SPI通信解决此问题。 CPU2上的主环路中的SPI,不带ISR计时器。 CPU1和CPU2将使用共享内存进行通信... 我希望它能以这种方式工作...

    感谢您的帮助,

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

    这实际上是一个合理的方法。 您可以在其中一个内核上执行主控制环路,另一个内核则用于管理通信。 您可以将数据放入共享内存中,然后使用IPC中断通知其它CPU。

    如果您有任何其他问题,请随时发帖!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的Mark:
    感谢您的回复。
    我已经制作了IPC,但尚未完成我的预期。 我想在CPU之间发送float32阵列。 我用消息RAM成功解决了问题(但只发送一个Float32位)。 我想使用共享RAM来完成此操作,但我不知道是否可以发送float 32,或者我需要像使用消息RAM一样将其转换为UINT32。 注:当我使用CPU1和CLA时,我可以直接使用float32数字。 您是否有使用共享RAM在CPU之间发送float32的示例?
    谢谢,Tihomir Zilic
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Tihomir,

    很抱歉耽误你的时间。 您是否能够解决您的问题? 简单的答案是共享RAM只是一个很大的哑内存。 您可以按照您认为合适的方式使用它。 如果CPU1在RAM空间中存储了一个值,并且它是float32格式,则应该对CPU2进行编程,以知道它在读取共享RAM时将拾取float32。 没有任何硬件强制实施任何结构。 换言之,如果CPU1在您的共享RAM中对float32值进行编程,CPU2可以将其读取为两个Int16值,这可能不起作用。  实际上,CPU2将解释RAM中的数据,但您告诉它解释数据。 关键是您的程序应该知道从何处提取数据以及如何解释数据,即使是在单个核心,简单的系统中也是如此。

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

    我解决了这个问题,但是花了太多时间...
    一个月前,我期待着TI专家的帮助。
    很抱歉接受了...

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

    很高兴听到您解决了您的问题。 如果您有任何其他问题,请在将来创建一个新帖子。