NRF24L01双向通讯不成功,请教

2020-01-13 18:34发布

本帖最后由 指端轻语 于 2013-5-24 00:20 编辑

好吧中午发的帖子没人理。我这么问吧

1、A模块通过无线模块向B模块发送一条指令,B接收到了之后将自己的一些数据发给A模块;
2、紧接步骤1,B模块也向A模块发送一条指令,A模块接收到之后做某个特定的动作;
3、重复以上两步骤

以上过程能成功么?
我现在遇到的问题是,1能成功,但是执行2步骤时需要连续重复3-4次执行才能成功,成功之后再进行1步骤又不会成功,多试几次又会成功·····很郁闷的说


据说这个问题是由于无线模块在发送完数据后还会一直不停地发送···我试了以下三种方法都不行
1.每次发送完设置ce=0也不行。
2.每次发送完让它成待机模式行不行。
3.每次发送完马上设成接收模式,接收完马上设成发送模式,也不行。

不会自动重发的问题吧,我都没建立自动重发功能
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
skype
1楼-- · 2020-01-13 22:33
一是A模块发发送时设置成自动重发有ACK模式,B模块设置成接收模式:
A:
        //3 使能AUTO ACK
        nrf24_Writer_REG(WRITE_REG + EN_AA, 0x01);                                                                      // Enable Auto.Ack:Pipe0
        //4 使能PIPE0
        nrf24_Writer_REG(WRITE_REG + EN_RXADDR, 0x01);                                                                  // Enable Pipe0
        //5 配置自动重发次数
        nrf24_Writer_REG(WRITE_REG + SETUP_RETR, 0x2f);                                                                 // 500us + 86us, 10 retrans...1a(0xff发射超时最大70MS,发射最小只要1MS)
B:
        //3 使能AUTO ACK
        nrf24_Writer_REG(WRITE_REG + EN_AA, 0x01);                                                                      // Enable Auto.Ack:Pipe0
        //4 使能PIPE0
        nrf24_Writer_REG(WRITE_REG + EN_RXADDR, 0x01);                                                                  // Enable Pipe0
A发射成功没有要看REG 0x07,如A模块启动发送后
void nrf24_Send_Data(int8_t *pbuf, uint8_t len)
{
        Standby_Mode_1();  //StandBy I模式
        //多字节写入是从低到高字节
        nrf24_Write_Buf(WRITE_REG + RX_ADDR_P0, (int8_t*)Tx_addr, TX_ADR_WIDTH);         // 装载接收端地址
        nrf24_Writer_REG(FLUSH_TX, 0x00);
        //写TX有效数据,1-32字节,写操作从字节0开始
        nrf24_Write_Buf(WR_TX_PLOAD, pbuf, len);                                                                                                         // Writes data to TX payload
        nrf24_Writer_REG(WRITE_REG + CONFIG, 0x0e);                                                                              // IRQ收发完成中断响应,16位CRC,主发送
        CE=1;                                                                                                                                                                                                                                           //置高CE,激发数据发送
}

下面就开始查询REG 0x07的状态,再根据状态做处理:
int8_t Get_RF_Status(void)
{
        uint8_t status;
        int8_t ret;
        status = nrf24_Read_REG(STATUS);
        if (status & 0x10)
        {//数据多次重发,无ACK
                nrf24_Writer_REG(FLUSH_TX, 0);
                nrf24_Writer_REG(FLUSH_RX, 0);
                ret = -1;    //再启动A模块发送数据
        }
        else if (status & 0x20)
        {//发送成功
                ret = 0;  //转到接收模式
        }
        else if (status & 0x40)
        {//收到数据
                ret = 1;//转到发送模式
        }
        status = nrf24_Read_REG(STATUS);
        nrf24_Writer_REG(WRITE_REG + STATUS, status);  
        return ret;
}
指端轻语
2楼-- · 2020-01-13 23:40
 精彩回答 2  元偷偷看……
skype
3楼-- · 2020-01-14 01:58

未命名.JPG (162.96 KB, 下载次数: 0)

下载附件

2013-5-23 23:28 上传


//发送代码:
//nrf24l01模式
void PowerDown_Mode(void)
{
        nrf24_Writer_REG(WRITE_REG|CONFIG, 0);
}

//待机模式1
void Standby_Mode_1(void)
{
        nrf24_Writer_REG(WRITE_REG|CONFIG, 0x02);
        CE = 0;
}

//待机模式2
void Standby_Mode_2(void)
{
        nrf24_Writer_REG(WRITE_REG|CONFIG, 0x02);
        CE = 1;
}


void NRF_24_init(void)
{
        SPI1_Master_Init();
        NRF24_CE_PIN_CONF();
        Standby_Mode_1();
}

/****************************************************************************************************
*函数:void TX_Mode(void)
*功能:数据发送配置
****************************************************************************************************/
void TX_Mode(void)
{
        Standby_Mode_1();
        nrf24_Writer_REG(WRITE_REG+STATUS,0xFF); // 清除所有中断标志
        nrf24_Writer_REG(FLUSH_TX, 0x00);
        //1 写Tx节点地址
        nrf24_Write_Buf(WRITE_REG + TX_ADDR, (int8_t*)Tx_addr, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
        //2 写Rx节点地址(主要是为了使能Auto Ack)
        nrf24_Write_Buf(WRITE_REG + RX_ADDR_P0, (int8_t*)Rx_addr, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
        //3 使能AUTO ACK
        nrf24_Writer_REG(WRITE_REG + EN_AA, 0x01);                                                                      // Enable Auto.Ack:Pipe0
        //4 使能PIPE0
        nrf24_Writer_REG(WRITE_REG + EN_RXADDR, 0x01);                                                                  // Enable Pipe0
        //5 配置自动重发次数
        nrf24_Writer_REG(WRITE_REG + SETUP_RETR, 0x2f);                                                                 // 500us + 86us, 10 retrans...1a(0xff发射超时最大70MS,发射最小只要1MS)
        //6 选择通信频率
        nrf24_Writer_REG(WRITE_REG + RF_CH, 0x6e);                                                                // 2.4G+0x6E
        //8 选择通道0 有效数据宽度
        nrf24_Writer_REG(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);                                 //设置接收数据长度,本次设置为32字节
        //7 配置发射参数(低噪放大器增益、发射功率、无线速率)
        nrf24_Writer_REG(WRITE_REG + RF_SETUP, 0x07);                                                                           // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
}

void nrf24_Send_Data(int8_t *pbuf, uint8_t len)
{
        Standby_Mode_1();  //StandBy I模式
        //多字节写入是从低到高字节
        nrf24_Write_Buf(WRITE_REG + RX_ADDR_P0, (int8_t*)Tx_addr, TX_ADR_WIDTH);         // 装载接收端地址
        nrf24_Writer_REG(FLUSH_TX, 0x00);
        //写TX有效数据,1-32字节,写操作从字节0开始
        nrf24_Write_Buf(WR_TX_PLOAD, pbuf, len);                                                                                                         // Writes data to TX payload
        nrf24_Writer_REG(WRITE_REG + CONFIG, 0x0e);                                                                              // IRQ收发完成中断响应,16位CRC,主发送
        CE=1;                                                                                                                                                                                                                                           //置高CE,激发数据发送
}


int8_t Get_RF_Status(void)
{
        uint8_t status;
        int8_t ret;
        status = nrf24_Read_REG(STATUS);
        if (status & 0x10)
        {//数据多次重发,无ACK
                nrf24_Writer_REG(FLUSH_TX, 0);
                nrf24_Writer_REG(FLUSH_RX, 0);
                ret = -1;
        }
        else if (status & 0x20)
        {//发送成功
                ret = 0;
        }
        else if (status & 0x40)
        {//收到数据
                ret = 1;
        }
        status = nrf24_Read_REG(STATUS);
        nrf24_Writer_REG(WRITE_REG + STATUS, status);  
        return ret;
}
/////////////main.c中
NRF_24_init();
TX_Mode();
  while(1)
  {
                Get_RF_Status();
                if (gGPS_extern_interface.Gpgsv_Run > 0)
                {
                        nrf24_Send_Data((int8_t*)&gGPS_extern_interface.Disp_Run[0][0], 32);
                        gGPS_extern_interface.Gpgsv_Run = 0;
                }
                if (gGPS_extern_interface.Gprmc_Run > 0)
                {
                        nrf24_Send_Data((int8_t*)&gGPS_extern_interface.Disp_Run[1][0], 32);
                        gGPS_extern_interface.Gprmc_Run = 0;                       
                }
                if(Gsensor_Run > 0)
                {
                        nrf24_Send_Data((int8_t*)&sensor[0], 32);
                        memset(sensor, 0 ,32);
                        Gsensor_Run = 0;
                }
  }

接收部分的main.c
//接收代码
       
       
        Standby_Mode_1();
        Standby_Mode_2();       
        Standby_Mode_1();
       

        SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, TX_ADR_WIDTH);         //写接收端地址,不要本地地址
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                                                                                                      //频道0自动 ACK应答禁止
        SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);                                                                                                  //允许接收地址只有频道0,如果需要多频道可以参考Page21  如果  
        SPI_RW_Reg(WRITE_REG + RF_CH, 0x6e);                                                                                                //设置信道工作为2.4GHZ,收发必须一致(2.4G~2.525G)
        SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);                                                                                             //设置发射速率为1MHZ,发射功率为最大值0dB
        SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);                                                                 //设置接收数据长度,本次设置为32字节
        SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F);                                                                                                      //IRQ收发完成中断响应,16位CRC,发射模式
        CE=1;
        //DelayMs(10);

        while(1)
        {
                nStatus = SPI_Read(STATUS);
                nFifo_status = SPI_Read(FIFO_STATUS);
                P36_DOUT = 1;
                if (nStatus & 0x40)
                {
                        SPI_Read_Buf(RD_RX_PLOAD, Temp, 32);
                        //可见及定位卫星信息
                        u32 = 0;
                        u32 = Str_find(Temp, 32, "$SA,", 4);
                        if (u32 >= 0)
                        {
                                P36_DOUT = 0;
                                for(i=0; i<12; i++)
                                {
                                        GPS_ActiveX_control.Disp_PRN_SNR[0] = 0;
                                        GPS_ActiveX_control.Disp_PRN_SNR[1] = 0;
                                        GPS_ActiveX_control.Disp_PRN_SNR[2] = 0;
                                        if ((Temp[4+i*2] & 0x80) > 0)
                                        {
                                                GPS_ActiveX_control.Disp_PRN_SNR[2] = Temp[4+i*2] & 0x7f;
                                        }
               
                                        GPS_ActiveX_control.Disp_PRN_SNR[0] = Temp[4+i*2] & 0x7f;
                                        GPS_ActiveX_control.Disp_PRN_SNR[1] = Temp[4+i*2+1];
                                }
                                GPGSA_View();
                        }
                        //定位时分秒信息
                        u32 = 0;
                        u32 = Str_find(Temp, 32, "$MC,", 4);
                        if (u32 >= 0)
                        {
                                P36_DOUT = 0;
                                memset(GPS_ActiveX_control.Latitude_string, '' ,11);
                                memset(GPS_ActiveX_control.Longitude_string, '' ,11);
                                GPS_ActiveX_control.FixStatus = Temp[4];
                                for(i=0; i<10; i++)
                                {
                                        GPS_ActiveX_control.Latitude_string = Temp[5+i];
                                        GPS_ActiveX_control.Longitude_string = Temp[15+i];
                                }
                                GPS_INFO.GPS_date.week = Temp[25];
                                GPS_INFO.GPS_date.year = Temp[26];
                                GPS_INFO.GPS_date.month = Temp[27];
                                GPS_INFO.GPS_date.day = Temp[28];
                                GPS_INFO.GPS_time.hour = Temp[29];
                                GPS_INFO.GPS_time.minute = Temp[30];
                                GPS_INFO.GPS_time.second = Temp[31];
                                GPRMC_View();
                        }
                        u32 = 0;
                        u32 = Str_find(Temp, 32, "$g", 2);
                        if (u32 >= 0)
                        {
                                P36_DOUT = 0;
                                memset(&gui[0][0], '' ,10);
                                memset(&gui[1][0], '' ,10);
                                memset(&gui[2][0], '' ,10);
                                for(i=0; i<10; i++)
                                {
                                        gui[0] = Temp[2+i*3];
                                        gui[1] = Temp[2+i*3+1];
                                        gui[2] = Temp[2+i*3+2];
                                }                               
                        }
                        gSensor_View();
                }
               
               
                SPI_RW_Reg(WRITE_REG + STATUS, nStatus);

                if (nFifo_status & 0x02)
                {
                        SPI_RW_Reg(FLUSH_RX, 0);
                }
               

                //printf("FIFO_STATUS = 0x%02x ", nFifo_status);       
                //printf("STATUS = 0x%02x----", nStatus);               
        }

//今天刚好调试完成的发送和接收的功能,还没有优化,直接给你贴上来了!
你先试一下吧,有问题再发贴,图片就是用2401传送数据示例!

指端轻语
4楼-- · 2020-01-14 02:29
skype 发表于 2013-5-23 23:30
//发送代码:
//nrf24l01模式
void PowerDown_Mode(void)

感谢,非常感谢这么热心的帮忙。

一发一收的模式我能调成功,就是互相收发的调不好(每个模块都是有收有发的,而不是单独的接收或发送),问题到现在还是那样就是我帖子描述的那样。

哎 都调蒙了
enthier
5楼-- · 2020-01-14 08:02
在ACK里携带数据包可以实现双向通讯。
指端轻语
6楼-- · 2020-01-14 09:57
enthier 发表于 2013-5-24 09:48
在ACK里携带数据包可以实现双向通讯。

这倒是个好办法  你实现过吗

一周热门 更多>