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.

[参考译文] MSP430FR5994:USCI_B1 SPI 通信问题

Guru**** 2589275 points
Other Parts Discussed in Thread: MSP430FR5994

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/624793/msp430fr5994-usci_b1-spi-communication-issue

器件型号:MSP430FR5994

大家好、

我尝试通过 SPI 通信将 MSP430FR5994 LP 与 LIS3DSH 加速计连接  、因为这是我第一次尝试使用这组硬件。 我正在以1MHz 的频率成功传输数据。 我要做的就是从地址0x0F 中读取寄存器(WHO _AM_I)、该地址是只读器件 ID、应始终返回0x3F。 因此、在发送虚拟字节为0x00后、它始终返回0x00。 我尝试发送其他测试数据、但它总是以0回复。 我不确定会出现什么问题。 请提前提供帮助、谢谢。

/*
*文件:main.c
*作者:Anand
*/


//***** 包括*****
#include 
#include 
#include "msp430fr5994.h"

#include "spi.h"

//***** 定义了*****
#define SPI_TIMEOUT 1234

uint16_t WHO _AM_I;

//***** 私有函数原型*****
void main (void);
void clock_init (void);

//***** 私有函数定义*****

/*
*@简短 XT1设置
*@参数无
*@返回无
*/
void clock_init (void)
{
CSCTL0_H = CSKKEY_H; //解锁 CS 寄存器--- |
// |
CSCTL1 = DCOFSEL_0; //将 DCO 设置为1MHz |
CSCTL1 &=~DCORSEL; // |
// |
CSCTL2 = SELA_LFXTCLK;// LFXTCLK (如果可用)、否则为 VLOCLK |
CSCTL2 |= SELs__DCOCLK;// DCOCLK |
CSCTL2 |= SELM_DCOCLK;// DCOCLK |
// |
CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; //设置所有分频器 |
// |
CSCTL4 &=~LFXTOFF; //如果选择 LFXT,则 LFXT 打开|
// |
操作 // |
{ // |
CSCTL5 &=~LFXTOFFG; //清除 XT1故障标志 |
SFRIFG1 &=~OFIFG; //
|} // |
while (SFRIFG1和 OFIFG); //测试故障标志 |
// |
CSCTL0_H = 0; //锁定 CS 寄存器--- |
}//


*@brief 这是 main 函数
*@param None
*@Return None
*/
void main (void)
{
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

//配置 GPIO
spi_b_gpio_init ();


//初始化时钟
clock_init();

//禁用 GPIO 上电默认高阻抗模式以激活
//先前配置的端口设置
PM5CTL0 &=~LOCKLPM5;

//初始化用于 SPI 操作的 USCI_B1
spi_b_init ();

P8DIR = 0xFF; //端口8作为输出
P8OUT = 0x00; //端口8为低输出

UCB1TXBUF = 0x0F | 0x80; //发送字符| R/W 位

uint16_t SPI_TIMEOUT = SPI_TIMEOUT;

while (((UCB1STATW && UCBUSY)&&(SPI_TIMEOUT > 0))
{
SPI_TIMEOUT--;
}

if (SPI_TIMEOUT = 0)
{
printf ("SPI 1发送失败\n");
}

UCB1TXBUF = 0x00; //发送字符

SPI_TIMEOUT = SPI_TIMEOUT;

while (((UCB1STATW && UCBUSY)&&(SPI_TIMEOUT > 0))
{
SPI_TIMEOUT--;
}

if (SPI_TIMEOUT = 0)
{
printf ("SPI 2发送失败\n");
}
其他
{
printf ("SPI 2发送时间:%u \n"、SPI_TIMEOUT);
}

WHO _AM_I = UCB1RXBUF;

printf ("正在退出 main \n");

返回;
}

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

    我在这里看不到 SPI_b_init(),但根据您的分析器设置,我怀疑您的时钟相位(UCCKPH)是反向的。 (在捏合时:尝试所有设置。 其中只有4个。)

    未经请求:

    > while (((UCB1STATW && UCBUSY)&&(SPI_TIMEOUT > 0))

    这种情况只会意外发生。 尝试:

    > while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))

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

    Bruce、您好!

    以下是我初始化 SPI 通信的设置。

    //*
    @将 USCI_B1配置为 SPI 操作
    *@param None
    *@return None
    */
    void SPI_b_init (void)
    {
    UCB1CTLW0 = UCSWRST; //将状态机复位--- |
    //|
    UCB1CTLW0 |= UCCKPH; //|
    UCB1CTLW0 |= UCCKPL; //无效状态为高电平 |
    UCB1CTLW0 |= UCMSB; // MSB 优先 |
    UCB1CTLW0 |= UCMST; //主模式 |
    UCB1CTLW0 |= UCMODE_2; 在 UCxSTE = 0时启用// 4引脚 SPI 从器件|
    UCB1CTLW0 |= UCSYNC; //同步模式 |
    UCB1CTLW0 |= UCSTEM; // STE 为从机生成使能信号 |
    UCB1CTLW0 |= UCSSEL_SMCLK;// SMCLK |
    //|
    UCB1BRW = 0x01; ///1 |
    //|
    UCB1CTLW0 &=~UCSWRST; //操作释放-------------------------------------------------------
    |}
    

    此外、我已使用 single &更改了 while 循环的代码、感谢您的更正。 此处是从加速计数据表中读取的 SPI 作为参考。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我读取 LIS3DH DS sec 6.2和 SLAU367L 表25-12时、UCCKPH 应为0。 您是否以这种方式尝试过?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我也尝试了这种方法。 默认情况下、复位 时 UCCKPH 将设置为0。 我尝试将其覆盖为:

    //*
    @将 USCI_B1配置为 SPI 操作
    *@param None
    *@return None
    */
    void SPI_b_init (void)
    {
    UCB1CTLW0 = UCSWRST; //将状态机复位--- |
    //|
    UCB1CTLW0 &=~(UCCKPH); //|
    UCB1CTLW0 |= UCCKPL; //无效状态为高电平 |
    UCB1CTLW0 |= UCMSB; // MSB 优先 |
    UCB1CTLW0 |= UCMST; //主模式 |
    UCB1CTLW0 |= UCMODE_2; 在 UCxSTE = 0时启用// 4引脚 SPI 从器件|
    UCB1CTLW0 |= UCSYNC; //同步模式 |
    UCB1CTLW0 |= UCSTEM; // STE 为从机生成使能信号 |
    UCB1CTLW0 |= UCSSEL_SMCLK;// SMCLK |
    //|
    UCB1BRW = 0x01; ///1 |
    //|
    UCB1CTLW0 &=~UCSWRST; //操作释放-------------------------------------------------------
    |} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您提到您的(寄存器)写入操作成功。 您是如何测试的(在无法读回它们的情况下)?

    在您开始交易时、我也有点担心 MOSI 上的低脉冲。 有趣的是、这会在 LIS3DH 内部生成 I2C 启动条件。 人们认为、一旦您断言/CS、它就会完美地将模式切换到 SPI、但我不确定我的项目是否会这样做。

    我假设这个脉冲与 SPI_b_GPIO_init ()有关--我在这里看不到--所做的是什么。 即使如此、我怀疑如果您移动 LOCKLPM5清除以跟随 SPI_b_init()、该脉冲将消失。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    哦、和:为了有趣、尝试写入一个不是0x00的"虚拟"(第二)字节。 有些与众不同的东西、例如0x5A。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我还没有尝试将数据写入器件寄存器。 我的意思是、在读取寄存器时、我可以看到正在输出正确的数据。 此外、我认为 P5.3是在原始示例代码中选择的 CS 线路、但由于该引脚在分线开发板上无法访问、因此我使用 P8.3作为 CS 线路并手动控制它。

    /*
    *@简要配置 USCI_B1 SPI GPIO 操作
    *@参数无
    *@返回无
    */
    void SPI_b_GPIO_init (void)
    {
    P5SEL1 &=~(BIT0 | BIT1 | BIT2 | BIT3);// USCI_B1 SCLK、MOSI、
    P5SEL0 |=(BIT0 | BIT1 | BIT2 | BIT3);// STE 和 MISO 引脚
    PJSEL0 |= BIT4 | BIT5;
    } 

    我尝试发送虚拟字节为0x55、但仍然返回0。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    移动 LOCKLPM5语句是否会消除该额外的 MOSI 脉冲? 您也可以(可能应该)移动 SPI_b_GPIO_init()调用以跟随 SPI_b_init()调用,以获得相同的效果。

    您可能不想在此应用程序中使用 UCSTEM。 它只提供1字节的传输,并且 LIS3DH 的传输都大于1字节。 您应该计划将/CS 引脚明确控制为 GPIO。 (您可以使用 P5.3、P8.3或任何方便的内容。)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尝试移动 LOCKLPM5、但对从加速计返回的数据没有影响。 以下是更新后的代码:

    /*
    *文件:main.c
    *作者:Anand
    */
    
    
    //***** 包括*****
    #include 
    #include 
    #include "msp430fr5994.h"
    
    #include "spi.h"
    
    //***** 定义了*****
    #define SPI_TIMEOUT 1234
    #define SPI_READ_BIT 0x80
    
    uint16_t WHO _AM_I;
    
    //***** 私有函数原型*****
    void main (void);
    void clock_init (void);
    
    //***** 私有函数定义*****
    
    /*
    *@简短 XT1设置
    *@参数无
    *@返回无
    */
    void clock_init (void)
    {
    CSCTL0_H = CSKKEY_H; //解锁 CS 寄存器--- |
    // |
    CSCTL1 = DCOFSEL_0; //将 DCO 设置为1MHz |
    CSCTL1 &=~DCORSEL; // |
    // |
    CSCTL2 = SELA_LFXTCLK;// LFXTCLK (如果可用)、否则为 VLOCLK |
    CSCTL2 |= SELs__DCOCLK;// DCOCLK |
    CSCTL2 |= SELM_DCOCLK;// DCOCLK |
    // |
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; //设置所有分频器 |
    // |
    CSCTL4 &=~LFXTOFF; //如果选择 LFXT,则 LFXT 打开|
    // |
    操作 // |
    { // |
    CSCTL5 &=~LFXTOFFG; //清除 XT1故障标志 |
    SFRIFG1 &=~OFIFG; //
    |} // |
    while (SFRIFG1和 OFIFG); //测试故障标志 |
    // |
    CSCTL0_H = 0; //锁定 CS 寄存器--- |
    }//
    
    
    *@brief 这是 main 函数
    *@param None
    *@Return None
    */
    void main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    //初始化时钟
    //clock_init();
    
    P8DIR = 0xFF; //端口8作为输出
    P8OUT = 0x00; //端口8为低输出
    
    //配置 GPIO
    spi_b_gpio_init ();
    
    //初始化用于 SPI 操作的 USCI_B1
    spi_b_init ();
    
    //禁用 GPIO 上电默认高阻抗模式以激活
    //先前配置的端口设置
    PM5CTL0 &=~LOCKLPM5;
    
    UCB1TXBUF = 0x0F | SPI_READ_BIT; //发送字符| R/W 位
    
    uint16_t SPI_TIMEOUT = SPI_TIMEOUT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI 1发送失败\n");
    }
    
    UCB1TXBUF = 0x55; //发送字符
    
    SPI_TIMEOUT = SPI_TIMEOUT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI 2发送失败\n");
    }
    
    WHO _AM_I = UCB1RXBUF;
    
    P8OUT = 0xFF; //端口8作为高输出
    
    printf ("正在退出 main \n");
    
    while (1)
    {
    
    }
    
    return;
    }
    
    //
    *@brief 配置 USCI_B1 SPI GPIO 操作
    *@param None
    *@return None
    */
    void SPI_b_GPIO_init (void)
    {
    P5SEL1 &=~(BIT0 | BIT1 | BIT2 | BIT3);// USCI_B1 SCLK、MOSI、
    P5SEL0 |=(BIT0 | BIT1 | BIT2 | BIT3);// STE 和 MISO 引脚
    PJSEL0 |= BIT4 | BIT5;
    }
    
    //
    *@将 USCI_B1简要配置为 SPI 操作
    *@param 无
    *@返回无
    */
    void SPI_b_init (void)
    {
    UCB1CTLW0 = UCSWRST; //将状态机复位--- |
    //|
    UCB1CTLW0 &=~(UCCKPH); //|
    UCB1CTLW0 |= UCCKPL; //无效状态为高电平 |
    UCB1CTLW0 |= UCMSB; // MSB 优先 |
    UCB1CTLW0 |= UCMST; //主模式 |
    UCB1CTLW0 |= UCMODE_2; 在 UCxSTE = 0时启用// 4引脚 SPI 从器件|
    UCB1CTLW0 |= UCSYNC; //同步模式 |
    UCB1CTLW0 |= UCSTEM; // STE 为从机生成使能信号 |
    UCB1CTLW0 |= UCSSEL_SMCLK;// SMCLK |
    //|
    UCB1BRW = 0x01; ///1 |
    //|
    UCB1CTLW0 &=~UCSWRST; //操作释放-------------------------------------------------------
    |}
    

    我使用 P8.3手动驱动/CS、这是逻辑分析仪的新捕获。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我建议您将 SPI_b_GPIO_init 调用移至 SPI_b_init 调用之后。 我认为这将完全消除该杂散 MOSI 脉冲。

    这是商用分线板吗? 是否有任何其他连接/连接到它上?

    LIS3DH 在正确的时间驱动 MISO 这一事实表明它看到第一个字节的第一个(R/W)位。 尝试通过首先发送0xC0、然后发送64个虚拟字节来读取所有寄存器。 结果中可能有线索。 (它是否输出除0以外的任何内容?)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已将 MSP430FR5994连接到 LIS3DSH、下面是我通过跳线进行的连接:

    VDD_IO 和 VCC 连接到3V3、GND 连接到 GND、CS 连接到 P8.3、SCL 连接到 P5.2、SDA 连接到 P5.0、SDO 连接到 P5.1

    我对代码进行了相应的更改、以下是更新的代码:

    /*
    *文件:main.c
    *作者:Anand
    */
    
    
    //***** 包括*****
    #include 
    #include 
    #include "msp430fr5994.h"
    
    #include "spi.h"
    
    //***** 定义了*****
    #define SPI_TIMEOUT 1234
    #define SPI_READ_BIT 0x80
    
    uint16_t WHO _AM_I;
    
    //***** 私有函数原型*****
    void main (void);
    void clock_init (void);
    
    //***** 私有函数定义*****
    
    /*
    *@简短 XT1设置
    *@参数无
    *@返回无
    */
    void clock_init (void)
    {
    CSCTL0_H = CSKKEY_H; //解锁 CS 寄存器--- |
    // |
    CSCTL1 = DCOFSEL_0; //将 DCO 设置为1MHz |
    CSCTL1 &=~DCORSEL; // |
    // |
    CSCTL2 = SELA_LFXTCLK;// LFXTCLK (如果可用)、否则为 VLOCLK |
    CSCTL2 |= SELs__DCOCLK;// DCOCLK |
    CSCTL2 |= SELM_DCOCLK;// DCOCLK |
    // |
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; //设置所有分频器 |
    // |
    CSCTL4 &=~LFXTOFF; //如果选择 LFXT,则 LFXT 打开|
    // |
    操作 // |
    { // |
    CSCTL5 &=~LFXTOFFG; //清除 XT1故障标志 |
    SFRIFG1 &=~OFIFG; //
    |} // |
    while (SFRIFG1和 OFIFG); //测试故障标志 |
    // |
    CSCTL0_H = 0; //锁定 CS 寄存器--- |
    }//
    
    
    *@brief 这是 main 函数
    *@param None
    *@Return None
    */
    void main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    //初始化时钟
    //clock_init();
    
    P8DIR = 0xFF; //端口8作为输出
    P8OUT = 0x00; //端口8为低输出
    
    //初始化用于 SPI 操作的 USCI_B1
    spi_b_init ();
    
    //配置 GPIO
    spi_b_gpio_init ();
    
    //禁用 GPIO 上电默认高阻抗模式以激活
    //先前配置的端口设置
    PM5CTL0 &=~LOCKLPM5;
    
    UCB1TXBUF = 0xC0 | SPI_READ_BIT; //发送字符| R/W 位
    
    uint16_t SPI_TIMEOUT = SPI_TIMEOUT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI -1传输失败\n");
    }
    
    uint8_t 索引= 0U;
    uint16_t received_data[64];
    
    for (index=0U;index<64U;index++)
    {
    UCB1TXBUF = 0x55; //发送字符
    
    SPI_TIMEOUT = SPI_TIMEOUT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI %u 发送失败\n"、索引);
    }
    
    Received_data[index]= UCB1RXBUF;
    }
    
    //WHO _AM_I = UCB1RXBUF;
    
    P8OUT = 0xFF; //端口8作为高输出
    
    printf ("正在退出 main \n");
    
    return;
    }
    
    //
    *@brief 配置 USCI_B1 SPI GPIO 操作
    *@param None
    *@return None
    */
    void SPI_b_GPIO_init (void)
    {
    P5SEL1 &=~(BIT0 | BIT1 | BIT2 | BIT3);// USCI_B1 SCLK、MOSI、
    P5SEL0 |=(BIT0 | BIT1 | BIT2 | BIT3);// STE 和 MISO 引脚
    PJSEL0 |= BIT4 | BIT5;
    }
    
    //
    *@将 USCI_B1简要配置为 SPI 操作
    *@param 无
    *@返回无
    */
    void SPI_b_init (void)
    {
    UCB1CTLW0 = UCSWRST; //将状态机复位--- |
    //|
    UCB1CTLW0 &=~(UCCKPH); //|
    UCB1CTLW0 |= UCCKPL; //无效状态为高电平 |
    UCB1CTLW0 |= UCMSB; // MSB 优先 |
    UCB1CTLW0 |= UCMST; //主模式 |
    UCB1CTLW0 |= UCMODE_2; 在 UCxSTE = 0时启用// 4引脚 SPI 从器件|
    UCB1CTLW0 |= UCSYNC; //同步模式 |
    UCB1CTLW0 |= UCSTEM; // STE 为从机生成使能信号 |
    UCB1CTLW0 |= UCSSEL_SMCLK;// SMCLK |
    //|
    UCB1BRW = 0x01; ///1 |
    //|
    UCB1CTLW0 &=~UCSWRST; //操作释放-------------------------------------------------------
    |}
    

    以及从逻辑分析仪采集的结果:

    https://www.dropbox.com/s/8ne15zj3o2ps8p7/0xC0.logicdata?dl=0

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

    我先前发送的文件可以由逻辑分析仪提供。 它具有如下捕获

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    PNG 中的分辨率并不能真正显示杂散 MOSI 脉冲是否消失、但它应该消失。 (我没有您的逻辑分析仪、因此我不能自己欺骗信号。)

    至少很明显、该器件能够产生非零值。 右下角的结果看起来不是很合适--即使 MOSI 数据看起来也是倾斜的,这是以前没有的。 您可能需要重新检查 Analysis 参数。 (注意:UCCKPH=0对应于 CPHA=1。)

    您在 Received_data[]数组中得到了什么? 这里没有什么大的神秘--我预计在那里的某个地方找到一个0x33,也许是移位/反转/涂片,大概不在元素[15]中。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    需要检查的其他事项:

    1) 1)您的接线有多长时间? 如果它们的长度可能超过3英寸、请尝试降低 SPI 速度。
    2) 2)您的逻辑分析仪探头连接在哪里? 如果它们位于 MCU 板引脚上、请尝试在分线板引脚处进行探测。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    好的、我已经将 CPHA 设置为1。 以下是 received_data 数组的内容:

    我能够以 CSV 格式导出逻辑分析仪捕获的数据。 以下是其链接:

    https://www.dropbox.com/s/jj9c1w8kfm18ccv/Capture_0xC0.csv?dl=0

    我的接插导线长度约为6英寸。 加速计能够以最大10MHz 的频率进行通信、我将 SPI 时钟设置为1MHz。 我最初在 MCU 进行探测。 如果我将它们切换到分线板、我 看不到任何变化。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    降低 SPI 速度不适用于器件、而是用于接线。 较慢的 SPI 更容易原谅长的导线、可疑的焊点和上拉电阻。

    从开始、假设 BRW=4 (250kHz)、然后是20 (50kHz)、再是50 (20kHz)、并观察行为的任何变化。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我尝试使用您建议的波特率来降低 SPI 通信速度、但行为没有改变。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    那么、20kHz 时 Received_data[]看起来是相同的?

    同样、我仍然怀疑有电气问题。 如果您有备用接插线、那么现在就试一下了。

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

    是的、接收到的数据看起来是相同的。 另一方面、如果我尝试使用模拟发现或海盗总线与同一加速计进行通信、我将获得正确的数据。 是的、这是一个商业分线板。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很好。 (虽然我并不认为芯片损坏了。) 您的 Bus Pirate 设置有何不同? 波形有何不同?

    >是的、这是一个商业分线板。
    哪一个? 我至少知道其中四个(完全不同)。

    顺便提一下:您提到您使用的是 FR5994 Launchpad、但 P5.3不可用。 我的 LaunchPad 在 J2上暴露了 P5.3。 我们是否看到了相同的电路板?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bruce、很抱歉迟到了。

    问题出在加速计 LIS3DSH。 它仅正确地重新过帐了世卫组织_AM_I 寄存器。 稍后、当我尝试向其写入一些测试数据时、它仍然总是返回0。 现在我使用的 是 Kionix KX122-1037加速计、SPI 驱动器工作正常。

    更新了 SPI 驱动器:

    /*
    文件:spi.c
    *创建日期:2017年9月12日
    * 作者:Anand
    */
    
    //***** 包括*****
    #include 
    #include 
    #include 
    #include "msp430fr5994.h"
    
    //***** 定义了*****
    #define SPI_TIMEOUT 1234
    #define SPI_READ_BIT 0x80
    #define SPI_WRITE_BIT 0x7F
    
    void Delay (void)
    {
    静态 uint16_t 计数器= SPI_TIMEOUT;
    
    while (计数器>0)
    {
    计数器--;
    }
    }
    
    //*
    @简要配置 USCI_B1 SPI GPIO 操作
    *@param None
    *@return None
    */
    void SPI_b_GPIO_init (void)
    {
    P8DIR = 0xFF; //端口8作为 P8.3上 CS 的输出
    
    P5SEL1 &=~(BIT0 | BIT1 | BIT2 | BIT3);// USCI_B1 SCLK、MOSI、
    P5SEL0 |=(BIT0 | BIT1 | BIT2 | BIT3);// STE 和 MISO 引脚
    PJSEL0 |= BIT4 | BIT5;
    
    /*
    P5DIR |=(BIT0 | BIT2);
    
    //启用 SOMI 输入上的上拉电阻
    P5REN |= BIT1;
    P5OUT |= BIT1;
    *
    
    //加速计中断将出现在 P4.1上
    P7SEL0 &=~(BIT3); // P4.1作为 GPIO
    P7SEL1 &=~(BIT3); // P4.1作为 GPIO
    P7DIR &=~(BIT3); // P4.1 SEL 作为输入
    P7IE |= BIT3; //在 P4.1上启用中断
    P7IES &=~(BIT3); //上升沿
    P7IFG &=(~BIT3); //清除 P7.3的中断标志;
    }
    
    //
    *@将 USCI_B1配置为 SPI 操作
    *@param 无
    *@返回无
    */
    void SPI_b_init (void)
    {
    UCB1CTLW0 = UCSWRST; //将状态机复位--- |
    UCB1CTLW0 |=(UCCKPH); //||
    UCB1CTLW0 |= UCMSB; // MSB 优先 |
    UCB1CTLW0 |= UCMST; //主模式 |
    UCB1CTLW0 |= UCMODE_2; 在 UCxSTE = 0时启用// 4引脚 SPI 从器件|
    UCB1CTLW0 |= UCSYNC; //同步模式 |
    UCB1CTLW0 |= UCSTEM; // STE 为从机生成使能信号 |
    UCB1CTLW0 |= UCSSEL_SMCLK;// SMCLK |
    //|
    UCB1BRW = 1; ///x |
    //|
    UCB1CTLW0 &=~UCSWRST; //操作释放------------------------------------------------------- |
    }/*
    
    
    @简介此函数从 LIS3DSH 加速计读取8位寄存器
    *@param 寄存器地址待读取
    * 指向用于存储寄存器内容的变量的指针
    *@如果函数成功执行*则返回 True
    如果函数失败*/
    
    bool SPI_b_read (uint8_t register_address、uint16_t * register_content)
    {则为 false
    P8OUT = 0x00; //端口8为低输出
    
    UCB1TXBUF = REGISTER_ADDRESS | SPI_READ_BIT;
    
    uint16_t SPI_TIMEOUT = SPI_TIMEOUT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI reg 地址发送失败\n"\});
    返回 false;
    }
    
    delay(); //延迟
    
    UCB1TXBUF = 0xFF; //虚拟字节
    
    SPI_TIMEOUT = SPI_TIMEOUT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI reg 内容传输失败\n"\});
    返回 false;
    }
    
    * register_content = UCB1RXBUF;
    
    P8OUT = 0xFF; //端口8作为高输出
    
    返回 true;
    }
    
    //
    *@brief 此函数从 LIS3DSH 加速计*
    @param 寄存器中读取8位寄存器要读取
    的地址* 指向用于存储寄存器内容的变量的指针
    *@如果函数成功执行*则返回 True
    如果函数失败、则为 false
    *
    / bool SPI_b_write (uint8_t register_address、uint8_t register_content)
    {
    P8OUT = 0x00; //端口8为低输出
    
    uint16_t SPI_TIMEOUT = SPI_TIMEOUT;
    
    UCB1TXBUF = REGISTER_ADDRESS 和 SPI_WRITE_BIT;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI reg 地址发送失败\n"\});
    返回 false;
    }
    
    delay(); //延迟
    
    SPI_TIMEOUT = SPI_TIMEOUT;
    
    UCB1TXBUF = register_content;
    
    while (((UCB1STATW 和 UCBUSY)&&(SPI_TIMEOUT > 0))
    {
    SPI_TIMEOUT--;
    }
    
    if (SPI_TIMEOUT = 0)
    {
    printf ("SPI reg 内容传输失败\n"\});
    返回 false;
    }
    
    P8OUT = 0xFF; //端口8作为高输出
    
    返回 true;
    }