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.

[参考译文] MSP430FR2311:SPI 多字节中断

Guru**** 2810805 points

Other Parts Discussed in Thread: MSP430FR2311

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/719967/msp430fr2311-spi-multi-byte-interrupt

器件型号:MSP430FR2311

您好!

我有一个 SPI 主器件、它通过 SPI 向从器件 MSP430FR2311发送数据。  我能够毫无问题地获得单字节中的数据、但我无法获得多个字节。  我已使用单独的器件验证主器件正在发送正确的数据。  当前我使用 CS 引脚中断、打开 RX 中断、然后在 RX 中断中获取数据。  有一个示例代码用于占用多个字节、但所有这些示例代码都在字节之间休眠、我必须在接收数据时保持正常运行。  我在 RX 中断中尝试了几种方式来接收数据、但我始终会获取垃圾数据或重复数据。  

以下是我尝试过的几个代码示例、供参考:

示例1:

#pragma vector=USCI_A0_Vector
_interrupt void USCI_A0_ISR (void)

   RXBUF[CMD_index]= UCA0RXBUF;
   CMD_index++;
   if (cmd_index >= RXBuf[0])   //检查所有字节 RX
   {
       CMD_INDEX = 0;
       P1IE |= BIT3;         // 启用 CS 线路
       UCA0IE = 0;            //禁用 USCI_A0 RX 中断
       //_bis_SR_register_ON_EXIT (LPM3_BITS | GIE);
   }
} //结束 USCI_A0_Vector

示例2:

#pragma vector=USCI_A0_Vector
_interrupt void USCI_A0_ISR (void)

   RX_COUNT = 0;

   开关(RX_COUNT)
   {
           情况0:                    // RX 字节1:数据包长度
               lengthSPI = UCA0RXBUF;
               RX_COUNT += 1;
               中断;

           情况1:                    // RX 字节2:校验和
               校验和= UCA0RXBUF;
               RX_COUNT += 1;
               中断;

           情况2:                    // RX 字节3:RTCMOD 低字节
               命令= UCA0RXBUF;
               RX_COUNT +=1;
               中断;

           案例3:
               增量 High = UCA0RXBUF;
               RX_COUNT +=1;
               中断;

           案例4:
               增量低= UCA0RXBUF;
               RX_COUNT +=1;
               中断;

           情况5:
               RTCMODHigh = UCA0RXBUF;
               RX_COUNT +=1;
               中断;

           案例6:
               RTCMODLOW = UCA0RXBUF;
               RX_COUNT +=1;
               中断;
           }
   if (RX_COUNT >= lengthSPI)   //检查所有字节 RX
   {
       RX_COUNT = 0;
       P1IE |= BIT3;         // 启用 CS 线路
       UCA0IE = 0;            //禁用 USCI_A0 RX 中断
       //_bis_SR_register_ON_EXIT (LPM3_BITS | GIE);
   }

} //结束 USCI_A0_Vector

感谢您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    溢出(软件) SPI 从器件相当容易、因为它无法控制字节的到达速度。

    SPI 没有反馈/流量控制机制、因此您必须针对(从器件)最坏情况进行设计、但并不总是很容易估算处理每个字节所需的时间。

    最明显的补救办法是:
    1) 1)降低主器件的速度;最简单的方法通常是降低其 SPI 时钟的速度。 这些示例使用非常慢的主时钟(ACLK/2)。
    和/或
    2) 2)加速从机时钟(MCLK)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    未经请求:如果您可以释放 STE 引脚、我建议您为从器件使用4线模式、而不是自行管理/CS。 这将使您能够提供这些额外的 CPU 时钟(来自引脚 ISR)来处理数据。 如果您多次跌落、它还会为您提供一些"绝缘"。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    为了确保没有错误或奇怪的行为、我对寄存器进行了大量的讨论并盯着它们、我已经将问题缩小了一个位。  我将时钟速率降低到本地时钟的一半、但仍然会得到奇怪的结果。  但真正奇怪的是、switch 语句从不会遇到第一种情况、但它总是用我发送的最后一个字节填充。  由于此版本的所有示例代码都将进入睡眠模式、而我不会进入睡眠模式、因此我是否需要执行其他操作才能使中断通过传入的数据进行迭代?  似乎只是通过整个数据包将每个字节放入第一个案例中。

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    其"本地时钟"的一半? 如果 SPI 在从器件 MCLK 的一半处运行、那么它只提供16 (CPU)个时钟来处理一个字节、这只足以进入 ISR、更不用说在那里执行任何操作了。

    只有看到最后一个字节、才表明主器件会在从器件进入 ISR 所需的时间内发送其所有字节。 您的主设备在哪个处理器上运行?

    我建议您从降低 SPI 时钟速度开始。 正如我提到过的、这些示例以~16kHz 的频率运行其 SPI 时钟、因此这可能是一个很好的起点。 然后、您可以向上踩下时钟、查看开始出现故障的位置。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我正在以16kHz 的频率运行主器件 BeagleBone Black、这是 MSP430FR2311时钟速度的一半。  

    谢谢!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    即使从机运行速度非常慢、上面的"一半"观察结果仍然保持不变、因为它基于 MCLK 周期。

    如果您确实需要以32kHz 的频率运行从站、那么"向下计数"可能更像是1kHz。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    谢谢、我将尝试一下。 我之前曾尝试使用1kHz、但一直锁定 BBB。 在进一步研究后、我发现其最小值为5kHz、因此我将进行拍摄。 如果这证明仍然不起作用、我想我将不得不考虑在代码中按应用动态设置时钟速度。 也许可以使用一个可耐受复位的标志来改变初始化或者其他东西。

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

    [引用 user="evan Griffith"]您好、
    但真正奇怪的是、switch 语句从不会遇到第一种情况、但它总是用我发送的最后一个字节填充。

    [/报价]

    第二个示例在 ISR 开始时、即在它检查值之前、将 RX 计数设置为零。  因此该值始终为零。  因此、您应该始终按照编写代码的方式遇到 switch 语句的第一个情况。

    Walter

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

    这是正确的答案。  它在驱动我的坚果。  我没有意识到这个中断正在重新中断每字节、这将重置计数器。  我很确定我知道它在做什么、但我没有仔细阅读状态机。  感谢您的查找!