OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4942|回复: 4

两个NRF2401通信问题

[复制链接]

10

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-3-5
在线时间
33 小时
发表于 2016-7-15 20:24:17 | 显示全部楼层 |阅读模式
10金钱
我用一块STM32F103ZE的板子做接收,一块F407VET6做发送,两个板子的检测NRF2401都成功检测到,但发送数据时一直是达到最大重发次数,请大家指点一下。




F407发送程序:
void NRF24L01_TX_Mode(void)
{                                                                                                                 
        NRF24L01_CE=0;            
  NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点
  NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址 ,主要为了使能ACK

  NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答
  NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  
  NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500US+86US;最大重发次数:10次
  NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);       //设置RF通道为40
  NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,
  NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);    //发送模式,开启所有中断
        NRF24L01_CE=1;//CE为高,10US后启动发送
}

F103接收函数:
void NRF24L01_RX_Mode(void)
{
        NRF24L01_CE=0;          
          NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点
          
          NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);    //使能通道0的自动应答
          NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址  
          NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);             //设置RF通信频率  
          NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据  宽度            
          NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//  设置TX发射参数,0db增益,2Mbps
          NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//接收模式,开启所有中断
          NRF24L01_CE = 1; //CEÎa¸ß,½øèë½óêÕÄ£ê½
}               



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2016-7-15 21:56:21 | 显示全部楼层
都是移植的我们的代码?
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2016-7-15 22:43:10 | 显示全部楼层
请看我测试通过的代码片段:
#define  NRF2401_MASTER_SEND    0   //NRF24L01无线模块工作模式选择: 1---主; 0---从

/******************************管脚定义*************************/
#define NRF24L01_CSNON  GPIOB->BSRR = GPIO_Pin_12
#define NRF24L01_CSNOFF GPIOB->BRR = GPIO_Pin_12

#define NRF24L01_CEON  GPIOB->BSRR = GPIO_Pin_11
#define NRF24L01_CEOFF GPIOB->BRR = GPIO_Pin_11





void NRF24L01_GPIO_SPI_Configration(void)
{   
     GPIO_InitTypeDef GPIO_InitStructure;
     SPI_InitTypeDef  SPI_InitStructure;
          
     NRF24L01_CSNON;
     NRF24L01_CEON;
       
         /* SPI2 NSS SCK MISO MOSI PB12-15 */   
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11|GPIO_Pin_12;//SPI2的I/O使能
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //NSS 推挽输出         
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //口线翻转速度为50MHz                              
     GPIO_Init(GPIOB, &GPIO_InitStructure);        //初始化函数

     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15|GPIO_Pin_14;//SPI2的I/O使能
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //SCK MOSI  MISO复用推挽输出         
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //口线翻转速度为50MHz                              
     GPIO_Init(GPIOB, &GPIO_InitStructure);        //初始化函数
       
       //注:SPI2 时钟 ----在外设时钟使能函数中开启
          //RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //SPI2 时钟                     
       SPI_I2S_DeInit(SPI2);
       
       SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工模式(或是半双工)
       SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主机模式(Slave从机模式)
          SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//八位数据(16b十六位)
          SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//Low低电平有效(High高)
          SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//第几个跳变沿传输数据
          SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//NSS管脚Soft软件控制  Hard是硬件控制
          SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;//(8种时钟分频2 4 8 16 32 64 128 256)
          SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//MSB数据高位在前 LSB低位在前
          SPI_InitStructure.SPI_CRCPolynomial = 7;//校验位
          SPI_Init(SPI2, &SPI_InitStructure);         
          SPI_Cmd(SPI2, ENABLE);//使能
}



/****************************************************************************************/
//NRF24L01初始化
/***************************************************************************************/
void TX_NRF24L01(void)
{
    NRF24L01_CEOFF;    // chip enable
    SPI_Write_Buf(WRITE_REGS + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址
    SPI_Write_Buf(WRITE_REGS + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址

    SPI_RW_Reg(WRITE_REGS + EN_AA, 0x01);      // 频道0自动 ACK应答允许
    SPI_RW_Reg(WRITE_REGS + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
    SPI_RW_Reg(WRITE_REGS + SETUP_RETR, 0x1a); // 设置自动重发时间和次数:500us + 86us, 10 retrans...
    SPI_RW_Reg(WRITE_REGS + RF_CH,40);        //   设置信道工作为2.4GHZ,收发必须一致
    SPI_RW_Reg(WRITE_REGS + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
    SPI_RW_Reg(WRITE_REGS + RF_SETUP, 0x0F);      //设置发射速率为1MHZ,发射功率为最大值0dB
    SPI_RW_Reg(WRITE_REGS + CONFIG, 0x0E);      // IRQ收发完成中断响应,16位CRC ,主接收
    NRF24L01_CEON;    // chip enable
}


void RX_NRF24L01(void)
{
    NRF24L01_CEOFF;  
    SPI_Write_Buf(WRITE_REGS+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址

    SPI_RW_Reg(WRITE_REGS+EN_AA,0x01);             //使能通道0的自动应答   
    SPI_RW_Reg(WRITE_REGS+EN_RXADDR,0x01);         //使能通道0的接收地址
    SPI_RW_Reg(WRITE_REGS+RF_CH,40);              //设置RF通信频率  
    SPI_RW_Reg(WRITE_REGS+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度   
    SPI_RW_Reg(WRITE_REGS+RF_SETUP,0x0F);          //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
    SPI_RW_Reg(WRITE_REGS+CONFIG, 0x0F);           //配置基本工作模式的参数WR_UP,EN_CRC,16BIT_CRC,接收模式
    NRF24L01_CEON;    //CE为高,进入接收模式
}  



u8 nRF24L01_TxPacket(u8 *tx_buf)
{
    u8 sta;
    NRF24L01_CEOFF;    //StandBy I模式
    SPI_Write_Buf(WRITE_REGS + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
    SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     // 装载数据

    NRF24L01_CEON;   //置高CE,激发数据发送
    OSTimeDly(20);

    sta = SPI_Read_Reg(STATUS);  //读取状态寄存器的值   
    SPI_RW_Reg(WRITE_REGS + STATUS,sta); //清除TX_DS或MAX_RT中断标志
       
    if(sta & MAX_TX)//达到最大重发次数
    {
        SPI_RW_Reg(FLUSH_TX,0xFF);//清除TX FIFO寄存器
        return MAX_TX;
    }
    if(sta & TX_OK)//发送完成
    {
        return TX_OK;
    }
               
    return 0xff;//其他原因发送失败

}



u8 nRF24L01_RxPacket(u8 *rxbuf)
{
    u8 sta;         
    sta = SPI_Read_Reg(STATUS);  //读取状态寄存器的值      
    SPI_RW_Reg(WRITE_REGS + STATUS,sta); //清除TX_DS或MAX_RT中断标志

    if(sta & RX_OK)//接收到数据
    {
        SPI_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
        SPI_RW_Reg(FLUSH_RX,0XFF);//清除RX FIFO寄存器
        return 0;
    }   
    return 1;//没收到任何数据  
}   



void Task_NRF24L01_RxTx(void *p_arg)
{                
   u8  sd_status=0;
       
   #if NRF2401_MASTER_SEND >0
        u8  table1;
   #else
        u8  table;
   #endif
       
   #if OS_CRITICAL_METHOD == 3   
   //OS_CPU_SR  cpu_sr = 0;
   #endif
       
    NRF24L01_GPIO_SPI_Configration();
       
   #if NRF2401_MASTER_SEND >0       
   TX_NRF24L01();
   #else       
   RX_NRF24L01();       
   #endif
       
   printf("Task_NRF24L01_RxTx Starting...\n\r");       


  while(1) {

     #if NRF2401_MASTER_SEND >0   //模式: 主机发送
                       
        if(Get_SendKey_Status() == 0)    //发送按钮--->是否按下      
        {
            //printf(" %d",nRF24L01_TxPacket(&table1));
                                       
            sd_status=nRF24L01_TxPacket(&table1);
                                       
            if(sd_status==TX_OK){
                printf("NRF24L01 Send OK!\n\r");                                               
            }else{
                printf(" %d\n\r",sd_status);
            }
                                               
           do{
                 OSTimeDly(20);                                                        
             }while(Get_SendKey_Status() == 0); //等待发送按钮抬起
        }
                               
  #else //模式: 从机接收
      sd_status=nRF24L01_RxPacket(&table);                                
        if(sd_status == 0)
        {     
           printf("%d ",table);
           REMOTE_LED_ON();               
           OSTimeDly(20);                                                
        }else{
            REMOTE_LED_OFF();                       
        }                                       
                               
   #endif       

  }

}






回复

使用道具 举报

10

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-3-5
在线时间
33 小时
 楼主| 发表于 2016-7-16 10:01:23 | 显示全部楼层
正点原子 发表于 2016-7-15 21:56
都是移植的我们的代码?

我把接收端板子的其他线拔了,就发送成功了。不过发送的东西是乱码,我把发送字节改为8,就正常了。
回复

使用道具 举报

10

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
115
金钱
115
注册时间
2016-3-5
在线时间
33 小时
 楼主| 发表于 2016-7-16 10:01:42 | 显示全部楼层
xfcjava3 发表于 2016-7-15 22:43
请看我测试通过的代码片段:
#define  NRF2401_MASTER_SEND    0   //NRF24L01无线模块工作模式选择: 1--- ...

我的测试成功了,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 08:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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