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.

[参考译文] EVM430-FR6047:SPI 接口示例程序

Guru**** 2577385 points
Other Parts Discussed in Thread: EVM430-FR6047, MSP430FR6047

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/860560/evm430-fr6047-spi-interface-sample-program

器件型号:EVM430-FR6047
主题中讨论的其他器件: MSP430FR6047

我尝试 使用 SPI 接口将 EVM430-FR6047连接到 Adafruit RFM9x、但我找不到任何库/代码示例。 我能够使用 AdafruIT/RadioHead (github.com/.../RadioHead)的 Arduino 库。 请传递您可能拥有的任何信息。

同时、我将尝试使用 TI 提供的代码示例之一 :msp430fr60x7_euscia0_spi_09、以确保了解 EVM430-FR6047上的 SPI 接口。 为了进行测试、我使用三线制 SPI 连接将两个 EVM430-FR6047连接在一起:

电路板1:       电路板#2:

P7.0 SPI_MOSI -> P7.1 SPI_MISO

P7.1 SPI_MISO --> P7.0 SPI_MOSI

P7.2 SPI_SCLK --> P7.1 SPI_SCLK

我肯定不是这方面的专家、但我的理解是、我应该能够将数据从一个板发送到另一个板、并使用调试器来查看结果。 该程序编译并运行、并且针对 TX 和 RX 信号触发 ISR、但接收到的数据(RXData)始终为0。  

以下是代码:

#include

volatile unsigned char RXData = 0;
volatile unsigned char TXData;

int main (空)

  WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器

   //配置 GPIO
   P7SEL1 &=~BIT0 |~BIT2 |~BIT3;// USCI_A1 SCLK、MOSI、MISO 引脚
   P7SEL0 |= BIT0 | BIT2 | BIT3;

   PJSEL0 |= BIT4 | BIT5;//用于 XT1

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

   // XT1设置
   CSCTL0_H = CSKKEY_H;//解锁 CS 寄存器
   CSCTL1 = DCOFSEL_0;//将 DCO 设置为1MHz
   CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;
   CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;//设置所有分频器
   CSCTL4 &=~LFXTOFF;
   操作
   {
      CSCTL5 &=~LFXTOFFG;//清除 XT1故障标志
      SFRIFG1 &=~OFIFG;
   } while (SFRIFG1 & OFIFG);//测试振荡器故障标志
   CSCTL0_H = 0;//锁定 CS 寄存器

   //为 SPI 操作配置 USCI_A0
   UCA1CTLW0 = UCSWRST;//**将状态机置于复位状态**
   UCA1CTLW0 |= UCMST | UCSYNC | UCCKPL | UCMSB;// 3引脚、8位 SPI 主器件
   //时钟极性高,MSB
   UCA1CTLW0 |= UCSSEL_ACLK;// ACLK
   UCA1BRW = 0x02;///2
   UCA1MCTLW = 0;//无调制
   UCA1CTLW0 &=~UCSWRST;//**初始化 USCI 状态机**
   UCA1IE |= UCRXIE;//启用 USCI_A0 RX 中断
   TXData = 0x1;//保留 TX 数据

   while (1)
   {
      UCA1IE |= UCTXIE;
      _bis_SR_register (LPM0_bits | GIE);// CPU 关闭、启用中断
      __DELAY_CYCLES (2000);//下次传输前延迟
      TXData++;//递增发送数据
   }

#if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
#pragma vector=EUSCI_A1_vector
_interrupt void USCI_A0_ISR (void)
#Elif defined (_GNU_)
void __attribute__((中断(EUSCI_A1_vector)) USCI_A1_ISR (void)
其他
错误编译器不受支持!
#endif

   开关(__evo_in_range (UCA1IV、USCI_SPI_UCTXIFG))
   {
   USCI_NONE 案例:中断;
   USCI_SPI_UCRXIFG 案例:
      RXData = UCA1RXBUF;
      UCA1IFG &=~UCRXIFG;
      _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//唤醒以设置下一个 TX
      中断;
   USCI_SPI_UCTXIFG 案例:
      UCA1TXBUF = TXData;//发送字符
      UCA1IE &=~UCTXIE;
      中断;
   默认值:break;
   }

我对该程序的原始版本进行了一些更改、因为它似乎是针对其他 EVM 板编写的。 原始代码将 P1.0、P1.2和 P1.3用于 SPI_SCLK、 SPI_MOSI、 SPI_MISO (按该顺序)。 EVM430-FR6047用户指南显示了这些连接的 P7.2、P7.0和 P7.1。 另一个修改是替换#include 具有#include 。  

我实际上尝试了几种组合:

  • 使用 P1.0、P1.2和 P1.3的原始代码
  • 使用原始#include

使用 UART 接口的类似测试与采样 msp430fr60x7_euscia0_UART_03.c 完美搭配、因此我不理解 SPI 接口为什么不工作。 下面是物理设置:

谢谢!

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

    >  UCA1CTLW0 |= UCMST | UCSYNC | UCCKPL | UCMSB;

    只有一侧可以是主器件。 主器件是驱动 SCK 的器件。 如果两侧都驱动时钟、则会出现一组总线争用、很难说出结果是什么。

    这并不重要,因为主器件实际上并不看时钟--当它完成时,它会停止8个脉冲。 这就是您的交易完成(每侧)的原因、即使没有真正传达任何信息。

    因此、您需要将一侧指定为从器件(UCMST=0)、并将 MISO 连接到 MISO、将 MOSI 连接到 MOSI。 从器件将根据主器件驱动的时钟运行。

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

    感谢您的快速响应-它帮助我更好地理解 SPI 概念。 遗憾的是、我仍然无法获取用于接收数据的接口。 在我的新设置中、主器件的代码是相同的。 这是从器件:

    #include
    int main (空)

       WDTCTL = WDTPW | WDTHOLD;              //停止看门狗计时器
       //配置 GPIO
       P7SEL1 &=~BIT2 |~BIT0 |~BIT1;       // USCI_A1 SCLK、MOSI、MISO 引脚
       P7SEL0 |= BIT2 | BIT0 | BIT1;

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

       // XT1设置
       CSCTL0_H = CSKKEY_H;                    //解锁 CS 寄存器
       CSCTL1 = DCOFSEL_0;                    //将 DCO 设置为1MHz
       CSCTL1 &=~DCORSEL;
       CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;
       CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;  //设置所有分频器
       CSCTL4 &=~LFXTOFF;
       操作
       {
           CSCTL5 &=~LFXTOFFG;               //清除 XT1故障标志
           SFRIFG1 &=~OFIFG;
       } while (SFRIFG1 & OFIFG);             //测试振荡器故障标志
       CSCTL0_H = 0;                          //锁定 CS 寄存器

       //为 SPI 操作配置 USCI_A1
       UCA1CTLW0 = UCSWRST;                   //**将状态机置于复位状态**
       UCA1CTLW0 |= UCSYNC | UCCKPL | UCMSB;  // 3引脚、8位 SPI 从器件
                                               //时钟极性高,MSB
       UCA1CTLW0 |= UCSSEL_SMCLK;            // ACLK
       UCA1BRW = 0x02;                        ///2
       UCA1MCTLW = 0;                         //无调制
       UCA1CTLW0 &=~UCSWRST;                 //**初始化 USCI 状态机**
       UCA1IE |= UCRXIE;                      //启用 USCI_A1 RX 中断
       _bis_SR_register (LPM0_bits | GIE);    //输入 LPM0、启用中断


    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=EUSCI_A1_vector
    _interrupt void USCI_A1_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((中断(EUSCI_A1_vector)) USCI_A1_ISR (void)
    其他
    错误编译器不受支持!
    #endif

       while (!(UCA1IFG&UCTXIFG));            // USCI_A0 TX 缓冲器准备就绪?
       UCA1TXBUF = UCA1RXBUF;                 //回显接收到的数据
    从器件上的 ISR 似乎永远不会触发。 (当我在最后一行上放置一个断点时、它永远不会在那里停止。) 在主器件的 ISR 中 、USCI_SPI_UCRXIFG 执行、但 RXData 始终为0。
    我将接线更改为:
    主器件        从器件
    SPI_MOSI P7.0 -> SPI_MOSI P7.0
    SPI_MISO P7.1 --> SPI_MISO P7.1
    SPI_CLCK P7.2 -> SPI_CLCK P7.2
     
    下面是一个快照:
    有什么想法吗? 谢谢!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我以前没有注意到两件事:

    >   P7SEL1 &=~BIT2 |~BIT0 |~BIT1;       // USCI_A1 SCLK、MOSI、MISO 引脚

    1) 1)这实际上不会更改 P7SEL1、因为"~"具有更高的优先级。  相反、它应该是:

    >   P7SEL1 &=~Ω(BIT2 | BIT0 | BIT1);       // USCI_A1 SCLK、MOSI、MISO 引脚
    (P7SEL1在复位时已经为0、因此该错误是无害的。 在其他情况下、它不会是。)  

    2)根据数据表(SLASEB7C)、表6-35、P7.0-3请参阅 UCA2、而不是 UCA1。 UCA1位于 P1.0-3上[表6-25/26]。 查看原理图(SLAR138B)、P1.0-3似乎与其他因素联系在一起。 遗憾的是、这可能意味着将源代码更改为使用 UCA2。  

    症状:您的从机不会做出反应,因为它从未看到任何 SCK。

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

    再次感谢您的快速响应。 我的修改(在主器件和从器件上从 UCA1更改为 UCA2)会编译并执行、而从器件上的 ISR 现在会成功触发。 但是从器件接收到的值似乎只是随机数、而不是主器件发送的值。 主器件还接收来自从器件的随机值。  

    以下是两个程序:

    主器件:

    //
    //  MSP430FR60xx 演示- eUSCI_A2、SPI 3线制主器件递增数据
    //
    //  说明:SPI 主设备使用3线制模式与 SPI 从设备通信。 令人惊叹
    //  数据由从0x01开始的主器件发送。 接收到的数据
    //  与之前的传输相同 TXData = RXData-1。
    //  USCI RX ISR 用于处理与 CPU 的通信、通常在 LPM0中。
    //  ACLK = 32.768kHz、MCLK = SMCLK = DCO ~1MHz。  BRCLK = ACLK/2
    //
    //
    //                  MSP430FR6047
    //                ------------
    //           /|\|             XIN|-
    //            |                 || 32KHz 晶振
    //            --|RST         XOUT|-
    //               |                |
    //               |            P7.0|->数据输出(UCA2SIMO)
    //               |                |
    //               |            P7.1|<-数据输入(UCA2SOMI)
    //               |                |
    //               |            P7.2|->串行时钟输出(UCA2CLK)
    //
    //  Evan Wakefield
    //  Texas Instruments Inc.
    //  2016年10月
    //  使用 IAR Embedded Workbench V6.50和 Code Composer Studio V6.2构建
    //
    #include
    #include
    volatile unsigned char RXData = 0;
    volatile unsigned char TXData;
    int main (空)

       WDTCTL = WDTPW | WDTHOLD;              //停止看门狗计时器
       GPIO_setAsOutputPin (GPIO_PORT_P1、GPIO_PIN0);      // LED1
       GPIO_setOutputLowOnPin (GPIO_PORT_P1、GPIO_PIN0);   // LED1
       //配置 GPIO
       P7SEL1 &=~Ω(BIT2 | BIT0 | BIT1);       // USCI_A2 SCLK、MOSI、MISO 引脚
       P7SEL0 |= BIT2 | BIT0 | BIT1;
       PJSEL0 |= BIT4 | BIT5;                 //用于 XT1
       //禁用 GPIO 上电默认高阻抗模式以激活
       //先前配置的端口设置
       PM5CTL0 &=~LOCKLPM5;
       // XT1设置
       CSCTL0_H = CSKKEY_H;                    //解锁 CS 寄存器
       CSCTL1 = DCOFSEL_0;                    //将 DCO 设置为1MHz
       CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;
       CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;  //设置所有分频器
       CSCTL4 &=~LFXTOFF;
       操作
       {
           CSCTL5 &=~LFXTOFFG;               //清除 XT1故障标志
           SFRIFG1 &=~OFIFG;
       } while (SFRIFG1 & OFIFG);             //测试振荡器故障标志
       CSCTL0_H = 0;                          //锁定 CS 寄存器
       //为 SPI 操作配置 USCI_A0
       UCA2CTLW0 = UCSWRST;                   //**将状态机置于复位状态**
       UCA2CTLW0 |= UCMST | UCSYNC | UCCKPL | UCMSB;// 3引脚、8位 SPI 主器件
                                               //时钟极性高,MSB
       UCA2CTLW0 |= UCSSEL_ACLK;             // ACLK
       UCA2BRW = 0x02;                        ///2
       UCA2MCTLW = 0;                         //无调制
       UCA2CTLW0 &=~UCSWRST;                 //**初始化 USCI 状态机**
       UCA2IE |= UCRXIE;                      //启用 USCI_A0 RX 中断
       TXData = 0x1;                          //保留 TX 数据
       while (1)
       {
           UCA2IE |= UCTXIE;
           _bis_SR_register (LPM0_bits | GIE);// CPU 关闭、启用中断
           __DELAY_CYCLES (2000);              //下次传输前延迟
           TXData++;                          //递增发送数据
       }
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=EUSCI_A2_vector
    _interrupt void USCI_A0_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((中断(EUSCI_A2_vector)) USCI_A2_ISR (void)
    其他
    错误编译器不受支持!
    #endif

       开关(__evo_in_range (UCA2IV、USCI_SPI_UCTXIFG))
       {
           USCI_NONE 案例:中断;
           USCI_SPI_UCRXIFG 案例:
               RXData = UCA2RXBUF;
               UCA2IFG &=~UCRXIFG;
               _BIC_SR_REGISTER_ON_EXIT (LPM0_BITS);//唤醒以设置下一个 TX
               中断;
           USCI_SPI_UCTXIFG 案例:
               UCA2TXBUF = TXData;                  //发送字符
               UCA2IE &=~UCTXIE;
               中断;
           默认值:break;
       }
    从属方:
    //
    //  MSP430FR60xx 演示- eUSCI_A2、SPI 3线从器件数据回波
    //
    //  说明:SPI 主设备使用3线制模式与 SPI 从设备通信。 令人惊叹
    //  数据由从0x01开始的主器件发送。 接收到的数据
    //  与之前的传输相同 TXData = RXData-1。
    //  USCI RX ISR 用于处理与 CPU 的通信、通常在 LPM0中。
    //  ACLK = 32.768kHz、MCLK = SMCLK = DCO ~1MHz。  BRCLK = ACLK/2
    //
    //
    //                  MSP430FR6047
    //                ------------
    //           /|\|             XIN|-
    //            |                 || 32KHz 晶振
    //            --|RST         XOUT|-
    //               |                |
    //               |            P7.0|->数据输出(UCA2SIMO)
    //               |                |
    //               |            P7.1|<-数据输入(UCA2SOMI)
    //               |                |
    //               |            P7.2|->串行时钟输入(UCA2CLK)
    //
    //  Evan Wakefield
    //  Texas Instruments Inc.
    //  2016年10月
    //  使用 IAR Embedded Workbench V6.50和 Code Composer Studio V6.2构建
    //
    #include
    volatile unsigned char RXData = 0;
    int main (空)

       WDTCTL = WDTPW | WDTHOLD;              //停止看门狗计时器
       //配置 GPIO
       P7SEL1 &=~Ω(BIT2 | BIT0 | BIT1);       // USCI_A2 SCLK、MOSI、MISO 引脚
       P7SEL0 |= BIT2 | BIT0 | BIT1;
       PJSEL0 |= BIT4 | BIT5;                 //用于 XT1
       //禁用 GPIO 上电默认高阻抗模式以激活
       //先前配置的端口设置
       PM5CTL0 &=~LOCKLPM5;
       // XT1设置
       CSCTL0_H = CSKKEY_H;                    //解锁 CS 寄存器
       CSCTL1 = DCOFSEL_0;                    //将 DCO 设置为1MHz
       CSCTL1 &=~DCORSEL;
       CSCTL2 = SELA_LFXTCLK | SELESS__DCOCLK | SELM_DCOCLK;
       CSCTL3 = DIVA__1 | DIVM_1 | DIVM__1;  //设置所有分频器
       CSCTL4 &=~LFXTOFF;
       操作
       {
           CSCTL5 &=~LFXTOFFG;               //清除 XT1故障标志
           SFRIFG1 &=~OFIFG;
       } while (SFRIFG1 & OFIFG);             //测试振荡器故障标志
       CSCTL0_H = 0;                          //锁定 CS 寄存器
       //为 SPI 操作配置 USCI_A2
       UCA2CTLW0 = UCSWRST;                   //**将状态机置于复位状态**
       UCA2CTLW0 |= UCSYNC | UCCKPL | UCMSB;  // 3引脚、8位 SPI 从器件
                                               //时钟极性高,MSB
       UCA2CTLW0 |= UCSSEL_SMCLK;            // ACLK
       UCA2BRW = 0x02;                        ///2
       UCA2MCTLW = 0;                         //无调制
       UCA2CTLW0 &=~UCSWRST;                 //**初始化 USCI 状态机**
       UCA2IE |= UCRXIE;                      //启用 USCI_A2 RX 中断
       _bis_SR_register (LPM0_bits | GIE);    //输入 LPM0、启用中断
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=EUSCI_A2_vector
    _interrupt void USCI_A2_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((中断(EUSCI_A2_vector)) USCI_A2_ISR (void)
    其他
    错误编译器不受支持!
    #endif

       while (!(UCA2IFG&UCTXIFG));            // USCI_A0 TX 缓冲器准备就绪?
       UCA2TXBUF = UCA2RXBUF;                 //回显接收到的数据
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我看不到任何明显的错误。 您是否有机会获得一个范围?

    您正在检查哪些内容以查看从器件正在接收随机数据? 随机有多大?

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

    再次感谢您的回答。 我必须购买一个逻辑分析仪、这样我就可以看到信号实际上是什么样的。 这将需要大约一周的时间。

    同时、我再次运行主器件和从器件、并记下从器件上接收到的值。 我在语句"UCA2TXBUF = UCA2RXBUF;"上的从器件 ISR 中放置一个断点、并注意到 UCA2RXBUF 的值  

    0xCF
    0xE5
    0x8B
    0xDF
    0xBC
    0x87
    0xA0
    (笑声)

    由于主器件不会被从器件上的调试器停止、我认为它会持续运行、因此第一个调试器之后的值显示为随机值并不奇怪。 但是、由于我首先启动了从器件、因此第一个数字应该是正确的:0x01。

    为了测试这个想法、我添加了一个数组、以便在多个值到达时尽快捕获它们:

    #define RXARRAYSIZE 10
    volatile unsigned char RXData = 0;
    volatile unsigned int rxArrayIndex = 0;
    unsigned char rxArray[RXARRAYSIZE]={0x0、0x0、0x0、0x0、0x0、 0x0、0x0、0x0、0x0、0x0 };
    int main (空)
      (笑声)
    _interrupt void USCI_A2_ISR (void)
    #Elif defined (_GNU_)
    void __attribute__((中断(EUSCI_A2_vector)) USCI_A2_ISR (void)
    其他
    错误编译器不受支持!
    #endif

       while (!(UCA2IFG&UCTXIFG));            // USCI_A2 TX 缓冲区准备就绪?
       if (rxArrayIndex < RXARRAYSIZE){
           rxArray[rxArrayIndex]= UCA2RXBUF;
           rxArrayIndex++;
       }
       否则{
           _nop();
       }
       UCA2TXBUF = UCA2RXBUF;                 //回显接收到的数据

    我关闭了两个板的电源,使用调试器重新启动从器件,并在_nop()上放置一个断点。 第一次上电主设备时、rxArray 几乎捕捉到我想要的内容:

    0x7f
    0x01
    0x02
    0x03
    0x04
    0x05
    0x06
    0x07
    0x08
    0x09

    它收到的第一个值是垃圾、但其余值是正确的。 不幸的是,这是它唯一的工作时间。  现在,当我再次尝试该过程(不更改任何代码)时,rxArray 通常包含随机值。 它是2的数倍:

    0xFC
    0x02
    0x04
    0x06
    0x08
    0x0A
    0x0C
    0x0E
    0x10
    0x12

    我认为、ISR 中等待 TX 缓冲区准备就绪的"while"循环可能会使事情减慢太多、但删除该语句没有帮助。 我还尝试更改主函数的延迟(从2000到10000)以减慢字符的速度、但从器件仍然收到大量垃圾。

       while (1)
       {
           UCA2IE |= UCTXIE;                  //启用 USCI_A0 TX 中断
           _bis_SR_register (LPM0_bits | GIE);// CPU 关闭、启用中断
           _DELAY_CYCLES (10000);              //下次传输之前的延迟
           TXData++;                          //递增发送数据
       }

    有关如何使 SPI 接口可靠工作的任何想法?

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

    我确信您已经厌倦了从我那里听到的内容、但我决定尝试4线 SPI 示例、认为可能还有其他一些组件(USS 模块?) 可能使用 SPI、这会导致冲突。 因此、我修改了4线制 SPI 主从采样(msp430fr60x7_euscia0_spi_11.c 和 msp430fr60x7_euscia0_spi_12.c)以在 P7和 EUSCI_A2上工作。

    结果令人鼓舞。 每次运行程序时、从器件都会以某种模式接收一系列值。 第一个值是随机的、但接收到的第二个值将是上一个值加1、加4、加16或其他一些数字。 我将包含以下代码。

    主器件:

    e2e.ti.com/.../3187.main.c

    从属方:

    e2e.ti.com/.../3187.main.c

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

    以下是一些始终为真的事情:

    1) 1)与主器件相比、从器件将始终关闭一个、因为在接收到第一个字节之前、它甚至听不到 SPI 正在运行。

    2) 2)从器件的调度非常严格、因为它的时序由主器件驱动-在下一个字节到达之前进行传输。 丢弃字节非常容易。 话虽如此、我本来希望主器件的2ms 延迟足够了。

    调试从站比较棘手(如您所见)、因为主站不知道它是否在那里。

    我建议尝试通过(a)保持主器件处于复位状态(按下按钮)使从器件复位(按下并释放)(c)让主器件运行(释放按钮)来使其保持同步。