【问题标题】:NRF24L01+ RX Mode and FlushNRF24L01+ RX 模式和刷新
【发布时间】:2019-01-19 12:11:51
【问题描述】:

我一直在尝试为 NRF24L01+ 编写自己的代码。我有一个问题,我无法解决它

作为接收器,我使用 STM32F103C8T6,作为发射器,我使用 Arduino Uno。

问题与RX操作有关。

正如我上面提到的,

作为接收器,我使用 STM32F103C8T6,作为发射器,我使用 Arduino Uno。

双方;

  1. 正在通过同一地址进行通信。
  2. 具有相同的 CRC 长度
  3. 不要使用增强模式
  4. 具有相同的地址宽度
  5. 具有相同的有效载荷宽度
  6. 具有相同的通信数据速率。 (1Mbps)

这是我用来从发射器获取数据的算法。 顺便说一下,我不使用 IRQ Pin。

  1. 设置 CE 高
  2. 检查 STATUS 寄存器中的 RX_DR 位。如果一个值到达 RX FIFO,则设置该位。如果是这样,将 CE 拉低以停止 RX 操作。 (数据表说 RX_DR 位是数据就绪 RX FIFO 中断。当新数据到达 RX FIFO 时断言
  3. 使用数据表中描述的 R_RX_Payload 命令并将数据分配给变量。
  4. 清除 RX FIFO
  5. 清除 STATUS 寄存器中的 RX_DR 位,(写入 1)

但它不起作用。

void RX_Mode()

{

ChipEnable_high(); // CE=1

//Check RX_DR bit. Wait until a value appears.
while(check)
{
    ReadRegister(REG_STATUS,1);

    if( (reg_data & 0x40) == 0x40 ){check = false;}         
}


ChipEnable_low(); // CE=0

csn_low(); //CSN=0
HAL_SPI_TransmitReceive(&hspi1, (uint8_t*)COMD_R_RX_PAYLOAD, &received_data, 1, 150); // Read the data
csn_high(); // CSN=1

Flush_RX(); //Clear RX FIFO

// Clear RX_DR bit. (Write 1)
ReadRegister(REG_STATUS,1);
data2write = ( reg_data | 0x40); 
WriteRegister(REG_STATUS,data2write,1); 

CDC_Transmit_FS(&received_data,1); // Print the received data out.

}

当我在代码中禁用 while 循环时,我不断读取 0x0E。

编辑:我的新问题与 Flush 命令有关。 我想在数据到达时刷新 RX FIFO。在发送器发送数据时,我一直在读取寄存器,我可以观察到新数据到达 RX FIFO,这意味着 RX_DR 位已设置并且 RX_FIFO 状态已更改。然后我关闭tx并在rx端执行FLUSH_RX命令,无法刷新fifo。寄存器仍然说RX FIFO中有数据。

void Flush_RX()

{

csn_low();

HAL_SPI_Transmit(&hspi1, (uint8_t *)COMD_FLUSH_RX, 1, 150);

while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

csn_high();

}

我们将不胜感激任何建议、帮助和指导。 提前致谢。

【问题讨论】:

    标签: stm32 flush fifo receiver


    【解决方案1】:

    对于 RX Mode 问题,我可能会有所帮助,但我不知道 Flush 操作。

    在 NRF24L01+ 数据表的第 59 页上,它说

    RX_DR IRQ 由新的数据包到达事件断言。处理这种中断的程序应该是

    1)读取载荷

    2)清除 RX_dR

    3)读取 FIFO_STATUS

    4)如果 FIFO 中有更多可用的有效载荷,则重复步骤 1。

    能否请您使用 IRQ 引脚并检查是否发生中断。如果是这样,请执行上述步骤。

    【讨论】:

      【解决方案2】:

      我对我的代码进行了一些更改。我现在正在尝试进行单向通信。所以,一侧只有RX,另一侧只有TX。我正在应用数据表中第 59 页描述的步骤。

      void RX_Mode(){
              ChipEnable_high(); // receiver monitors for a data
      
              while( !(IRQ_Pin_Is_Low() && RXDR_Bit_Is_Set()) ); // Wait until IRQ occurs and RX_DR bit is set.
      
              ChipEnable_low(); // when the data arrives, bring CE low to read payload
      
              ReadPayload(); // read the payload
      
              ClearInterrupts(); // clear all interrupt bits
      
          // This while loop is to check FIFO_STATUS register, if there are more data in FIFO read them.
              while(check)
              {
      
                  ReadRegister(REG_FIFO_STATUS,1); 
      
                  if((reg_data & 0x01)==0x00) 
                  {   
                      ReadPayload();
                      ClearInterrupts(); // clear all interrupt bits
                  }
                  else 
                      check = false;              
              }       
      
              Flush_RX(); //Flush RX FIFO
              check = true;       }
      

      读取payload的代码是:

          void ReadPayload()
          {
          csn_low(); //CSN=0
          HAL_SPI_TransmitReceive(&hspi1, (uint8_t *)COMD_R_RX_PAYLOAD, &received_data ,1, 1500); // READ RX FIFO
          while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);
          CDC_Transmit_FS(&received_data,1); // print the received data out
          csn_high(); // CSN=1
           }
      

      但是;当我打开 tx 设备时,我读取 STATUS 寄存器的值为 0x42(意味着设置了 RX_DR 位)然后我连续读取 0x02(意味着 RX_DR 位被清除)。我发送的数据是0x36。

      【讨论】:

        【解决方案3】:

        PDF nRF24L01Pluss_Preliminary_Product_Specification_v1_0_1页码中提到了两种通信模式。 72,73,74。 请通过它。我使用带有外部中断的 stm32 微控制器。传递给 NRF 芯片的命令序列将取决于以下两种模式:

        1. 单向通信(tx 将发送,rx 将仅接收)

        2. 双方通信((tx+rx) (rx+tx))

        在第一种模式下,您必须启用自动确认,

        在 2nd 中,禁用自动确认。

        特此写下第二模式的一些步骤,

        1> 发送端同时发送:

        a)冲洗发射器

        b)清除 tx_ds 标志

        c)传递写入payload的命令

        d)填充有效载荷

        e)准备传输

        f)检查状态

        g)清除所有标志(maxtx,rx_dr,tx_ds)

        2>接收端同时接收:

        注意:接收器应始终处于接收模式。如果使用中断,则无需检查状态位。

        当中断到来时;

        a) 读取有效载荷

        b)检查状态

        c)清除 RX_DR 标志

        d)刷新 RX_FIFO

        e) 再次配置为接收器。

        试试这个

        谢谢你,一切顺利。

        *嗨

        对于单向通信,您必须启用自动确认, 最好在读取一个数据包后刷新接收器fifo。无论 Tx 正在发送什么数据,只需在串口或其他方法上检查它,因为如果有效载荷长度与 rx 中的预定义长度不匹配,那么 NRF 芯片上的 RX_DR 中断将不会发生,因此您将无法在 rx 端获取数据。 测试只启用一个管道,检查 rx 是否接收到数据。

        芯片使能和 SPI 芯片选择在读取有效负载或写入有效负载方面起着至关重要的作用。

        *

        【讨论】:

        • 感谢您的回复。我现在将使用第一种方法。我对第一种方法有一些疑问。对于 RX 模式,1. 据我了解,对于一种方式的通信自动确认,应根据数据表禁用。 2.正如我所说,我不使用中断引脚。我检查 RX_DR 位,如果它变高,我知道数据到达 RX FIFO,我写 1 来清除该位。这个可以吗? 3. MASK_RX_DR 位我需要做些什么吗? 4.我设置了管道号,然后我应该对地址做任何事情还是会自动识别相关寄存器中的地址?
        猜你喜欢
        • 2012-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-30
        • 1970-01-01
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        相关资源
        最近更新 更多