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接收中断问题

Guru**** 2584395 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/616214/msp432p401r-problem-with-spi-receive-interrupt

部件号:MSP432P401R

您好! 我尝试使用MSP432 通过SPI与CY15B104Q FRAM通信。 问题是,如果我在触发RX ISR后立即读取接收缓冲区,它将读取0,但如果我在读取前添加一个小延迟,它将读取正常。 我使用的是CCS SDK.TI 16.9 v.4.LTS,0.0.0013万 7.2 1.40 .1.00。 这是我的代码:

CY15B104Q_Assert_CS();
while (framTxFlag == false)
{
MAP_PCM_GotoLPM0InterruptSafe ();
MAP_Interrupt_enableMaster();
}
framTxFlag =假;
SPI_SPI_SpeneData (EUSI_A1_base, 0x05);

while (framTxFlag == false)
{
MAP_PCM_GotoLPM0InterruptSafe ();
MAP_Interrupt_enableMaster();
}
framTxFlag =假;
SPI_SPI_Spendate(EUSI_A1_base, 0x00);//虚拟写入以从FRAM中超时数据

while (framRxFlag == false)
{
MAP_PCM_GotoLPM0InterruptSafe ();
MAP_Interrupt_enableMaster();
}
framRxFlag =假;

CY15B104Q_DEASSERT_CS();




void EUSCIA1_IRQHandler (void) { unsigned int状态; 状态= MAP_SPI_getEnabledInterruptStatus(EUSSCI_A1_base); MAP_SPI_clearInterruptFlag (EUSCI_A1_BASE,状态); Char Rx; IF (状态和EUSCI_A_SPI_Transmit_Interrupt) { framTxFlag =真; } IF (状态和EUSCI_A_SPI_Receive_interrupt) { int jj; 对于(jj=0;j<100;jj++); Rx = MAP_SPI_receiveData(EUSSCI_A1_base); framRxFlag =真; } MAP_Interrupt_DisableSleepOnIsrExit(); }

如果我从IRQ处理程序注释for()循环,则SPI_receiveData()读数为0,但循环读数为OK。

问题是什么? 是否按预期工作? 接收缓冲区已满时,RX中断似乎未触发。

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

    我可以研究一下并尝试为您解决这个问题。 您能否与我分享您的SPI配置的外观? 您是否有一个精简的代码示例,我可以调查并查看是否可以重新创建?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    基督教,

    此外,在添加延迟之前和之后,您是否有任何示波器/逻辑分析器快照?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您正在通过SPI发送两个字节,因此(根据定义)您收到两个字节。您对第二个字节感兴趣。

    由于Tx中断的工作方式,第一个Rx字节很有可能在您发送第二个Tx字节后到达。

    最简单的解决方案可能是在发送第二个Tx字节之前,使用framRxFlag联锁显式获取(并丢弃)第一个Rx字节。  

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

    我附上了该项目,以便您进行测试。 我还尝试了以下代码:

    UINT8_t tempBuffer =0;
    同时(!(MAP_SPI_getInterruptStatus (EUSCI_A1_BASE,EUSCI_A_SPI_Transmit_Interrupt)));
    UCA1TXBUF = 0x05;//读取状态寄存器操作码
    while (!(MAP_SPI_getInterruptStatus(EUSSCI_A1_base, EUSCI_A_SPI_Transmit_Interrupt));//虚拟写入以超时数据
    UCA1TXBUF = 0;
    
    同时(!(MAP_SPI_getInterruptStatus (EUSCI_A1_BASE,EUSCI_A_SPI_Receive_interrupt)));
    int jj;
    对于(jj=0;j<100;jj++);
    TempdBuffer = UCA1RXBUF; 

    如果没有for ()延迟,则tempBuffer始终为0。

    e2e.ti.com/.../test.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    遗憾的是,我没有任何分析仪捕获。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果我只发送第一个字节,我只收到0。 所以我得出结论,我需要生成一个时钟信号来读取FRAM的响应。 所以我发现虚拟写入是解决方案。

    我注意到,读取缓冲区之前,我需要先放置一个断点,以延迟时间。 当我使用断点时,它显示为OK。 但当我在读取缓冲区后放置断点时,它的读数为0。 使用该延迟时工作正常(但我认为RX中断在RX缓冲区满时发生!)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这些都是正确的陈述。

    问题是这个代码--没有延迟--读取第一个Rx字节(根据数据表为0),然后完成。 添加延迟可为第二个Rx字节(您想要的字节)的到达留出一些额外时间。 这种“工作”(如您所见),但不遵循硬件协议,因此是危险的--特别是您需要获得适合您的SPI速度的延迟;它也不能扩展到>2字节。

    这就是我建议(上面)在发送第二个字节之前显式接收并丢弃第一个字节的原因。 通过在硬件协议中工作,您始终知道您正在读取哪个字节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢! 我现在明白为何有需要这样做。 我在读取前已尝试清除RX中断标志,但它未读取"正常"。 您知道原因吗?