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.

[参考译文] MSP432P401R:SPI 发送中断标志不能#39;t 上升

Guru**** 2553450 points
Other Parts Discussed in Thread: CC1200

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/596169/msp432p401r-spi-transmit-interrupt-flag-doesn-t-go-up

器件型号:MSP432P401R
主题中讨论的其他器件:CC1200

我将在下面提供通过 SPI 发送的代码。
我需要非常快速地向 CC1200芯片发送字节。 因此、我在没有中断的情况下工作、我只观察该标志。 一旦它上升、我就会通过 SPI 发送下一个字节。
首先将 STE 拉低、然后等待 CC1200就绪(等待 SOMI 变为高电平)、然后通过 SPI 发送字节。 最后、我等待发送完成、并将 STE 拉至高电平。

有两个问题:
1.使用 SPI 忙功能似乎不起作用,所以我手动查看忙位。
2.有时 SPI 不想设置发送缓冲区的中断标志。 在某些传输后、该标志会下降、而不会恢复。
此错误很少发生、我找不到发生原因。

#define CC1200 EUSCI_B0_BASE

uint8_tCC1200_Burst 写入(uint8_t* inputBuffer、uint8_t staringAddress、uint8_t length)
{
int32_ti;
uint8_t statusByte;

CC1200_Select_Module ();

//显示 startingAddress、uint8_t length (I);* int32_t I
= CC1200_statusByte;* starbyte


= starting from starting (I);CC1200_transmit (I);* starbyte = CC1200_statusByte statusByte = byte;* 

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

    我将为您研究这个问题。 一些初步问题、以帮助我。 您能告诉我您正在使用的器件的修订版吗? 建议使用版本 C 和更高版本。

    您的 SPI 使用什么时钟源? 在本例中、请确保它是同步的。 这稍微提醒我 USCI43勘误表。 您能否阅读说明并评估您是否也在使用 SPI 时看到过这种情况?
    www.ti.com/.../slaz610
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗯、

    我们使用的是 REV C 和 SMCLK 6MHz。  它是同步的。

    我不知道您能查看多少内容、但这里有一些信息。 我查看了勘误表、但我现在就在家里、所以我明天就会研究它。
    目前、实现这一目的的唯一方法是手动清除中断位。 如果通过这种方式将其清零、则不会将其自身重新置位。 我们从不清除这个位、所以它不能是。
    最糟糕的是我无法重新创建它。 在过去的六个月里、我发生了2-3次这种情况。 现在、我将我的代码交给了我的合作伙伴、他将我的代码与他一起测试、每天会发生几次。
    我们检查了、他甚至没有与 EUSCIB0进行任何交互。
    我们现在可以想到的唯一权变措施是看门狗计时器、因为我们的系统可以通过它快速恢复。


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

    您能否与我分享您的 SPI 初始化代码? 请告诉我、您的调查将带您进入何处。 我还想知道使用中断是否能够真正消除这种异常。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是代码中与 SPI 相关的部分。

    CC1200的/* SPI 主配置参数*/
    静态常量 eUSCI_SPI_MasterConfig spiCC1200Config =
    {
    EUSCI_B_SPI_CLOCKSOURCE_SMCLK、 // SMCLK 时钟源
    6000000、 // SMCLK = HFXT/8 = 6MHz
    6000000、 // SPICLK = 6MHz
    EUSCI_B_SPI_MSB_FIRST、 // MSB 优先
    EUSCI_B_SPI_PHASE_DATA_Captured_ONFIRST_Changed_On_Next、//相位
    EUSCI_B_SPI_CLOCKPOLARITY_INACT_LOW、 //极性低
    EUSCI_B_SPI_3引脚 // 3线 SPI 模式
    };
    
    void CC1200_Init()
    {
    /*初始化所有与 SPI 相关的 GPIO 并启动 SPI 模块*/
    MAP_GPIO_setAsOutputPin (CC1200_SPI_PORT、CC1200_SPI_STE);
    
    MAP_GPIO_setOutputHighOnPin (CC1200_SPI_PORT、CC1200_SPI_STE);
    
    MAP_GPIO_setPeripheralModuleFunctionInputPin (CC1200_SPI_PORT、
    CC1200_SPI_CLK | CC1200_SPI_MOSI | CC1200_SPI_MISO、GPIO_PRIMARY_MODULE_FUNCTION);
    
    /*为 CC1200在3线主控模式下配置 SPI */
    SPI_initMaster (CC1200_SPI、&spiCC1200Config);
    SPI_enableModule (CC1200_SPI);
    EUSCI_B_SPI_DisableInterrupt (CC1200_SPI、CC1200_SPI_Transmit 中断);
    EUSCI_B_SPI_DisableInterrupt (CC1200_SPI、CC1200_SPI_Receive_interrupt);
    }
    

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

    您的调查进展如何?

    此外、在您的注释中、您会注意到 SMCLK = HFXT/8。 HFXT 是 SMCLK 的来源吗? 如果是、您能否尝试为实验寻找 DCO、并查看您看到的异常是否已复制?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Evan、

    嗯、我没有发布任何帖子的原因是问题没有发生。

    您的建议有一些问题。 我不能使用中断、因为它们会使我的速度降低一点、我必须重新设计我的当前系统。 我只提供了我们拥有的整个代码的一小部分。

    就 DCO 的建议而言,我会很慢我的速度。 我以1MHz 的频率发送数据、我的 SPI 需要尽可能快。 因此、使用 HFXT/6是6MHz。 我可以将其降低、但不能降低到32KHz。
    如果出现问题、我将报告、并尝试重新创建。

    您是否进行过任何调查?

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

    如果您要使用 EUSCIBx 中断、您的 NVIC 优先级设置为什么? 是否还有其他优先级高于它的中断可能会阻止它执行、从而导致您减慢速度?

    同时、我将开始尝试重新创建此问题"是"。 您能告诉我您的 MCLK 设置是什么吗?

    您是否有一个您可以共享的已拆分版本的程序、您可以看到您所说的异常? 这将极大地帮助/加速调试。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jasaleja、

    您能否解释一下为什么将其设置为 DCO 会将您的速度减至32KHz? 使用 DCO 作为源在其上面运行应该不会有任何问题。 请帮助我了解我是否遗漏了什么。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jasaleja、

    为了确保我们尽可能控制这种情况并找出根本问题、您是否还可以对所有函数使用 MAP_函数。 虽然大多数 DriverLib API 都在 ROM 中提供、但由于架构限制、ROM 中未包含某些 API。 此外、如果在对器件 ROM 进行编程后将任何错误修复添加到 API 中、则最好使用 API 的闪存版本。 已创建了一个"情报"来解决这个问题。 如果用户包含 rom_map.h
    头文件并使用 API 前面的 MAP_前缀、头文件将自动使用预处理器宏来决定是使用 ROM 还是闪存版本的 API。

    这将有助于确保我们不会遇到任何已经解决的错误。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Evan、

    我弄错了。 出于某种原因、我认为 DCO 像 LFXT 那样被限制在32KHz、但这是错误的。 我将尝试使用此来源、但问题今天也没有出现。

    此外、如您所见、在上面的代码中、我使用除 SPI 函数之外的所有 MAP_函数。 在几个月前的一个主题中、由于某种原因、我被告知不将 MAP_与 SPI 函数一起使用。 我了解 MAP_智能的工作原理(我看到了他的代码)。 即使在示例中、它们也不会将 MAP_与 SPI 一起使用、而是将其与其他内容一起使用。

    我将尝试选择 DCO 作为源、我知道我们需要解决这个问题、但我目前无法执行任何操作、因为它根本没有发生。

    一旦我获得任何新信息、我将在这里通知您、但直到那时、我才做任何事情。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jasaleja、

    听起来不错。 同时、我将尽力重新创建它、但正如您所说、可靠地重新创建似乎有点困难。 我将在后台跟踪此情况、并与调查勘误表 USCI43的人员交谈、并从他们那里获得更多信息。

    在地图上、我没有意识到这一点。 我将询问一下、看看为什么会这样。 今天学到了一些新东西:)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jasaleja、

    我想我会快速更新您、需要一些时间、但我能够确认、从理论上讲、eUSCI 的 SPI 模块可能会受到导致 USCI43的同一问题的影响。 我们很快将发布一个新的勘误表来解决 SPI 问题、但我可以说、该变通办法与 USCI43中建议的解决办法非常相似。 我们建议使用中断来避免此问题。

    关于使用中断的问题、您应该确保为您的应用适当设置中断的优先级、确保在 NVIC 中 SPI 中断的优先级高于其他外设。 如果 DMA 适合您的应用、您还可以考虑使用 DMA、但我认为与轮询相比、使用中断不会减慢您的通信速度。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Evan、

    非常感谢您的回答。 非常有帮助。 在平均时间内、错误不断发生、我们用一个简单的技巧来解决它。

    经过大量测试后、我们发现应用中存在问题。 我们在主系统中使用了 eUSCIB0 SPI、有时我们将其与 DMA 同时使用。

    这导致错误发生的频率更高、但我们很快就解决了问题。 现在、问题仍然不时发生、通过额外的测试、我们设法将其缩小为硬件中的问题。  

    我想我用一个小把戏解决了这个问题。 在该 函数中轮询 CC1200_SPI_Transmit 中断后:

    静态空 CC1200_Transmit 字节(uint8_t byte)
    {
    /*等待发送缓冲区为空和发送字节*/
    while (!(EUSCI_B_SPI_getInterruptStatus (CC1200_SPI、CC1200_SPI_Transmit 中断)));
    EUSCI_B_SPI_transmitData (CC1200_SPI、字节);
    }
    
    

    我添加了一行代码:

    静态空 CC1200_Transmit 字节(uint8_t byte)
    {
    /*等待发送缓冲区为空和发送字节*/
    while (!(EUSCI_B_SPI_getInterruptStatus (CC1200_SPI、CC1200_SPI_Transmit 中断)));
    EUSCI_B_SPI_clearInterruptFlag (CC1200_SPI、CC1200_SPI_Transmit 中断);
    
    EUSCI_B_SPI_transmitData (CC1200_SPI、字节);
    } 


    现在永远不会发生错误。

    感谢您的帮助、感谢您将其添加到勘误表中。

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

    很高兴您能找到您的问题的解决方案、我们可以在该过程中提供帮助!