搜索
bottom↓
回复: 14

NRF24L01双向通讯不成功,请教

[复制链接]

出0入0汤圆

发表于 2013-5-23 17:45:28 | 显示全部楼层 |阅读模式
本帖最后由 指端轻语 于 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.每次发送完马上设成接收模式,接收完马上设成发送模式,也不行。

不会自动重发的问题吧,我都没建立自动重发功能

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入8汤圆

发表于 2013-5-23 19:39:34 | 显示全部楼层
一是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;
}

出0入0汤圆

 楼主| 发表于 2013-5-23 22:55:09 | 显示全部楼层
skype 发表于 2013-5-23 19:39
一是A模块发发送时设置成自动重发有ACK模式,B模块设置成接收模式:
A:
        //3 使能AUTO ACK

你好,你这个程序有没有完整的啊  谢谢  能具体请教一下你吗

出0入8汤圆

发表于 2013-5-23 23:30:09 | 显示全部楼层

//发送代码:
//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, '\0' ,11);
                                memset(GPS_ActiveX_control.Longitude_string, '\0' ,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], '\0' ,10);
                                memset(&gui[1][0], '\0' ,10);
                                memset(&gui[2][0], '\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\r\n", nFifo_status);       
                //printf("STATUS = 0x%02x----", nStatus);               
        }

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-5-24 00:18:52 | 显示全部楼层
skype 发表于 2013-5-23 23:30
//发送代码:
//nrf24l01模式
void PowerDown_Mode(void)

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

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

哎 都调蒙了

出0入0汤圆

发表于 2013-5-24 09:48:35 | 显示全部楼层
在ACK里携带数据包可以实现双向通讯。

出0入0汤圆

 楼主| 发表于 2013-5-24 23:49:59 | 显示全部楼层
enthier 发表于 2013-5-24 09:48
在ACK里携带数据包可以实现双向通讯。

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

出0入0汤圆

发表于 2013-5-25 08:55:44 | 显示全部楼层
实现过啊,打开动态数据长度就可以。

出0入0汤圆

发表于 2014-6-11 15:32:40 | 显示全部楼层
请问有没有使用ACK里携带数据包实现双向通讯的相关资料  NRF24l01的资料里没有提到?

出0入0汤圆

发表于 2014-6-12 17:20:08 | 显示全部楼层
我也想知道怎么用ACK接收到数据的。

出0入0汤圆

发表于 2014-6-14 19:54:29 | 显示全部楼层
有没有相关资料?急需?

出0入0汤圆

发表于 2015-11-19 07:38:54 | 显示全部楼层
绝对零度 发表于 2014-6-14 19:54
有没有相关资料?急需?

同求互相收发的例子

出0入0汤圆

发表于 2015-11-19 07:40:51 | 显示全部楼层
skype 发表于 2013-5-23 23:30
//发送代码:
//nrf24l01模式
void PowerDown_Mode(void)

继续贴上来啊,急需

出0入0汤圆

发表于 2016-12-27 11:58:14 | 显示全部楼层
mark 以下

出0入0汤圆

发表于 2018-11-19 00:21:01 | 显示全部楼层
楼主调好了没
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 00:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表