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.

[参考译文] TM4C123GH6PM:SPI 从器件的 SSIDataGet 阻塞

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1216291/tm4c123gh6pm-ssidataget-blocking-for-spi-slave

器件型号:TM4C123GH6PM
主题中讨论的其他器件: TM4C123

大家好、我正在使用一对 TM4C123G 评估板尝试使 SSI 通道正常工作。 这些电路板具有 TM4C123GH6PM 微控制器。 我正在使用最新版本的 Code Composer Studio 和 TivaWare 2.2.0.295。

在板之间、我们连接了 SSI1时钟、SSI1 RX/TX 交叉-板上1的 RX 连接到板上2的 TX、反之亦然。 我有两个 CCS 项目、一个是 SPI 主设备、另一个是 SPI 从设备。 我只是尝试以每秒两次的频率将"1234"从主设备传输到从设备。 我们看了示波器上的这些行、我们看到了一个1MHz 时钟和2Hz 数据。 从这一点来看、主侧似乎按预期工作。 我遇到的这个问题是在从器件上。 设置完成后、我进入了尝试读取数据的循环、并且对 SSIDataGet 的第一次调用从不返回。 两侧都有源代码。 "我怎么了?"

// SPI master
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

/////////////////////////////////////////////////////////////////////////////
void InitializeSystem()
{
    // Set the clocking to run directly from the crystal.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    // Initialize UART1 to 115200 baud, N-8-1
    // UART1 : GPIO Port B : UART1RX = PB0 : UART1TX = PB1
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinConfigure(GPIO_PB0_U1RX);
    GPIOPinConfigure(GPIO_PB1_U1TX);

    GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200,
                        UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
}

/////////////////////////////////////////////////////////////////////////////
void InitializeSSI1()
{
    // Enable the SSI1 peripheral for use.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);

    // We have PD0 (SSI1 Clk), PD2 (SSI1 Rx), and PD3 (SSI1 Tx) connected.
    // (Odd thing, pins/ports for SSI1 are the same as SSI3 ?!)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    // Configure the pin muxing for SSI functions
    GPIOPinConfigure(GPIO_PD0_SSI1CLK);
    GPIOPinConfigure(GPIO_PD1_SSI1FSS);
    GPIOPinConfigure(GPIO_PD2_SSI1RX);
    GPIOPinConfigure(GPIO_PD3_SSI1TX);

    // Configure the GPIO settings for the SSI pins.  This function also gives
    // control of these pins to the SSI hardware.
    GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    // Configure and enable the SSI port for SPI master mode.
    SSIDisable(SSI1_BASE);
    SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 1000000, 8);

    // Advance mode settings. Legacy is default. I've seen several mentions
    // in technical forum discussions that when writing as SSI master, you
    // need "dummy" reads (in legacy mode)?
    //SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_WRITE);

    // Enable the SSI module.
    SSIEnable(SSI1_BASE);

    // Read residual data from the SSI port so we don't read any junk.
    uint32_t RxData;
    while (SSIDataGetNonBlocking(SSI1_BASE, &RxData))
    {
    }
}

/////////////////////////////////////////////////////////////////////////////
int main(void)
{
    InitializeSystem();
    InitializeSSI1();

    // A call to SysCtlDelay with a delay count of 1 takes 3 clock cycles
    unsigned int nDelayOneMillisecond = (SysCtlClockGet() / 3) / 1000;
    const unsigned int nDelayCount = 500 /* milliseconds */ * nDelayOneMillisecond;

    const unsigned int Message[4] = { '1', '2', '3', '4' };
    uint32_t RxData = 0;
    while (true)
    {
        // Transmit on SPI and UART every <n> milliseconds.
        SysCtlDelay(nDelayCount);

        for (unsigned int nByte = 0 ; nByte < 4 ; nByte++)
        {
            while (SSIDataGetNonBlocking(SSI1_BASE, &RxData)) {}
            SSIDataPut(SSI1_BASE, Message[nByte]);
//            SSIDataGetNonBlocking(SSI1_BASE, &RxData);
            UARTCharPut(UART1_BASE, (unsigned char)Message[nByte]);
        }
    }
}

// SPI slave
#include <stdint.h>
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

/////////////////////////////////////////////////////////////////////////////
void InitializeSystem()
{
    // Set the clocking to run directly from the crystal.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    // Initialize UART1 to 115200 baud, N-8-1
    // UART1 : GPIO Port B : UART1RX = PB0 : UART1TX = PB1
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinConfigure(GPIO_PB0_U1RX);
    GPIOPinConfigure(GPIO_PB1_U1TX);

    GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(), 115200,
                        UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
}

/////////////////////////////////////////////////////////////////////////////
void InitializeSSI1()
{
    // Enable the SSI1 peripheral for use.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);

    // We have PD0 (SSI1 Clk), PD2 (SSI1 Rx), and PD3 (SSI1 Tx) connected.
    // (Odd thing, pins/ports for SSI1 are the same as SSI3 ?!)
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

    // Configure the pin muxing for SSI functions
    GPIOPinConfigure(GPIO_PD0_SSI1CLK);
    GPIOPinConfigure(GPIO_PD1_SSI1FSS);
    GPIOPinConfigure(GPIO_PD2_SSI1RX);
    GPIOPinConfigure(GPIO_PD3_SSI1TX);

    // Configure the GPIO settings for the SSI pins.  This function also gives
    // control of these pins to the SSI hardware.
    GPIOPinTypeSSI(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);

    // Configure and enable the SSI port for SPI slave mode.
    SSIDisable(SSI1_BASE);
    SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE, 1000000, 8);
    //SSIConfigSetExpClk(SSI1_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE_OD, 1000000, 8);

    // Advance mode settings. Legacy is default.
    //SSIAdvModeSet(SSI1_BASE, SSI_ADV_MODE_LEGACY);

    // Enable the SSI module.
    SSIEnable(SSI1_BASE);

    // Read residual data from the SSI port so we don't read any junk.
    uint32_t RxData;
    while (SSIDataGetNonBlocking(SSI1_BASE, &RxData))
    {
    }
}

/////////////////////////////////////////////////////////////////////////////
int main(void)
{
    // Initialize the system
    InitializeSystem();
    InitializeSSI1();

    unsigned int nByte = 0;
    while (true)
    {
        // Get next charater on SPI and forward to UART
        SSIDataPut(SSI1_BASE, 0); // dummy write?
        SSIDataGet(SSI1_BASE, &nByte);
        UARTCharPut(UART1_BASE, (unsigned char)nByte);
    }
}

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

    我们通过在两个板之间连接 FSS 引脚来实现这一点。 但我们仍然有一个问题,这需要在没有 FSS 的情况下工作。 我们使用 SDLC/SPI 连接惯性单元。 为此、我们目前使用 MSP430、它们工作正常、但我们想升级到 TM4C。 那里的接口只有连接到微控制器的时钟和 RX。 所有 MOTO 模式是否都需要 FSS? 有没有一个不起作用的模式?  

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

    尊敬的 David:

     TM4C123作为主器件时不需要片选功能。 如果需要、可以将 FSS 引脚重新用于 GPIO 引脚。 它是需要芯片选择进行资格认证的从器件。  要使 MOTO 模式在 TM4C123上作为从设备工作、您必须选择芯片。 不过、该芯片选择无需 FSS、因为在您当前的设置中使用两个不同的 TM4C 板、您可以通过在主器件侧使用 GPIO 引脚生成自己的芯片选择。 当时钟到达时、从器件需要片选信号来限定数据采样。 如果您有另一个不需要片选的从器件、它将在接收到主器件的时钟时对数据进行采样。 但是、我还没有遇到不需要片选的从器件。

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

    谢谢 Charles、我认为这对您有所帮助。 请先不要锁定螺纹。

    负责 MSP430实施的人员已经离开了。 此处未连接从器件选择。 该引脚具有多功能、并选择了其他功能之一。 根据您的答案、我们猜测当未选择时、从设备选择处于告知从设备数据始终有效的状态。 软件会不断地进行读取、包括实际数据之间的所有填充。 ?!

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

    尊敬的 David:

     当你写回这个线程时、该线程会自动 将状态设置为打开、并且我会收到通知。  

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

    我对正在工作的现有 MSP430设计进行了更深入的研究。 除了时钟和数据外、该器件还具有用于 SPI 的 STE (从器件发送启用)。 STE 与 TM4C 上的 FSS 相同? MSP430有一种3引脚模式、在该模式下不使用 STE、而这是我们要使用的模式。

    对于 TM4C 上的 SPI 从器件、则需要使用 FSS。 那么、在 MSP430上没有相当于3引脚模式的模式?

    对于一对 TM4C 评估板、它在一个上运行 SPI 主器件而在另一个上运行 SPI 从器件、它在 MOTO_MODE_3下运行、FSS 仅在从器件上接地、而不连接到电路板。 但在连接到我们尝试侦听的传感器的 SPI 从器件上进行了此尝试、但数据仍然不正确。 我们将传感器输出分离到了 MSP430和 TM4C、MSP430仍能正确读取数据。

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

    您好!

    但在连接到我们尝试收听的传感器的 SPI 从设备上尝试过此操作,但数据仍然不正确。

    您能详细说明一下什么不妥吗?  

    根据您的响应,TM4C 上的 SPI 从设备需要 FSS。 因此、MSP430上的3引脚模式没有等效功能?

    再次阅读数据表、它具有有关模式0和模式2的以下说明。 您将需要对这两种模式使用 FSS。  

    在连续的背对背传输中、必须以 SSInFss 信号脉冲形式传输
    由于从器件选择引脚在数据串行时冻结数据、因此每个数据字传输之间为高电平
    外设寄存器、如果 SPH 位被清零、则不允许更改该位。 从而成为主设备
    器件必须在每次数据传输之间拉高从器件的 SSInFss 引脚以启用
    串行外设数据写入。 连续传输完成后、将返回 SSInFss 引脚
    将在捕获到最后一个位后的一个 SSInClk 周期内恢复到其空闲状态。

    在一对 TM4C 评估板上,在一个评估板上运行 SPI 主站,在另一个从板上运行 SPI 主站,它在 MOTO_MODE_3下工作,FSS 仅在从板上接地,而不连接到板

    对于模式1和模式3、下面介绍了这两种模式。  

    连续的背靠背传输、SSInFss 引脚保持低电平有效状态、直到
    最后一个字的最后一位已被捕捉、然后返回到如上所述的空闲状态。


    对于连续的背靠背传输、SSInFss 管脚在连续的数据字之间保持低电平
    端接与单字传输相同。

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

    您能详细说明一下什么不妥吗?  

    执行一些操作。 传入数据使用 SDLC、应该在实际数据的开始和结束时进行同步、该数据由之前和之后的六个1位组成。 它们之间的消息大约为30字节。 消息和同步标记之间的填充 XFF。 我将 MSP430代码转移到了尽可能紧密的 TM4C 上。 它可以在 MSP430上找到开始和结束同步、它只能偶尔在 TM4C 上工作。 在 TM4C 上、大多数情况下它不会找到 SYNC、有时它会找到 SYNC、但很早、有时则是关闭。

    我们还修改了我们使用的硬件、使传感器时钟和 RX 输出同时传送到 MSP430和 TM4C。 我在两者上放软件、以便在舍弃 XFF 填充器后只接受 SPI 输入并发送 UART。 并在 PC 上同时记录了这两项内容。 它是不同的。 我可以在 MSP430输出中找到唯一的字节序列、但在 TM4C 输出中找不到相同的序列。 反之亦然

    以上两种都处于 MOTO_MODE_3中、FSS 接地。  从模式1和3的描述来看、它似乎应该起作用? 但会有来自某些东西的噪声。

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

    小更新。 我们在 MSP430中检查了 UCA 控制寄存器。 它们设置为时钟极性0、时钟相位1、8位、3引脚 SPI 从器件。 因此、我们使用 MOTO_MODE_1对 TM4C 进行了重新测试、传入的数据仍然不干净。

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

    您好!

     在字节之间 FSS (芯片选择)确实保持低电平。 不过、不知道 FSS 是否与 GND 绑定在一起、从状态机是否知道传输的正确开始。   

    如果 QSSI 启用并且发送 FIFO 中存在有效数据、则表示开始发送
    由被驱动为低电平的 SSInFss 主信号构成。 主机 SSInDAT0/SSInTX 输出启用。
    半个 SSInClk 时钟周期后、主机和从机的数据都已就绪
    各自的传输线路。 与此同时 SSInClk 以一个上升沿使能
    转换时发生。

    它可以在 MSP430上找到开始和结束同步,它只能偶尔在 TM4C 上工作。 大部分时间在 TM4C 上它不会找到同步,有时它会找到同步,但很早,有时它关闭。[/报价]

    您是否在 SSI 中看到任何错误,如接收超时?

    这两者之间的消息约为30字节。 消息和同步标记之间的输入用 XFF 填充。

    消息中字节之间的持续时间是多少? 消息之间的间隔时间是多长? 由于 FSS 已接地、因此 请确保 将超时计数器重置为 o

    RX FIFO 有一个相关的超时计数器、该计数器会在递减计数的同时开始递减计数
    SSISR 寄存器的 RNE 位标志为非空。 该计数器可随时复位  

    一个新的或下一个字节被写入 RX FIFO、因此计数器将继续递减计数到0
    除非有新活动。 根据 SSInClk 周期、超时周期为32个周期。
    当计数器计数到0时、SSIRIS 寄存器中的超时中断位 RTRIS 将置位。
    向 SSI 中断清零(SSIIC)的 RTIC 位写1即可清除超时中断。
    或清空 RX FIFO 来设置。 如果中断被清除并且中还有残留数据、则可能会发生这种情况
    已写入 RX FIFO 或新数据条目、计时器向下计数启动中断
    计数到32个周期后重新置位。

    在您启动从机前、您是否先清除了接收 FIFO?

    //
    //从 SSI 端口读取任何剩余数据。 这可以确保接收
    // FIFO 为空,因此我们不会读取任何不需要的垃圾邮件。 具体操作请点击此处
    //因为 SPI SSI 模式是全双工的,允许您发送和
    //同时接收。 SSIDataGetNonBlocking 函数返回
    //返回数据时为"true",未返回数据时为"false"。
    //"非阻塞"函数检查接收中是否存在任何数据
    // FIFO,如果没有,则不会"挂起"。
    //
    while (SSIDataGetNonBlocking (SSI0_BASE、&pui32DataRx[0])

    }

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

    我试图从示波器上载时钟和数据线的图像、它们看起来像上载的一样、但在预览窗格中没有显示任何图像。

    消息以~400Hz 的频率出现。 然后传感器(SPI 主器件)的时钟线为1.0152MHz、并且始终运行。 在示波器上、您可以看到每条消息的长度为~0.25毫秒、然后数据线处于高电平持续2.25毫秒、直到显示下一条消息。 您可以看到、时钟的上升沿以每个数据位为中心。

    我没有看到接收超时。 我正在使用阻止 SSI 调用来读取数据。 我在前面添加了以下内容:

                nInterruptStatus = SSIIntStatus(SSI1_BASE, false);
                if ((nInterruptStatus & SSI_RXTO) != 0)
                {
                    nTimeoutCount++;
                }
                SSIDataGet(SSI1_BASE, &nData);
    

    我让它在调试器中运行一段时间、然后中断、超时计数为零。 我希望是这样、因为时钟始终存在、并且消息之间的数据线较高、消息之间的读取返回0xFF、并且始终有内容要读取。

    是的、我确实在启动从器件之前清除了接收 FIFO、它位于我最初上传的代码样本中 InitializeSSI1的底部。 我将在启用 SSI1之后执行此操作、这是在我看到的所有采样中完成的操作。

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

    您好!

     您可以将文件拖动到编辑器中。 如果仍有问题、请将图像捕获到文件中、然后将文件拖放到上面。 看到这些图片很好,但通过你的描述,我应该清楚我所问的问题。  

     我有一些问题:

     -从机是否未能正确捕获第一条消息,还是始终是一些以后的消息?

     -如果您只关注第一条消息,从器件是否正确解码消息的开头(01111110b)和结尾(01111110b)?

     -我认为上述问题的答案将有助于回答如果问题是由于没有 FSS -其中从机无法识别 SPI 传输的第一位。

     -我将建议您在 TX 引脚上发送接收到的数据,而不是发送虚拟'0'。 通过这种方法、可以在逻辑分析仪上查看 RX 和 TX。 这样可以更轻松地查看 TX 和 RX 开始偏离的位置。  

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

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

    我看到了图像、但这正是主器件发送的内容。 我真不知道该怎么办。 您能回答我之前提出的问题吗? 逻辑分析仪将极大地促进调试、尤其是消息流的调试。  

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

    我修改了代码、在 SSIDataGet 接收每个字节后、立即将该代码写入 SPI Tx。 还切换回 MOTO_MODE_3、这与 TM4C 文档最匹配、从器件选择低电平和在上升时钟沿进行采样的数据位。

    重点关注第一条消息。 消息的长度为31到33字节。 我在调试器中运行了10次、设置了一个断点、其中代码认为它可以同时看到某条消息的开始标记和结束标记、或者知道它走得太远(>60个字节)而找不到结束标记。 我转到了第一个断点、第一条消息。 只有一个运行看起来可能是合法的、其余的则在60字节后或更早的时候停止。

    我还要在 MSP430上、在相同的输入上运行相同的代码。 它每次都会查找起始标记和结束标记、终止标记在起始后始终为31到33个字节。

    我们没有逻辑分析仪。 如果您认为这很关键、我们将找到解决方法。 非常感谢您的帮助。

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

    尊敬的 David:

    注意第一条消息。 消息的长度为31到33字节。 我在调试器中运行了10次、设置了一个断点、其中代码认为它可以同时看到某条消息的开始标记和结束标记、或者知道它走得太远(>60个字节)而找不到结束标记。 我转到了第一个断点、第一条消息。 只有一个运行看起来可能是合法的,其余的则在60字节后或更早的时候停止。

    首先、我真的认为逻辑分析仪值得投入、尤其是用于调试您的电流问题、它会非常方便。 如今的逻辑分析仪可解码您能想到的大多数通信协议、而不仅仅是 SPI。 这样、您也可以将其用于调试其他协议。 根据模型、您最多可以捕获一秒钟的线迹。 需要采集大量数据。 我不支持任何特定的模型。 您可以进行一些最适合您的开发的搜索。  

    只有一个运行看起来似乎是合法的,其余的则在60个字节后或更早的时候停止。

    我还不知道问题是否与软件或硬件有关。 因此、我们需要一些实验。

     -您可以关注01111110b 上的 Start Marker。 您的外部主器件只能发送起始标记吗? 您能否始终可靠地接收此01111110b? 这只是一个字节。 如果您甚至无法接收此字节、那么我认为这不是软件问题。 如果您无法控制主器件生成更多的字节、则至少应将您的范围配置为在时钟的第一个边沿触发。 TX 和 RX 是什么样子的?

     -为了隔离是否是硬件问题,我建议您使用另一个 GPIO 引脚控制到从器件的 FSS 输入引脚。 首先、在从器件初始化之前以及您即将启动主器件传输之前将 FSS 引脚置为高电平、将 FSS 置为低电平。 您能否可靠地捕获起始标记和第一条消息? 如果 FSS 的存在(即 SPI 传输的开始)有所不同、那么我们可以知道问题与 FSS 引脚有关。 如果接收仍然在某个地方蹩脚,也许它有一些东西与软件。  

     -如何处理接收到的数据? 您是否在使用中断? 您是否使用 UARTprintf()将数据发送到终端? 我想知道您是如何编写软件的。 我提出这个问题的原因是、UART 的运行速度比 SPI 慢得多。 如果您正在等待 UART 完成传输、SPI 可能会接收到更多数据。 换言之、UART 可能无法跟上 SPI。 如果您在阻塞模式下使用 UART、您可能会  在 SSI RXFIFO 中丢失数据。 据我所知、它不会丢失数据、而是捕获错误的数据、是这样吗?

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

    我想这种情况下有一个断点。 我编写了测试应用程序来执行您建议的操作、只需查找起始标记即可。 我首先做了 MSP430、它工作正常。 然后、我选择了 TM4C、它使用了与 MSP430中相同的扫描代码。 它不起作用。 但是... 然后检查位流的字节顺序。 在 TM4C 上、位被反转、MSB 是 MSP430上的 LSB。 我将 TM4C 切换为反转扫描、它现在已成功找到开始标记。 我上周检查了 MSB/LSB、但肯定犯了一个错误。 现在、我将查找尾部同步以查看它是否有效。

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

    尊敬的 David:

     这是一个很好的发现。 看起来您已缩小 Tiva 和 MSP430之间的差距。 请告知我们您是否能够成功扫描跟踪同步。  

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

    我现在也能可靠地获得尾部同步。 非常感谢您的帮助!

    这里是对任何人的总结。

    我们正在进行硬件升级、并计划使用 TM4C 来替代 MSP430。 我们将与使用 SDLC 并且是 SPI 主设备的 IMU 连接。 我们仅连接到时钟和 RX (来自 IMU 的 TX)的 SPI 线路。 另外还涉及 TX 和 FSS 这两条线路。 我们使 TX 保持未连接状态、它可以在 MSP430和 TM4C 上运行。 IMU 的时钟始终开启。

    MSP430数据表将第4行 SPI 称作 STE、而不是 FSS、我们使用的是将其忽略的3引脚模式。 在 MSP430上、这个引脚是未连接的。 它工作正常、具有始终需要读取数据的奇特性。 在实际数据帧之间、这两条线是三态的、读数为0xFFs。

    为了使类似的代码能够在 TM4C 上运行、我们没有找到3引脚模式。 在 SSI_FRF_MOTO_MODE_3中运行、FSS 接地。 对于 MOTO_MODE_3、FSS 在数据有效时为低电平。 将其接地、似乎会在模式3中告诉 SPI 从器件数据始终有效。 因此、我们可以像在 MSP430上一样在数据之间获取0xFF 填充字段。 拼图的最后一项内容是、位流在 TM4C 上与 MSP430上的位流反相。 考虑到这一点、我们现在要在位流中找到包含数据的 SDLC 起始标记和结束标记。 此外,我们使用 SSI_MODE_SLAVE_OD 是值得的,因为我们只听:

    SSIConfigSetExpClk (SSI1_base、SysCtlClockGet ()、SSI_FRF_MOTO_MODE_3、SSI_MODE_SLAVE_OD、1000000、 8);