极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: human2010

关于NRF24L01无线通讯问题详解???

[复制链接]
 楼主| 发表于 2013-10-22 11:40:20 | 显示全部楼层
以下是接收程序:

#include "NRF24L01.h"

#define TX_ADR_WIDTH    5   
#define TX_PLOAD_WIDTH  32  
unsigned char TX_ADDRESS[TX_ADR_WIDTH]  =
{
  0x34,0x43,0x10,0x10,0x01
};

unsigned char rx_buf[TX_PLOAD_WIDTH];
unsigned char tx_buf[TX_PLOAD_WIDTH];

#define CE       3
#define CSN      2
#define SCK      5
#define MOSI     4
#define MISO     6
#define IRQ      7

//*********************************************
void setup()
{
  pinMode(CE,  OUTPUT);
  pinMode(SCK, OUTPUT);
  pinMode(CSN, OUTPUT);
  pinMode(MOSI,  OUTPUT);
  pinMode(MISO, INPUT);
  pinMode(IRQ, INPUT);
  
  Serial.begin(9600);
  
  NRF24L01_init();   
  //SPI_Read_Buf(RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH);//接收数据  
}

void loop()
{
  SetRX_Mode();
  
  int i=SPI_Read(CD);//读取载波检测
  if(i)//如果接收到载波,
  {  
   // SPI_RW_Reg(FLUSH_RX,0);
    Serial.println("get");
    Serial.println(i);   
    delay(1000);
  }
  else
  {
    Serial.println("lost");
    Serial.println(i);
    delay(10);
  }
}

void NRF24L01_init(void)
{
  digitalWrite(CE,0);
  digitalWrite(CSN,1);
  digitalWrite(SCK,0);
  digitalWrite(IRQ,1);
  
  SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device
  
  SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      // Enable Auto.Ackipe0
  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 设置接收数据长度,本次设置为32字节
  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  
  //SPI_Read_Buf(RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH);//接收数据
}
//**********************接收模式*****************************
void SetRX_Mode(void)
{
  digitalWrite(CE,0);
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);// IRQ收发完成中断响应,16位CRC,接收模式               
  digitalWrite(CE,1);
  delay(1);   
}

unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
  unsigned char revale=0;
  unsigned char status=SPI_Read(STATUS);        // 读取状态寄存其来判断数据接收状况
  if(status&RX_DR)                                // 判断是否接收到数据(RX_DR接收数据中断)
  {
    digitalWrite(CE,0);                         //SPI使能
    SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);//读取数据
    revale =1;                        //读取数据完成标志
  }
  SPI_RW_Reg(WRITE_REG+STATUS,0xff);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
  return revale;
}

/**************************************************
* Function: SPI_RW();
*
* Description:
* Writes one unsigned char to nRF24L01, and return the unsigned char read
* from nRF24L01 during write, according to SPI protocol
**************************************************/
unsigned char SPI_RW(unsigned char Byte)
{
  unsigned char i;
  for(i=0;i<8;i++)                      // output 8-bit
  {
    if(Byte&0x80)
    {
      digitalWrite(MOSI, 1);
    }
    else
    {
      digitalWrite(MOSI, 0);
    }
    digitalWrite(SCK, 1);
    Byte <<= 1;                         // shift next bit into MSB..
    if(digitalRead(MISO) == 1)
    {
      Byte |= 1;                               // capture current MISO bit
    }
    digitalWrite(SCK, 0);
  }
  return(Byte);                           // return read unsigned char
}
/**************************************************/

/**************************************************
* Function: SPI_RW_Reg();
*
* Description:
* Writes value 'value' to register 'reg'
/**************************************************/
unsigned char SPI_RW_Reg(unsigned char reg, unsigned char value)
{
  unsigned char status;

  digitalWrite(CSN, 0);                   // CSN low, init SPI transaction
  status = SPI_RW(reg);                   // select register
  SPI_RW(value);                          // ..and write value to it..
  digitalWrite(CSN, 1);                   // CSN high again

  return(status);                   // return nRF24L01 status unsigned char
}
/**************************************************/

/**************************************************
* Function: SPI_Read();
*
* Description:
* Read one unsigned char from nRF24L01 register, 'reg'
/**************************************************/
unsigned char SPI_Read(unsigned char reg)
{
  unsigned char reg_val;

  digitalWrite(CSN, 0);           // CSN low, initialize SPI communication...
  SPI_RW(reg);                   // Select register to read from..
  reg_val = SPI_RW(0);           // ..then read register value
  digitalWrite(CSN, 1);          // CSN high, terminate SPI communication

  return(reg_val);               // return register value
}
/**************************************************/

/**************************************************
* Function: SPI_Read_Buf();
*
* Description:
* Reads 'unsigned chars' #of unsigned chars from register 'reg'
* Typically used to read RX payload, Rx/Tx address
/**************************************************/
unsigned char SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
  unsigned char status,i;

  digitalWrite(CSN, 0);                  // Set CSN low, init SPI tranaction
  status = SPI_RW(reg);                   // Select register to write to and read status unsigned char

  for(i=0;i<bytes;i++)
  {
    pBuf[i] = SPI_RW(0);    // Perform SPI_RW to read unsigned char from nRF24L01
  }

  digitalWrite(CSN, 1);                   // Set CSN high again

  return(status);                  // return nRF24L01 status unsigned char
}
/**************************************************/

/**************************************************
* Function: SPI_Write_Buf();
*
* Description:
* Writes contents of buffer '*pBuf' to nRF24L01
* Typically used to write TX payload, Rx/Tx address
/**************************************************/
unsigned char SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char bytes)
{
  unsigned char status,i;

  digitalWrite(CSN, 0);                  // Set CSN low, init SPI tranaction
  status = SPI_RW(reg);             // Select register to write to and read status unsigned char
  for(i=0;i<bytes; i++)             // then write all unsigned char in buffer(*pBuf)
  {
    SPI_RW(*pBuf++);
  }
  digitalWrite(CSN, 1);                   // Set CSN high again
  return(status);                  // return nRF24L01 status unsigned char
}


回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-10-22 11:41:57 | 显示全部楼层
经再次调试,只有发送调试OK,接收还是NG.悲剧!{:soso_e109:}
回复 支持 反对

使用道具 举报

发表于 2013-10-22 18:08:01 | 显示全部楼层
human2010 发表于 2013-10-22 09:12
可能我描述有问题,您说的我明白!
我现在用的是软件模拟SPI接口与NRF24L01通讯。
我说的中断是指NRF24 ...

你还是用我调试成功的那个帖子里边的代码来测试,不要去修改任何代码,只用按照它定义的接法去接你的硬件,记住nRF24L01的IRQ脚直接连到你的主控板上的0号硬件中断口上。再试试……我一会儿用Leonardo板子试试接收,如成功了,就告诉你接线顺序,只要测试成功一次了,后边怎么修改代码就简单了
回复 支持 反对

使用道具 举报

发表于 2013-11-2 01:25:19 | 显示全部楼层
human2010 发表于 2013-10-22 11:41
经再次调试,只有发送调试OK,接收还是NG.悲剧!

我的那个程序没有问题的。那个是模拟SPI,模拟SPI是借用别人写的。模拟SPI就是用普通的I/O口去模拟SPI,任何数字脚或者模拟脚都可以使用。你在那个nrf24l01.h里面修改引脚再插到对应的引脚上去完全没问题。经过我3周多的钻牛角尖之后,我目前猜测是2560板子的PCB布线有问题,影响了高频通信。我也只是猜测。因为我本身自己焊了三块UNO自制小板子,其中2块收发成功,有一块不行,那一块跟2560一样也是只能发不能收。已排除了虚焊和硬件的问题,所以很可能是我布线不好干扰了通信。UNO那块板子任你怎么设引脚收跟发都是没问题的,2560就不行,
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-16 10:47:18 | 显示全部楼层
keyosa 发表于 2013-11-2 01:25
我的那个程序没有问题的。那个是模拟SPI,模拟SPI是借用别人写的。模拟SPI就是用普通的I/O口去模拟SPI,任 ...

谢谢您提醒!我重新买了块UNO板子
回复 支持 反对

使用道具 举报

发表于 2013-11-16 13:53:49 | 显示全部楼层
我上次也是测试这个搞了很久死活不行。

最后在3.3v和GND之间加了个100uf电容就啥问题都没了……

可以参考我发的帖子
回复 支持 反对

使用道具 举报

发表于 2014-3-26 00:51:40 | 显示全部楼层
这个很好很爱昂强大
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-9 21:13 , Processed in 0.036359 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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