搜索
bottom↓
回复: 54

当检测一个nRF24L01发送数据是否成功,可以用什么方法?

[复制链接]

出0入0汤圆

发表于 2010-1-7 08:56:34 | 显示全部楼层 |阅读模式
大家帮忙看一下吧,不知道是发送的问题,还是接收的问题,想要分别检测,先谢谢大家了!

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入4汤圆

发表于 2010-1-7 08:58:24 | 显示全部楼层
NRF24L01可以产生应答信号

出0入0汤圆

 楼主| 发表于 2010-1-7 09:03:35 | 显示全部楼层
是发射端产生应答信号吗,它的6个引脚的电平会发生什么变化吗?比如IRQ的引脚会变化吗?我只知道接收到有效信号后IRQ的引脚电平会变低,不知道对不对,希望大家多多指教?

出0入4汤圆

发表于 2010-1-7 09:23:13 | 显示全部楼层
nrf24l01可以工作在增强型的ShockBurstTM 模式,在该模式下通信时 接收端在收到数据后会产生一个应答信号给发送端,详细的过程看手册吧,
点击此处下载 ourdev_523539.pdf(文件大小:565K) (原文件名:nrf24L01中文资料.pdf)

出0入0汤圆

发表于 2011-7-10 19:30:40 | 显示全部楼层
24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根本不知道是发的问题还是收的问题,不隐晦的说,我当时也是没理清调试思路才浪费了大半天时间看着模块干瞪眼。正确的方法应该是先调试发送方,能保证发送正确,再去调接收,这样就可以有针对性的解决问题。
至于怎么去调发送方,先说下发送方的工作流程:

•配置寄存器使芯片工作于发送模式后拉高CE端至少10us
•读状态寄存器STATUS
•判断是否是发送完成标志位置位
•清标志
•清数据缓冲

网上的程序我也看过,大多都是成品,发送方发送-等应答-(自动重发)-触发中断。可是这样的流程就已经把接收方给牵涉进来了,就是说一定要接收方正确收到数据并且回送应答信号之后发送方才能触发中断,结束一次完整的发送。可是这跟我们的初衷不相符,我们想单独调试发送,完全抛开接收,这样就要去配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);                 // 失能通道0自动应答
        SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00);            // 失能接收通道0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00);          // 失能自动重发
(注:以下贴出的寄存器描述由于中文资料上有一个错误,故贴出原版英文资料)






有了以上这三个配置,发送方的流程就变成了发送-触发中断。这样就抛开了接收方,可以专心去调试发送,可是怎么样才知道发送是否成功呢,要用到另外两个寄存器,STATUS和FIFO_STATUS。





这样就很清晰了,我们可以通过读取STATUS的值来判断是哪个事件触发了中断,寄存器4、5、6位分别对应自动重发完成中断,数据发送完成中断,数据接收完成中断。也就是说,在之前的配置下,如果数据成功发送,那么STATUS的值应该为0x2e。这样就可以作为一个检测标准,另外一个标准可以看FIFO_STATUS寄存器,第5位的描述:发送缓冲器满标志,1为满,0为有可用空间;第4位的描述:发送缓冲器空标志,1为空,0为有数据;同样可以看到接收缓冲器的对应标志。这样在数据发送成功后,发送寄存器当然应该是空的,接收缓冲因为在之前已经失能,所以也应该是空,也就是说成功发送之后的FIFO_STATUS寄存器值应该是0x11。
有了这两个检测标准,我们即使不用接收方也可以确定发送方是否成功发送。当发送方调试成功之后,在程序里让它一直发送,然后我们就可以去调试接收方,思路是一样的,同样说下接收方工作流程先。

•配置寄存器使芯片工作于接收模式后拉高CE端至少130us
•读状态寄存器STATUS
•判断是否是接收完成标志位置位
•清标志
•读取数据缓冲区的数据
•清数据缓冲

然后在初始化配置寄存器的时候要和发送方保持一致,比较重要的是要失能自动应答,使能通道0接收:
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);                 // 失能通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);            // 接收要使能接收通道0
这样就可以了,接收方就可以进入接收模式去接收数据了,这次的调试就会灵活一些,因为是接收数据,可以在接收方添加一个显示设备把数据直观的显示出来,去对照看是否正确,当然还可以使用和发送方一样的方法:观察STATUS和FIFO_STATUS的值,对照寄存器描述,接收正确时STATUS的值应该是0x40,对于FIFO_STATUS的情况就多了些,因为数据宽度的不同也会造成寄存器的值不一样,24L01最大支持32字节宽度,就是说一次通讯最多可以传输32个字节的数据,在这种情况下,接收成功读数据之前寄存器值应该为0x12,读数据之后就会变成0x11;如果数据宽度定义的小于32字节,那么接收成功读数据之前寄存器值应该为0x10,读数据之后就会变成0x11。这个看起来挺复杂,其实很清晰,大家可以试着分析下,对照数据手册分析每个位的状态就可以得到结果。

好了,到这里对nRF24L01的调试基本上就算通了,但是要明白这些只是调试方法,最终的产品如果不加上应答和重发的话那么数据的稳定性是很难保证的,所以在基本的通讯建立之后就要把发送的配置改为:       
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);               // 使能接收通道0自动应答
        SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);           // 使能接收通道0               
        SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a);          // 自动重发10次,间隔500us
接收方的配置也要更改:
        SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                 // 失能通道0自动应答
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);            // 接收要使能接收通道0

这样发送和接收就进入了一个标准状态,发送-等应答-(自动重发)-触发中断;接收-应答-触发中断,一切按部就班,程序里加上自己的应用部分就能实现很多功能了,呵呵,这个帖子就先到这,明白芯片工作原理之后写程序就有目的性了,下一篇再说说程序中查询法和中断法以及具体的程序实例。写了一个多小时了,得忙会儿工作,别被老板逮着了,哈哈。。。祝大家成功~~















NRF24L01发送端程序调试成功
•        复制地址
翰林文圣_2.4G 2011年03月10日 22:13 阅读(7) 评论(0) 分类:单片机资料
•        举报
•        字体:中▼
o        小
o        中
o        大


     在网友(李渊)的鼎力相助下,今天总算把困扰我好久的无线模块调试成功了,并且其中学到了很多学不到的东西~感觉专业人士就是不一样,ARM嵌入不是一般人能做的!感谢感谢,不然不知道需要在黑暗中摸索多久。下面献上热乎乎的程序!因为网上根本没有单独发送并且已经调试好的程序,独家首发^_^好兴奋!
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//****************************************IO端口定义***************************************
sbit  MISO=P1^0;
sbit  MOSI=P1^1;
sbit SCK =P1^2;
sbit CE  =P1^3;
sbit CSN =P1^4;
sbit IRQ =P1^5;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH    5    // 5 uints TX address width
#define RX_ADR_WIDTH    5    // 5 uints RX address width
#define TX_PLOAD_WIDTH  32   // 20 uints TX payload
#define RX_PLOAD_WIDTH  32   // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x01,0x01,0x01,0x01,0x01}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //接收地址      
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG        0x00   // 读寄存器指令
#define WRITE_REG       0x20  // 写寄存器指令
#define RD_RX_PLOAD     0x61   // 读取接收数据指令
#define WR_TX_PLOAD     0xA0   // 写待发数据指令
#define FLUSH_TX        0xE1  // 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2   // 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3   // 定义重复装载数据指令
#define NOP             0xFF   // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       0x02  // 可用信道设置
#define SETUP_AW        0x03  // 收发地址宽度设置
#define SETUP_RETR      0x04  // 自动重发功能设置
#define RF_CH           0x05  // 工作频率设置
#define RF_SETUP        0x06  // 发射速率、功耗功能设置
#define STATUS          0x07  // 状态寄存器
#define OBSERVE_TX      0x08  // 发送监测功能
#define CD              0x09  // 地址检测           
#define RX_ADDR_P0      0x0A  // 频道0接收数据地址
#define RX_ADDR_P1      0x0B  // 频道1接收数据地址
#define RX_ADDR_P2      0x0C  // 频道2接收数据地址
#define RX_ADDR_P3      0x0D  // 频道3接收数据地址
#define RX_ADDR_P4      0x0E  // 频道4接收数据地址
#define RX_ADDR_P5      0x0F  // 频道5接收数据地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收频道0接收数据长度
#define RX_PW_P1        0x12  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
//uchar SPI_Read(uchar reg);
//void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
//uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
//unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
void nRF24L01_TxPacket(unsigned char * tx_buf);
//*****************************************长延时*****************************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
//******************************************************************************************
uint  bdata sta;   //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
  _nop_();
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
    inerDelay_us(100);
  CE=0;    // chip enable
  CSN=1;   // Spi disable
  SCK=0;   // Spi clock line init high
IRQ=1;
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      //  频道0自动 ACK应答禁止
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  如果  
SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //设置发射速率为2MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,发射模式
}   //ps:波特率用设置么?IRQ用拉高么?不响应中断?
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uuchar)
{
uint bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
  MOSI = (uuchar & 0x80);         // output 'uchar', MSB to MOSI
  uuchar = (uuchar << 1);           // shift next bit into MSB..
  SCK = 1;                      // Set SCK high..
  uuchar |= MISO;           // capture current MISO bit
  SCK = 0;                // ..then set SCK low again
    }
    return(uuchar);               // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
uchar reg_val;

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

return(reg_val);        // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;

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

return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
/*
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;

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

for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
  pBuf[uchar_ctr] = SPI_RW(0);    //

CSN = 1;                           

return(status);                    // return nRF24L01 status uchar
}
*/
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;

CSN = 0;            //SPI使能      
status = SPI_RW(reg);   
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  SPI_RW(*pBuf++);
CSN = 1;           //关闭SPI
return(status);    //
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/****************************************************************************************************/
/*
void SetRX_Mode(void)
{
CE=0;
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
*/
/******************************************************************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
/******************************************************************************************************/
/*
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
    unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR)    // 判断是否接收到数据
{
     CE = 0;    //SPI使能
  SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
  revale =1;   //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}
*/
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0;   //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     // 装载数据
// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送
CE=1;   //置高CE,激发数据发送
inerDelay_us(50);
}
//************************************主函数************************************************************
void main()
{
//unsigned char TxBuf[20]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};    //test
//unsigned char TxBuf[20]={0};   
unsigned char TxBuf[20]={1};
init_NRF24L01();

nRF24L01_TxPacket(TxBuf);
while(1)
{
nRF24L01_TxPacket(TxBuf);
P0=~SPI_Read(STATUS);
SPI_RW_Reg(WRITE_REG+STATUS,0XFF);   //清状态寄存器
Delay(2100);  //感觉不加延时或是改小些都无所谓,根据实际情况来。
  
}
}
明天最好能调试出接收端程序哈哈  调试ing




   经过一周的努力终于把发射和接受都搞定了,估计在多弄一天我就得崩溃了,先是硬件出问题,引脚弄反了,查出之后又开始调试软件,结果一个接着一个的查寄存器,看手册,这期间耗费了大量的心血,多亏认识了一个网友(李渊),在他的指点下才渐渐了解这个芯片的工作原理,传输机制,一天半就成功传送数据。在调试时注意ACK自动应答和电平CE的延长时间,试着查看STATUS的寄存器状态!终于可以安心的做毕业设计了哈哈\(^o^)/~
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//****************************************IO端口定义***************************************

sbit  MISO=P1^0;
sbit  MOSI=P1^1;
sbit SCK =P1^2;
sbit CE  =P1^3;
sbit CSN =P1^4;
sbit IRQ =P1^5;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH    5    // 5 uints TX address width
#define RX_ADR_WIDTH    5    // 5 uints RX address width
#define TX_PLOAD_WIDTH  32  // 20 uints TX payload
#define RX_PLOAD_WIDTH  32   // 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x10,0x10,0x10,0x10,0x10}; //本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x01,0x01,0x01,0x01,0x01}; //接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG        0x00   // 读寄存器指令
#define WRITE_REG       0x20  // 写寄存器指令
#define RD_RX_PLOAD     0x61   // 读取接收数据指令
#define WR_TX_PLOAD     0xA0   // 写待发数据指令
#define FLUSH_TX        0xE1  // 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2   // 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3   // 定义重复装载数据指令
#define NOP             0xFF   // 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       0x02  // 可用信道设置
#define SETUP_AW        0x03  // 收发地址宽度设置
#define SETUP_RETR      0x04  // 自动重发功能设置
#define RF_CH           0x05  // 工作频率设置
#define RF_SETUP        0x06  // 发射速率、功耗功能设置
#define STATUS          0x07  // 状态寄存器
#define OBSERVE_TX      0x08  // 发送监测功能
#define CD              0x09  // 地址检测           
#define RX_ADDR_P0      0x0A  // 频道0接收数据地址
#define RX_ADDR_P1      0x0B  // 频道1接收数据地址
#define RX_ADDR_P2      0x0C  // 频道2接收数据地址
#define RX_ADDR_P3      0x0D  // 频道3接收数据地址
#define RX_ADDR_P4      0x0E  // 频道4接收数据地址
#define RX_ADDR_P5      0x0F  // 频道5接收数据地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收频道0接收数据长度
#define RX_PW_P1        0x12  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
//void nRF24L01_TxPacket(unsigned char * tx_buf);
//*****************************************长延时*****************************************
void Delay(unsigned int s)
{
unsigned int i;
for(i=0; i<s; i++);
for(i=0; i<s; i++);
}
//******************************************************************************************
uint  bdata sta;   //状态标志
sbit RX_DR =sta^6;
sbit TX_DS =sta^5;
sbit MAX_RT =sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)
{
for(;n>0;n--)
  _nop_();
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
    inerDelay_us(100);
  CE=0;    // chip enable
  CSN=1;   // Spi disable
  SCK=0;   // Spi clock line init high
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_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, 0);        //   设置信道工作为2.4GHZ,收发必须一致
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //设置发射速率为1MHZ,发射功率为最大值0dB
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
uint bit_ctr;
    for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
    {
  MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
  uchar = (uchar << 1);           // shift next bit into MSB..
  SCK = 1;                      // Set SCK high..
  uchar |= MISO;           // capture current MISO bit
  SCK = 0;                // ..then set SCK low again
    }
    return(uchar);               // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
uchar reg_val;

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

return(reg_val);        // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
uint status;

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

return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;

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

for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
  pBuf[uchar_ctr] = SPI_RW(0);    //

CSN = 1;                           

return(status);                    // return nRF24L01 status uchar
}
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
uint status,uchar_ctr;

CSN = 0;            //SPI使能      
status = SPI_RW(reg);   
for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
  SPI_RW(*pBuf++);
CSN = 1;           //关闭SPI
return(status);    //
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置
/****************************************************************************************************/
void SetRX_Mode(void)
{
CE=0;
// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收
CE = 1;
inerDelay_us(130);
}
/******************************************************************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放如rx_buf接收缓冲区中
/******************************************************************************************************/
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
    unsigned char revale=0;
sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
if(RX_DR)    // 判断是否接收到数据
{
     CE = 0;    //SPI使能
  SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
  revale =1;   //读取数据完成标志
}
SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
/*
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
CE=0;   //StandBy I模式
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     // 装载数据
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送
CE=1;   //置高CE,激发数据发送
inerDelay_us(10);
}
*/
//************************************串口初始化*********************************************************
void StartUART( void )
{         //波特率4800
     SCON = 0x50;
     TMOD = 0x20;
     TH1 = 0xFA;
     TL1 = 0xFA;
     PCON = 0x00;
     TR1 = 1;
}
//************************************通过串口将接收到数据发送给PC端**************************************
void R_S_Byte(uchar R_Byte)
{
  SBUF = R_Byte;  
     while( TI == 0 );    //查询法
    TI = 0;   
}
//************************************主函数************************************************************
void main(void)
{
uchar i;
uchar RxBuf[32];
    init_NRF24L01() ;
StartUART();
Delay(6000);
while(1)
{

  SetRX_Mode();
  P0=~sta;
// R_S_Byte(RX_DR);
     if(nRF24L01_RxPacket(RxBuf))
  {
   
   for(i=0;i<32;i++)
   {
    R_S_Byte(RxBuf);
    //Delay(600);
   
   }
  }

}

}

出0入0汤圆

发表于 2011-8-9 09:00:42 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-9 16:54:32 | 显示全部楼层
要顶的

出0入0汤圆

发表于 2011-8-10 00:38:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-14 22:23:16 | 显示全部楼层
顶啊

出0入0汤圆

发表于 2011-8-15 21:56:35 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-15 22:48:49 | 显示全部楼层
首先是用示波器看IRQ端,其实看了也没什么用,因为很多情况下的中断都会使IRQ产生变化!确切的说,你根本无法识别到底是什么情况产生了中断(如果是最大重发次数溢出,也会产生中断的。。。)

我教你一个有效的方法!载开启自动应答后,在判断RX_DR位或者TX_DR位的时候在其后面添加一句能够让你知道程序已经产生了RX_DR或者TX_DR标志的比较醒目的信号,比如:点亮发光二极管,或者用串口发送一句提示语句,提示已经产生了RX_DR或者TX_DR标志!因为如果产生了这两个标志,绝对能说明已经发送或者接受成功了!

出0入0汤圆

发表于 2011-8-23 14:48:59 | 显示全部楼层
最近也在玩24l01,上电后发现IRQ输出是低电平,不知道怎么回事?不知道是不是初始化不对?
玩过的朋友指点一下,谢谢!

出0入0汤圆

发表于 2011-8-23 21:43:23 | 显示全部楼层
MARK

出0入0汤圆

发表于 2011-8-24 18:07:34 | 显示全部楼层
读取FIFO_STATUS寄存器时为什么发送缓存空标志为1 (没数据)  不断发送的话应该发送缓存里还有数据啊·

出0入0汤圆

发表于 2011-8-24 18:08:03 | 显示全部楼层
回复【4楼】xiaochun90188
-----------------------------------------------------------------------

读取FIFO_STATUS寄存器时为什么发送缓存空标志为1 (没数据)  不断发送的话应该发送缓存里还有数据啊·

出0入0汤圆

发表于 2011-8-26 08:27:10 | 显示全部楼层

出0入0汤圆

发表于 2011-8-27 19:13:37 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-27 21:44:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-29 09:52:23 | 显示全部楼层
学习了

出0入0汤圆

发表于 2011-8-30 22:39:51 | 显示全部楼层
mark 一下, 学习!

出0入0汤圆

发表于 2011-9-2 17:08:38 | 显示全部楼层
学习中

出0入0汤圆

发表于 2011-9-2 17:16:24 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2011-10-8 16:52:46 | 显示全部楼层
学习中,谢谢,收藏先

出0入0汤圆

发表于 2011-10-9 22:20:21 | 显示全部楼层
楼主 后续呢?
接收程序

出0入0汤圆

发表于 2011-10-9 23:42:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-10-20 10:32:59 | 显示全部楼层
顶一下,现在我也在玩这个

出0入0汤圆

发表于 2012-2-2 16:39:40 | 显示全部楼层
多谢 xiaochun90188   !!!!

出0入0汤圆

发表于 2012-4-8 11:05:31 来自手机 | 显示全部楼层
标记了,学习中!

出0入0汤圆

发表于 2012-4-8 17:52:52 | 显示全部楼层
最近也在搞这个,一起学习下

出0入0汤圆

发表于 2012-4-9 08:57:39 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-4-14 12:27:26 | 显示全部楼层
最近也在搞这个,一起学习下

出0入0汤圆

发表于 2012-4-16 01:13:06 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2012-4-17 09:44:58 | 显示全部楼层
xiaochun90188 发表于 2011-7-10 19:30
24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根 ...

学习了,晚上再详读

出0入0汤圆

发表于 2012-6-7 16:08:53 | 显示全部楼层
郁闷呀,始终调不出来

出0入0汤圆

发表于 2012-6-13 17:50:14 | 显示全部楼层
内部有握手信号的

出0入0汤圆

发表于 2012-8-16 13:09:22 | 显示全部楼层
有调出来的吗?有没有单片机与单片机传输数据的?

出0入0汤圆

发表于 2012-8-17 10:13:27 | 显示全部楼层
xiaochun90188 发表于 2011-7-10 19:30
24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根 ...

这个有用,谢了

出0入0汤圆

发表于 2012-8-17 17:34:13 | 显示全部楼层
xiaochun90188 发表于 2011-7-10 19:30
24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根 ...

       发送和接收都要初始化NRF24L01, 会出现初始化不成功的情况么  怎么判断,有类似的ID  还是读状态判断!

出0入0汤圆

发表于 2012-8-19 11:15:34 | 显示全部楼层
mark         

出0入0汤圆

发表于 2012-8-23 17:38:04 | 显示全部楼层
学习了,谢谢。过几天调试。

出0入0汤圆

发表于 2012-8-27 11:39:25 | 显示全部楼层
非常感谢。调试成功了。

出0入0汤圆

发表于 2012-10-12 15:43:33 | 显示全部楼层
我也正困在无线里,楼主解决了吗,指导下小弟感激不尽,QQ970931626

出0入0汤圆

发表于 2012-10-12 17:20:58 | 显示全部楼层
路过看看,我们在产品中也没有用自动重发,而是靠上层完成的重发。

出0入0汤圆

发表于 2012-10-14 20:32:56 | 显示全部楼层
NRF24L01天线怎么做的???

出0入0汤圆

发表于 2012-10-15 12:57:24 | 显示全部楼层
xiaochun90188 发表于 2011-7-10 19:30
24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根 ...

听君一席话,胜读十年书啊

出0入0汤圆

发表于 2013-3-23 00:58:01 | 显示全部楼层
我读取了状态寄存器读回来的是14,不懂是什么原因,求指教

出0入0汤圆

发表于 2013-3-25 00:01:54 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2013-6-6 16:39:36 | 显示全部楼层
学习中,谢谢!

出0入0汤圆

发表于 2014-10-16 21:11:53 | 显示全部楼层
学习了,真给力!

出0入0汤圆

发表于 2014-10-17 16:43:02 | 显示全部楼层
xiaochun90188 发表于 2011-7-10 19:30
24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根 ...

顶5楼     

出0入0汤圆

发表于 2015-1-12 08:53:05 | 显示全部楼层
学习了,正在调,顶一下

出0入0汤圆

发表于 2015-4-17 19:27:13 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2015-4-21 22:01:51 | 显示全部楼层
woshiliupei 发表于 2010-1-7 09:03
是发射端产生应答信号吗,它的6个引脚的电平会发生什么变化吗?比如IRQ的引脚会变化吗?我只知道接收到有效 ...

既然是应答,当然是谁接受谁应答。
比如我隔着一段距离喊你一声,你说谁来应?

出0入0汤圆

发表于 2016-4-19 12:02:45 | 显示全部楼层
正在学习,MARK一下

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-7-23 07:19

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

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