NRF24L01 + RX模式和冲洗

时间:2018-08-12 16:49:57

标签: stm32 flush fifo receiver

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

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

问题与RX操作有关。

如上所述,

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

双方;

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

这是我用来从发送器获取数据的算法。 顺便说一句,我不使用IRQ引脚。

  1. 将CE设置为高
  2. 检查STATUS寄存器中的RX_DR位。如果值到达RX FIFO,则该位置1。如果是这样,请将CE调低以停止RX操作。 (数据表中, RX_DR位是数据就绪RX FIFO中断。在新数据到达RX FIFO时置位。)
  3. 使用数据表中描述的R_RX_Payload命令,并将数据分配给变量。
  4. 清除RX FIFO
  5. 清除状态寄存器中的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。

编辑:我的新问题与“刷新”命令有关。 我想在数据到达时刷新RX FIFO。在发送器发送数据时,我一直在读取寄存器,并且可以观察到有新数据到达RX FIFO,这意味着RX_DR位置1且RX_FIFO状态已更改。然后我关闭了发送并在接收端执行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();

}

任何建议,帮助和指导将不胜感激。 预先感谢。

3 个答案:

答案 0 :(得分:0)

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

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

  2. 双方通信((tx + rx)<---->(rx + tx))

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

第二次,禁用自动确认。

在此为第二模式编写一些步骤,

1>对于发送时的发送方:

a)冲洗变送器

b)清除tx_ds标志

c)传递写入有效载荷的命令

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芯片选择在读取有效负载或写入有效负载中起着至关重要的作用。

*

答案 1 :(得分:0)

对于RX模式问题,我可能会有所帮助,但是我不了解刷新操作。

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

通过新的数据包到达事件来声明RX_DR IRQ。处理该互操作的程序应为

1)读取有效载荷

2)清除RX_dR

3)读取FIFO_STATUS

4)如果FIFO中有更多可用负载,请重复步骤1。

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

答案 2 :(得分:0)

我对代码进行了一些更改。我现在正在尝试进行单向通信。因此,一侧仅是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;       }

读取有效负载的代码是:

    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位置1),然后连续读取0x02(表示将RX_DR位清除了)。我发送的数据是0x36。