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.

[参考译文] MSP430F2013:NSP430F2013 + nRF24L01 SPI 通信问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/824662/msp430f2013-nsp430f2013-nrf24l01-spi-communication-issue

器件型号:MSP430F2013

您好!

我已经将一个 MSP430F2013与一个 nRF24L01模块连接。 SPI 设置都正确且工作正常、因为我能够写入和读取射频模块的寄存器。

但是、当来自另一个射频模块的数据到达时、我无法读取它。 它报告所有零。 无论是 MSP 侧还是射频模块侧的问题、我都不会感到惊讶。

 我使用的硬件是- ezMSP430开发套件。 是否有人遇到过类似的问题?

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

    如果可以、发布用于读取 FIFO 的代码。 通常、这与寄存器读取代码是分开的、有时它所采用的只是一个拼写错误。

    我模糊地回顾、每个事务的第一个 Rx 字节(通常被忽略)是一个状态字节。 该零点也是吗?

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

    您好、Bruce、

    感谢您的回答!  状态字节正在被正确读取、它只是被读取为零的数据。 下面是供您参考的代码,请原谅一些愚蠢的事情,比如使用循环来获得延迟,我针对 原型执行了快速而肮脏的实施:)一旦 RF 部件被清除,它就会被清理。

    /*
     *文件名:main.c
     *
     *



    #include
    #include "types.h"


    //nRF24L01寄存器地址-总计23 (十进制)/0x17 (十六进制)
    //------------------------------------------
    #define REG_CONFIG         0x00   //配置:屏蔽中断- RX DR、TX DS 和 MAX RT over、启用 CRC、CRC 类型、PWR UP、PRIM_RX/TX
    #define REG_EN_AA          0x01   //启用自动 ACK
    #define REG_EN_RXADDR      0x02   //启用 RX 管道
    #define REG_SETUP_AW       0x03   //设置地址宽度- 1到5个字节
    #define REG_SETUP_RETR     0x04   //设置编号 重试次数
    #define REG_RF_CH          0x05   //设置射频通道
    #define REG_RF_SETUP       0x06   //射频参数设置:PLL 锁定、数据速率、功率 LVL
    #define REG_STATUS         0x07   //状态- RX 数据就绪、TX 数据发送、MAX_RT、RX_P_NO (数据到达的 RX 管道)、TX_FULL
    #define REG_Observ_TX     0x08   //观察 TX 参数数据包丢失计数、重新发送 PKT 计数
    #define REG_CD             0x09   //载波检测
    #define REG_RX_ADDR_P0     0x0A   //默认0XE7E7E7
    #define REG_RX_ADDR_P1     0x0B   //默认值0XC2C2C2C2C2C2
    #define REG_RX_ADDR_P2     0x0C   //默认 LSB - OXC3,其余保持与 P1相同
    #define REG_RX_ADDR_P3     0x0D   //默认 LSB - 0xc4
    #define REG_RX_ADDR_P4     0x0E   //默认 LSB - 0XC5
    #define REG_RX_ADDR_P5     0x0F   //默认 LSB - 0XC6
    #define REG_TX_ADDR        0x10       //默认0XE7E7E7
    #define REG_RX_PW_P0       0X11   //有效载荷宽度管道0 -默认值0 MAX 32
    #define REG_RX_PW_P1       0x12   //与上面的 pipe1相同
    #define REG_RX_PW_P2       0x13   //与上面的 PIPE2相同
    #define REG_RX_PW_P3       0x14   //与上面的 PIPE3相同
    #define REG_RX_PW_P4       0X15   //与上述 PIPE4相同
    #define REG_RX_PW_P5       0x16   //与上述 PIPE5相同
    #define FIFO_STATUS        0x17   //状态- TX_REuse、TX_FULL、TX_EMPTY、RX_FULL、RX_EMPTY

    //寄存器读取和写入命令掩码
    //同时使用寄存器读取和写入命令,这些命令与5位命令一起使用
    //寄存器地址以获取相应的寄存器读/写命令
    ///---------------------------------------------------------
    #define R_REG_CMD_MASK     0x00
    #define W_REG_CMD_MASK     0x20

    //NRF24配置掩码
    ///------------------
    #define NRF_CFG_PWRUP   0x02
    #define NRF_CFG_PWRDN   0xFD

    #define NRF_CFG_Prim_RX 0xFE
    #define NRF_CFG_Prim_TX 0x01

    #define NRF_CFG_ENABLE_CRC     0x08
    #define NRF_CFG_DISABLE_CRC    0xF7

    #define NRF_CFG_CRC_PHASE_1B  0x04
    #define NRF_CFG_CRC_PHASE_2B  0xFB

    //射频收发器的地址宽度
    ///----------------------------
    #define NRF_AW_3B              0x01
    #define NRF_AW_4B              0x10
    #define NRF_AW_5B              0x11

    //nRF24L01芯片选择和启用掩码
    ///------------------------------
    #define NRF_CS_MASK            0xEF       //低电平有效位 P1.4
    #define NRF_CE_MASK            0x08       //高电平有效位 P1.3

    //启用自动确认掩码
    ///------------------


    //读取写操作指令
    ///----------------------------
    #define R_RX_PAYLOAD   0x61
    #define W_TX_PAYLOAD   0xA0
    #define FLUSH_TX       0xE1
    #define FLUSH_RX       0xE2
    #define REUSE_TX_PL    0xE3
    #define NOP            0xFF

    //数据包位置索引
    ///------------------
    #define ADDR_POS        0x01
    #define context_POS     0x02
    #define RMT_CMD_POS     0x03
    #define DATA_HI_POS     0x04
    #define DATA_LO_POS     0x05

    #define CMD_OFF         0x00
    #define CMD_ON          0x01

    #define self_ADDR        0x01         //这是逻辑地址,每个从机不同
    #define broadcast_ADDR   0xFF         //这是广播地址,表示所有从机都应对数据执行操作。
    #define ADDR_width       0x05         //使用5字节地址

    主灯发出//远程命令
    ///----------------------------
    #define RMT_CMD_BTN_State_Change 0x01
    #define RMT_CMD_SET_Brightness   0x02

    /*全球定义*/
    //--------
    unsigned char g_rxBuf[8];                 //全局缓冲器可接收来自 NRF 模块的所有内容,大小适合最大有效负载长度
    unsigned char g_txBuf[8];                 //global buffer、用于将所有内容发送到 NRF 模块、大小适合最大有效载荷长度
    unsigned char g_payloadBuf[8];            //global buffer、用于保存从主器件接收到的数据、大小适合最大有效载荷长度


    //由于我们将使用逻辑寻址,所有从属节点将具有相同的物理地址,但有效负载将是
    //包含用于区分各个节点的逻辑地址
    const unsigned char g_txAddress[6]={"10000"};
    const unsigned char g_rxAddress[6]={"20000"};


    uint8  g_datalelength = 1;                  //长度包括命令字节。 因此、最小值为1
    uint8  g_transfer_complete = 0;           //表示 MSP 和无线电之间的 SPI 传输完成
    uint8  g_data_ready = 0;
    uint8  g_buf_index = 0;
    uint8  g_init_done = 0;
    const uint8 g_payloadWidth = 7;            //最大有效载荷大小为32字节,但我们的数据仅为7字节。

    //函数原型
    //--------
    void Init_Port1 (void);
    void Init_SPI (void);
    void Init_PWM (void);
    void Init_Radio (void);
    void process_Master_Command (void);
    void Radio_CE_Enable (void);
    void Radio_CE_Disable (void);                        //停止 SPI 通信
    void Radio_CS_Enable (void);
    void Radio_CS_Disable (void);                        //停止 SPI 通信
    void Radio_WriteRegister (UINT8 regName、UINT8长度);
    void Radio_ReadRegister (uint8 regName、uint8 len);


    /**
     * main.c
     *
    int main (空)

     volatile unsigned int i;

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

     //首先初始化内部外设
     init_Port1();
     init_spi();
     init_pwm ();

    /*在此处启用常规中断,因为否则我们将无法使用
     * Radio_Init 中的 SPI 中断!!
     *

     _BIS_SR (GIE);

     init_Radio();


     while (1)
     {
         unsigned int i;
         //if (g_data_ready){                      //interrupt -data 已到达、已注释为使用轮询模式进行测试、因为 IRQ 不会变为低电平:(
         for (i=0;i<0x1ff;i++);

             Process_Master_Command ();
           // g_data_ready = 0;
             P1OUT &=~BIT0;
         //}
     }



    //中断服务例程
    ///------------------

    // USI 中断服务例程
    #if defined (__TI_Compiler_version__)|| Defined (__IAR_systems_ICC__)
    #pragma vector=USI_vector
    _interrupt void universal_serial_interface (void)
    #Elif defined (_GNU_)
    void __attribute__((interrupt (USI_vector))) universal_serial_interface (void)
    其他
    错误编译器不受支持!
    #endif

       //将接收到的数据读出到缓冲区中,
       //在它被下一个写入前
       G_rxBuf[g_buf_index]= USISRL;

       //检查是否是上电后的第一次或者是否正在进行事务处理
       g_datalelength --;
       if (g_datalelength = 0){
           G_buf_index = 0;
           G_TRANSFER_COMPLETE = 1;              //传输完成
           if (USICTL1 & 0x01)
               USICTL1 &=~USIIFG;
       }
       否则{ //需要发送更多数据
           G_buf_index++;
           USISRL = g_txBuf[g_buf_index];
           USICNT = 8;                      //重载计数器
       }



    //Port1 GPIO 引脚中断服务例程
    #pragma vector = Port1_vector
    _interrupt void InterruptVectorPort1 ()

           P1IFG &=~BIT1;                    //清除中断标志
           P1OUT |= BIT0;
           G_DATA_READY = 1;                    //主器件已传入


    //中断服务例程结束


    //此处显示所有功能代码

    /
     *函数:Init_Port1
     *此函数将给定数量的字节写入指定的寄存器
     在 nRF24L01内通过 SPI 总线
     (二 /
    空 Init_Port1 (空)


       //位配置
       // P1.7::P1.6:P1.5:P1.4:P1.3:P1.2:P1.1:P1.0
       //输出 ::输入  ::输出 :: 输出 ::输出 ::输入::  输出
       // MOSI:::MISO:SCK ::CSn :CE  :PWM ::IRQ :LED

       P1DIR |= BIT4 + BIT3 + BIT2 + BIT0;        // P1.4、P1.3、P1.2和 P1.0输出
       P1REN |= BIT4;//+ BIT1;                      //为 P1.4 (CSn)和 P1.1 (IRQ)启用上拉
       P1IE |= BIT1;                              //启用 port1.1中断
       P1IES |= BIT1;                             //高到低边沿或下降边沿,因为 nRF24的 IRQ 信号为低电平有效
       //初始状态设置
       P1OUT |= BIT4;                             //驱动高电平 P1.4 - CSn 低电平有效
       P1OUT &=~BIT3;                            //将 P1.3驱动为低电平、CE 为高电平有效
       P1OUT &=~BIT2;                            //将 P1.2驱动为低电平、MOSFET 默认处于关闭状态
       P1OUT &=~BIT0;                            //将 P1.0驱动为低电平、LED 为高电平有效


    /
     *函数:Radio_CE_Enable
     *此函数将给定数量的字节写入指定的寄存器
     在 nRF24L01内通过 SPI 总线
     (二 /
    空 Init_SPI (空)

     USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE;//端口、SPI 主控
     USICTL1 |= USIIE + USICKPH;             //计数器中断、标志保持置位、nRF24所需的时钟相位为1

     USICKCTL = USIDIV_4 + USISSEL_2;         ///16 SMCLK
     USICTL0 &=~USISWRST;                    // USI 被释放以运行



    /
     *函数:Init_PWM
     *此函数将给定数量的字节写入指定的寄存器
     在 nRF24L01内通过 SPI 总线
     (二 /
    空 Init_PWM (空)

    #if 0
         P1DIR |= 0x04;                           // P1.2
         P1SEL |= 0x04;                           // P1.2配置为备用功能1.
         CCR0 = 51-1;                            // PWM 周期
         CCTL1 = OUTMOD_7;                        // CCR1复位/置位
         CCR1 = 384;                              // CCR1 PWM 占空比
         TACTL = tassel_2 + MC_1;                 // SMCLK、向上计数模式
    #endif


    /
     *函数:Config_Radio
     *此函数将给定数量的字节写入指定的寄存器
     在 nRF24L01内通过 SPI 总线
     (二 /
    空 Init_Radio (空)

      unsigned int i;
      RADIO_CS_Disable ();


       RADIO_ReadRegister (((UINT8) REG_CONFIG、2);
       G_txBuf[1]= 0x01;
       RADIO_WriteRegister (((UINT8) REG_CONFIG、2);       //PWR_UP = false、MODE = PRIM_RX
       for (i = 0xff;i;i--);
       RADIO_ReadRegister (((UINT8) REG_CONFIG、2);

       G_txBuf[1]= 0x03;
       RADIO_WriteRegister (((UINT8) REG_SETUP_AW、2);     //地址宽度-5字节
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_SETUP_AW、2);

       for ( i = 0;<ADDR_WIDTH ;i++ ){
           G_txBuf[i+1]= g_txAddress[i];
       }
       RADIO_WriteRegister ((((UINT8) REG_TX_ADDR、6);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_TX_ADDR、6);

       RADIO_WriteRegister ((((UINT8) REG_RX_ADDR_P0、6);    //这似乎有点令人困惑、但 Tx 地址和 Rx 管道0地址是相同的
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_RX_ADDR_P0、6);


       G_txBuf[1]= 0x07;                         //将有效载荷大小设置为7字节
       RADIO_WriteRegister ((((UINT8) REG_RX_PW_P0、2);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_RX_PW_P0、2);

       for ( i = 0;i< ADDR_width;i++){
               G_txBuf[i+1]= g_rxAddress[i];
           }
       RADIO_WriteRegister ((((UINT8) REG_RX_ADDR_P1、6);//和 Rx 管道1地址为
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_RX_ADDR_P1、6);

       G_txBuf[1]= 0x07;
       RADIO_WriteRegister ((((UINT8) REG_RX_PW_P1、2);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_RX_PW_P1、2);

       G_txBuf[1]= 0x00;
       RADIO_WriteRegister (((UINT8) REG_EN_AA、2);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_EN_AA、2);

       G_txBuf[1]= 0x03;
       RADIO_WriteRegister ((((UINT8) REG_EN_RXADDR、2);
       for (i = 0xff;i;i--);

       G_txBuf[1]= 0x5F;
       RADIO_WriteRegister (((UINT8) REG_SETUP_RETR、2);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_SETUP_RETR、2);

       G_txBuf[1]= 0x4C;                          //选择射频通道76
       RADIO_WriteRegister (((UINT8) REG_RF_CH、2);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_RF_CH、2);

       G_txBuf[1]= 0x07;                          //选择射频数据速率1Mbps 和功率0dBm
       RADIO_WriteRegister (((UINT8) REG_RF_Setup、2);
       for (i = 0xff;i;i--);
       RADIO_ReadRegister ((((UINT8) REG_RF_Setup、2);

       RADIO_WriteRegister (((UINT8) FLUSH_TX、1);
       for (i = 0xff;i;i--);
       RADIO_WriteRegister (((UINT8) FLUSH_RX、1);

       G_txBuf[1]= 0x43;                         //仅配置 RX_DR 中断
       RADIO_WriteRegister (((UINT8) REG_CONFIG、2); //PWR_UP = true、MODE = PRIM_RX
       for (i = 0xff;i;i--);
       RADIO_ReadRegister (((UINT8) REG_CONFIG、2);

       RADIO_CE_Enable ();                         //启动接收模式- PRIM_RX


    /
     *函数:Radio_ReadPayload
     *此函数读取从主设备发出的用于打开/关闭 LED 的命令消息
     或调节亮度
     *参数:
     (二 /
    unsigned int Radio_ReadPayload (空)

       unsigned char status;
       unsigned int i;

       RADIO_ReadRegister (REG_STATUS、2);
       状态= g_rxBuf[0];

       if (status & 0x40)                               //if data received:RX_DR 被置位、
       {
           if (status & 0x02){                          //pipe number = 1。
               //现在读取有效载荷
               G_txBuf[0]= R_RX_PAYLOAD;
               G_datalelength = 8;
               USISRL = g_txBuf[0];
               USICNT = 8;
               while (!g_transfer_complete){;}
               对于(i = 0;i < g_payloadWidth;i++){
                   G_payloadBuf[i]= g_rxBuf[i+2];            //将内容传输到有效负载寄存器、因为 Tx 缓冲区很快就会被覆盖。
               }

               G_txBuf[1]=状态| 0x70;                //复位中断标志
               RADIO_WriteRegister (REG_STATUS、2);
               for (i = 0;i< 0xff;i++);
               返回 g_payloadWidth;
           }
           返回0;
       }
       其他
           返回0;


    #if 0
    /
     *函数:Radio_SendPayload
     *此函数向主器件发送消息、如灯的当前状态、
     或亮度级别。 解决方案。
     (二 /
    unsigned int Radio_SendPayload (nrf_WriteTypeDef writeType、unsigned char* txBuf、unsigned int numBytes)

       //现在我们没有任何东西要传输到主设备,因此没有实现
       返回0;


    #endif

    /
     *函数:Radio_CS_Enable
     *此函数将芯片选择信号置为有效以启用对 nRF24芯片的 SPI 读取/写入
     *参数:无
     *返回:无
     (二 /
    void Radio_CS_Enable()

       //将 CSn 引脚驱动为低电平;
       P1OUT &=~BIT4;


    /
     功能:Radio_CS_Disable
     *此函数将芯片选择信号置为无效以禁用对 nRF24芯片的 SPI 读取/写入
     *参数:无
     *返回:无
     (二 /
    void Radio_CS_Disable()

       //将 CSn 引脚驱动为高电平;
           P1OUT |= BIT4;


    /
     *函数:Radio_CE_Enable
     *此函数将芯片使能信号置为有效以控制传输或接收
     *在 Prim_TX 模式下、我们将 CE 线路保持在低电平、直到我们希望发送某个内容。 进行选择
     *为了发送、我们将负载转储到 TX_PLD 寄存器中并将该引脚置为 短路状态
     *持续时间。
     *在 PRIM_RX 模式下、该引脚必须始终保持高电平才能监听传输。
     *参数:无
     *返回:无
     (二 /
    void Radio_CE_Enable()

       //将 CSn 引脚驱动为低电平;
       P1OUT |= BIT3;


    /
     功能:Radio_CE_Disable
     *此函数将给定数量的字节写入指定的寄存器
     在 nRF24L01内通过 SPI 总线
     (二 /
    void Radio_CE_Disable ()

       //将 CSn 引脚驱动为高电平;
           P1OUT &=~BIT3;


    /
     *函数:Radio_ReadRegister
     *此函数从指定寄存器读取给定数量的字节
     在 nRF24L01内通过 SPI 总线。 在这里、我们只需启动操作
     *主传输发生在 USI 中断服务例程内
     *我们始终使用全局 g_txBuff 缓冲区进行传输
     (二 /
    空 Radio_ReadRegister (UINT8 regName、UINT8 len)

       unsigned int i;
       RADIO_CS_Enable();                                 //启动 SPI 通信
       对于(i = 0;i < 128;i++);
       G_TRANSFS_COMPLETE = g_Buf_INDEX = 0;             //将标志设置为 false
       G_txBuf[0]= regName |(UINT8) R_REG_CMD_MASK;      //使用寄存器地址设置寄存器读取屏蔽
       G_datalelength = len;                                //要传输的字节数
       USISRL = g_txBuf[0];                               //将第一个字节加载到 USI 数据寄存器中
       USICNT = 8;                                        //加载位数来启动传输
       while (!g_transfer_complete)
       {  ; }//wait                                           for the flag to be set (等待标志设置)
       G_TRANSFER_COMPLETE = 0;
       RADIO_CS_Disable ();
       对于(I = 0;I < 128;I++);                          //停止 SPI 通信




    /
     *函数:Radio_WriteRegister
     *此函数将给定数量的字节写入指定的寄存器
     在 nRF24L01内通过 SPI 总线
     *我们始终使用全局 g_txBuff 缓冲区进行传输
     (二 /
    空 Radio_WriteRegister (UINT8 regName、UINT8 len)

       unsigned int i;
       RADIO_CS_Enable();                        //启动 SPI 通信
       for (i = 0x7f;i;i--);
       G_TRANSFS_COMPLETE = g_Buf_INDEX = 0;
       G_datalelength = len;//将标志设置为 false
       G_txBuf[0]= regName |(UINT8) W_REG_CMD_MASK;
       USISRL = g_txBuf[0];
       USICNT = 8;                 //加载位数来启动传输
       while (!g_transfer_complete)
       {  ; }//wait                                    for the flag to be set (等待标志设置)
       G_TRANSFER_COMPLETE = 0;
       RADIO_CS_Disable ();                        //启动 SPI 通信
       for (i = 0x7f;i;i--);



    /
     *函数:Process_Master_Command
     *此函数处理从主器件接收到的命令。
     *命令可以是打开/关闭类型和调光级别设置
     (二 /
    void proc_Master_Command (void)

       uint8 addr = g_rxBuf[ADDR_POS];

       if (!Radio_ReadPayload()){
           if ((addr =broadcast_ADDR)||(addr =self_ADDR))  //如果它是宽幅广播消息
               {
                   switch (g_payloadBuf[RMT_CMD_POS]){

                   案例1:
                       if (g_rxBuf[DATA_LO_POS]== CMD_ON)
                           P1OUT |= BIT2;                 //打开灯
                       其他
                           P1OUT &=~BIT2;                //关闭灯
                       中断;
                   案例2:

                       中断;

                   }
               }
       }



    /
     *函数:LED_BrightnessControl
     *此函数根据从主器件接收到的设置来改变 PWM 占空比。
     *亮度将转换为 PWM
     (二 /
    void LED_BrightnessControl (内部亮度)

       //to do

    此致

    Sreenivasa Chary

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

    您好、Sreenivasa、

    为了检查问题是在 MSP430侧还是在 NRE24L01侧、您可以参考代码示例、其中 msp430x20x3_USI_02、msp430x20x3_USI_03、msp430x20x3_USI_04 和  msp430x20x3_USI_05 都是与 SPI 接口相关的代码示例。

    http://dev.ti.com/tirex/explore/node?node=AP2kp.Wkb-aPCeyAi0c3ag__IOGqZri__LATEST

    此致

    Johnson

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

    您似乎忘记了在 R_RX_PAYLOAD 请求周围将 CS 置为有效/取消置为无效。 这可能会导致您描述的症状。

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

    您好、Bruce、

    感谢评论!! 它解决了问题。 我没有提出 CSn 线。   在寄存器读取和写入函数中、我添加了 CS 使能和禁用调用、因此状态寄存器读取工作正常。

    此致

    Sreenivasa Chary