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.

[参考译文] MSP430G2313:MSP430 USCI SPI 从器件恢复似乎关闭了一位。

Guru**** 2524460 points
Other Parts Discussed in Thread: MSP430G2313

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/590204/msp430g2313-msp430-usci-spi-slave-recv-seems-to-be-off-by-one-bit

器件型号:MSP430G2313

大家好

我将 MSP430G2313 USCI 配置为 SPI 从设备(POL=0、PH=0、3线、RX 中断启用)、该设备通过可拆卸连接器连接到 SPI 主设备。  当我连接连接器时、SCK 引脚上可能会出现随机噪声、这会将 SPI 移位寄存器置于部分移位状态。

我通过监视 SPI 忙状态(UCB0STAT 和 UCBUSY)来解决此问题。  如果我看到大于~50ms 的繁忙状态,我将假定移位寄存器中有部分移位数据,并且我将通过 UCB0CTL1中的 UCSWRST 位复位 SPI 通道以清除该状态。

我的问题是、在 SPI 复位后、接收到的 SPI 数据似乎被右移一位(即、我的逻辑分析仪显示主器件发送0xA5、但当我进入 RX ISR 时、UCB0RXBUF 为我提供0x52)。  一旦我进入这种状态(UCB0STAT 和 UCBUSY),我就会说我不忙,所以 SPI 硬件似乎不会认为有任何问题。

有一个错误条目 USCI40描述了一个逐位问题、但它仅在 PH=1和 Xmit 上而不是 Recv 时出现。  也许是相关的?  

有什么关于我可能出错的想法吗?

谢谢你

Scott

以下是我的初始化代码:

// SPI 设置
UCB0CTL0 = 0b00100001;// pH = 0、pol = 0、MSB 1、8位、 从器件、3引脚 SPI、SYNC/SPI 模式
UCB0CTL1 = 0b00000000;//无复位 SPI
UCB0STAT = 0b00000000;//清除任何错误
IE2 |= UCB0RXIE;//启用 Rx 中断

每~8ms 调用一次该函数、以检查是否存在部分移位的数据:

//如果 SPI 卡在部分 xfer 上~50ms,则假设
// SCK 线路上的一些噪声会缓冲并重置传输
bool spiBusy =(UCB0STAT & UCBUSY)!= 0;
if ( spipidBusy ){

if ( SpipidBusy == spipy )
FailCount++;
if (spiFailCount >= 6)
{
spiFailCount = 0;
UCB0CTL1 = 0x01;//重置 SPI
UCB0CTL1 = 0x00;
IE2 |= UCB0RXIE;//重新启用 Rx 中断
}

否则
spiFailCount = 0;
SpiBusy = spipy;

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

    难怪 SPI 不是 UART 而会出现问题:)您应该使用具有较长 GND 引脚的连接器,在从端 MOSI/CLK 线路上添加弱下拉电阻器。 此外、您还需要使用下拉电阻器实现片选(CS)信号。 使用 SOMI 线路的从器件检测不会受到影响-主器件可以检测连接的从器件、执行一些延迟、使用 CS 复位从器件、再次延迟、然后仅启动 SPI 通信。 如果您无法添加 CS、您也可以实施一些初始握手、以允许主器件确保从器件同步、但这种方法"异常"、并且比仅 CS 解决方案更难进行编码。

    [编辑]为了实现器件间通信、最好使用 UART。

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

    我同意 UART 会更好、但遗憾的是、我要通信的器件只有 SPI 输出。 :(

    我还想使用 STE、但连接器只有三根导线。 :(

    我做了一些测试、当一个位被移入移位寄存器时、UCBUSY 标志会错误地返回 FALSE。  如果2-7位已经移入、UCBUSY 将正确返回 true。

    我当前的权变措施是、如果预期的命令字节被移动一位、则重置 SPI 通道。  我还将检测代码移至 SPI ISR 中:

    #pragma vector=USCIAB0RX_Vector
    __interrupt void SPI_intr (void)
    {
    unsigned int rx = UCB0RXBUF;
    
    //如果 SPI 卡在部分 xfer 上,假设
    // SCK 线路上的一些噪声会缓冲并复位 SPI
    
    //*** hack alert ***!
    // UCBUSY 在单个位已移入 SPI
    //移位寄存器时错误地报告为 false,因此 SPI 复位逻辑无法捕捉到它。
    由于// SPI_CMD_GET_INFO 命令在发现时调用,因此检测
    它是否被//移位一位,并将 SPI 通道复位(如果是)。
    
    if ((UCB0STAT 和 UCBUSY)!= 0 ||(Rx = SPI_CMD_GET_INFO >> 1)
    ){
    UCB0CTL1 = 0x01;//重置 SPI
    UCB0CTL1 = 0x00;
    IE2 |= UCB0RXIE;//重新启用 Rx 中断
    返回;
    }