nrf24l01是适合初学入门的无线模块.docx

上传人:b****8 文档编号:9312593 上传时间:2023-02-04 格式:DOCX 页数:24 大小:22.62KB
下载 相关 举报
nrf24l01是适合初学入门的无线模块.docx_第1页
第1页 / 共24页
nrf24l01是适合初学入门的无线模块.docx_第2页
第2页 / 共24页
nrf24l01是适合初学入门的无线模块.docx_第3页
第3页 / 共24页
nrf24l01是适合初学入门的无线模块.docx_第4页
第4页 / 共24页
nrf24l01是适合初学入门的无线模块.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

nrf24l01是适合初学入门的无线模块.docx

《nrf24l01是适合初学入门的无线模块.docx》由会员分享,可在线阅读,更多相关《nrf24l01是适合初学入门的无线模块.docx(24页珍藏版)》请在冰豆网上搜索。

nrf24l01是适合初学入门的无线模块.docx

nrf24l01是适合初学入门的无线模块

24l01的多机通信采用频分多子的方法,只需要在接受端对不同的通道配置地址即可。

发送端使用相应的地址作为本机地址。

接受数据时通过读取STATUS中相关位即可得知接收的是哪个通道的数据。

以下仅给出多对一的通信代码。

至于一对多,以及多对多等情况读者可以自行研究了。

只给出相关部分,其他部分请参考前两篇文章

------------------------------------------接受端------------------------------------------------

uintconstADDRESS0[ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//频道0接收地址

uintconstADDRESS1[ADR_WIDTH]={0xc4,0xc3,0xc2,0xc1,0xc0};//频道1接收地址

ucharwho=0xff;

//****************************************************************************************

/*NRF24L01初始化

//***************************************************************************************/

voidinit_NRF24L01(void)

{

   us(100);

  CE=0;   //chipenable

  CSN=1;  //Spidisable

  SCK=0;  //Spiclocklineinithigh

//SPI_Write_Buf(WRITE_REG+TX_ADDR,ADDRESS0,ADR_WIDTH);   //写本地地址

  

SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,ADDRESS0,ADR_WIDTH);//频道0地址

SPI_Write_Buf(WRITE_REG+RX_ADDR_P1,ADDRESS1,ADR_WIDTH);//频道1地址

SPI_RW_Reg(WRITE_REG+EN_AA,0x03);          //频道0、1自动应答

SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x03);     //允许频道0、1

SPI_RW_Reg(WRITE_REG+RF_CH,0);       //  设置信道工作为2.4GHZ,收发必须一致

SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//0接收数据长度

SPI_RW_Reg(WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);//1接收数据长度

SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);    //设置发射速率为1MHZ,发射功率为最大值0dB

}

/******************************************************************************************************/

/*函数:

unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)

/*功能:

数据读取后放如rx_buf接收缓冲区中

/******************************************************************************************************/

unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)

{

   unsignedcharrevale=0;

sta=SPI_Read(STATUS);//读取状态寄存其来判断数据接收状况

if(RX_DR)    //判断是否接收到数据

{

  CE=0;   

  SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);

  revale=1;

  who=sta&0x0e;

  who|=0xf0;                          //通道0:

who==0xf0;通道1:

who==0xf2

}

SPI_RW_Reg(WRITE_REG+STATUS,0xff);  //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志

CSN=0;

SPI_RW(FLUSH_RX);

CSN=1;

returnrevale;

}

voidmain(void)

{

uchari;

ucharRxBuf[TX_PLOAD_WIDTH];

   init_NRF24L01();

StartUART();

ms(6000);

while

(1)

{

  //如果接收到数据,发往PC

  SetRX_Mode();

  if(nRF24L01_RxPacket(RxBuf))

  {

   R_S_Byte(who);

   ms(10000);

   for(i=0;i

   {

   R_S_Byte(RxBuf[i]);

   ms(10000);

   }

  }

}

}

-------------------------------------------发送1----------------------------------------------------

uintconstADDRESS0[ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};

其余与双工通信相同

-------------------------------------------发送2----------------------------------------------------

uintconstADDRESS1[ADR_WIDTH]={0xc4,0xc3,0xc2,0xc1,0xc0};//频道1接收地址

其余与双工通信相同

以上就是简要的代码。

也是重要的地方。

如果发送端要发送数据的话,可能在配置自动应答的接受地址时会遇到一些问题。

(因为是以通道0作为应答通道,而发送模式又必须使得接收发送地址一致,这样给两台发送机发数据就要对0实时配置地址)笔者尝试过配置,没有成功,只好不配置了,都是这样接收端无法接收到自动应答的信号~~

24l01双向通讯

2010-11-1921:

28

   一周的时间过去了,终于搞出来了双向通讯,中间出了点莫名奇妙的情况,导致我迷惘了很久。

   上次发的头文件和.c文件有个模式设置的选项。

在做双向通信的时候发现这个有点多余。

所以就删掉了,内容也做了些小改动。

所以就只发修改的部分

------------------------------------------------------24l01.h------------------------------------------------------------

这个文件和之前的一样。

只去掉

//模式选择

//#defineRMODE

#defineTMODE

这几行

------------------------------------------------------24l01.c-------------------------------------------------------------

修改了三个地方。

分别是

1、

//****************************************************************************************

/*NRF24L01初始化

/*这里不用设置什么模式,等需要接受或发送数据时指定模式

//***************************************************************************************/

voidinit_NRF24L01(void)

{

   us(100);

  CE=0;   //chipenable

  CSN=1;  //Spidisable

  SCK=0;  //Spiclocklineinithigh

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

}

2、

/****************************************************************************************************/

/*函数:

voidSetRX_Mode(void)

/*功能:

数据接收配置

/****************************************************************************************************/

voidSetRX_Mode(void)

{

CE=0;

SPI_RW_Reg(WRITE_REG+CONFIG,0x0f);    //IRQ收发完成中断响应,16位CRC,主接收

CE=1;

us(130);

}

3、

/***********************************************************************************************************

/*函数:

voidnRF24L01_TxPacket(unsignedchar*tx_buf)

/*功能:

发送tx_buf中数据

/**********************************************************************************************************/

voidnRF24L01_TxPacket(unsignedchar*tx_buf)

{

CE=0;   //StandByI模式

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,激发数据发送

us(10);

}

-------------------------------------------------------------------------------------------------------------

以上就是全部的修改。

这两个文件同样适用于单工通信。

以下给出这次测试用的两个主函数。

为了方便与上次的文章对应。

这里还是以接收,发送区分。

--------------------------------------------------接收--------------------------------------------------------

#include"nrf24l01.h"

#include"delay.h"

ucharTxBuf[TX_PLOAD_WIDTH]={0x55,0xaa};

//************************************串口初始化*********************************************************

voidStartUART(void)

{       //波特率2400

    SCON=0x50;

    TMOD=0x20;

    TH1=0xF3;

    TL1=0xF3;

    PCON=0x00;

    TR1=1;

}

//************************************通过串口将接收到数据发送给PC端**************************************

voidR_S_Byte(ucharR_Byte)

{

SBUF=R_Byte;

    while(TI==0);    //查询法

TI=0;   

}

//************************************主函数************************************************************

voidmain(void)

{

uchari;

ucharRxBuf[TX_PLOAD_WIDTH];

   init_NRF24L01();

StartUART();

ms(6000);

while

(1)

{

  //如果接收到数据,发往PC

  SetRX_Mode();

  if(nRF24L01_RxPacket(RxBuf))

  {

   for(i=0;i

   {

   R_S_Byte(RxBuf[i]);

   }

  }

  //发送0x55,0xaa要求发送端发数据

  nRF24L01_TxPacket(TxBuf);

  //SPI_RW_Reg(WRITE_REG+STATUS,0XFF);加上这句后,会出现接收到几组数据后停止了接收的现象,原因未知

  ms(130);//这个延时很重要,延时过短,数据包丢失。

   //延时过长,减慢速度,甚至无法接收(实验时出现的问题,原因未知)

  RxBuf[0]=0;

  RxBuf[1]=0;

}

}

--------------------------------------------------------------------发送---------------------------------------------

include"nrf24l01.h"

#include"delay.h"

ucharTxBuf[TX_PLOAD_WIDTH]=

{

0x01,0x02

};

voidmain()

{

   charRxBuf[TX_PLOAD_WIDTH]={0};

init_NRF24L01();

nRF24L01_TxPacket(TxBuf);

ms(6000);

while

(1)

{

  SetRX_Mode();

  if(nRF24L01_RxPacket(RxBuf))

  {

   //将收到的数据发回接收端检验是否正确

   //如果设置的数据较长,应使用for循环

   TxBuf[0]=RxBuf[0];

   TxBuf[1]=RxBuf[1];

   nRF24L01_TxPacket(TxBuf);

   SPI_RW_Reg(WRITE_REG+STATUS,0XFF);

   ms(90);//这个延时一样很重要

   RxBuf[0]=0;

   RxBuf[1]=0;

  }

}

}

-------------------------------------------------------------------------------------------------------------

以上就是这周忙活的东西了,高手不要见笑。

PS:

原先想要使用自动重发功能的,结果发现自动重发的话,传输速率很慢,没有延时的快。

也可能是我自动重发的延时没设置好。

另外最开始几天一直在做中断通信,如果使用IRQ上中断来接受数据,可以明显减轻MCU的负担。

可是我测试了几天下来发现一个无语的结果。

在中断里读出来的STATUS的值是0x00,顿时心灰意冷。

网上有其他人貌似做出来了,可惜我写的跟他们一样也不行啊~~~~,不知道问题在哪。

但有一点是肯定的:

接收到数据时必然引起中断。

过几天继续贴出多机通信的代码。

nrf24l01的51驱动程序

2010-11-1318:

58

   随着物联网时代的到来,无线通信技术日趋重要。

   nrf24l01是适合初学入门的无线模块。

于是乎我就一头埋进去,苦干一周有余。

发现网上的程序都是抄来抄去的,不甚寒心。

抄也就算了,光抄错的!

后来自己动手研究,完成了SPI接口的操作,继续攻克无线模块,最终无果,只好再找代码。

终于找到了一个可以的。

   本来想直接贴出来的,但为了许多和我曾经一样迷茫的同胞可以顺利进入无线领域。

我特意修改代码,整理出nrf24l01.h与nrf24l01.c,一则便于模块化管理,二则,便于使用,便于二次开发。

同时,增加了许多注释。

    代码中应该还有许多不足的,甚至多余的东西,后续将会继续发表一篇关于无线模块开发的注意事项。

//---------------------nrf24l01.h----------------------------

#ifndefNRF24L01_H

#defineNRF24L01_H

#include

//模式选择

//#defineRMODE

#defineTMODE

typedefunsignedcharuchar;

typedefunsignedcharuint;

//****************************************SPI-IO端口***************************************

sbitCE  =P1^0;//3

sbitSCK=P1^1;//5

sbitMISO=P1^2;//7

sbitCSN=P1^5;//4

sbitMOSI=P1^6;//6

sbitIRQ=P1^7;//8

//*****************************************地址、数据长度*************************************

#defineTX_ADR_WIDTH   5  //5uintsTXaddresswidth

#defineRX_ADR_WIDTH   5  //5uintsRXaddresswidth

#defineTX_PLOAD_WIDTH32//20uintsTXpayload

#defineRX_PLOAD_WIDTH32//20uintsTXpayload

//***************************************NRF24L01寄存器指令*******************************************************

#defineREAD_REG       0x00//读寄存器指令

#defineWRITE_REG      0x20//写寄存器指令

#defineRD_RX_PLOAD    0x61//读取接收数据指令

#defineWR_TX_PLOAD    0xA0//写待发数据指令

#defineFLUSH_TX       0xE1//冲洗发送FIFO指令

#defineFLUSH_RX       0xE2//冲洗接收FIFO指令

#defineREUSE_TX_PL    0xE3//定义重复装载数据指令

#defineNOP            0xFF//保留

//*************************************SPI(nRF24L01)寄存器地址****************************************************

#defineCONFIG         0x00//配置收发状态,CRC校验模式以及收发状态响应方式

#defineEN_AA          0x01//自动应答功能设置

#defineEN_RXADDR      0x02//可用信道设置

#defineSETUP_AW       0x03//收发地址宽度设置

#defineSETUP_RETR     0x04//自动重发功能设置

#defineRF_CH          0x05//工作频率设置

#defineRF_SETUP       0x06//发射速率、功耗功能设置

#defineSTATUS         0x07//状态寄存器

#defineOBSERVE_TX     0x08//发送监测功能

#defineCD             0x09//地址检测          

#defineRX_ADDR_P0     0x0A//频道0接收数据地址

#defineRX_ADDR_P1     0x0B//频道1接收数据地址

#defineRX_ADDR_P2     0x0C

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1