nrf24l01是适合初学入门的无线模块_第1页
nrf24l01是适合初学入门的无线模块_第2页
nrf24l01是适合初学入门的无线模块_第3页
nrf24l01是适合初学入门的无线模块_第4页
nrf24l01是适合初学入门的无线模块_第5页
免费预览已结束,剩余14页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、24101 的多机通信采用频分多子的方法,只需要在接受端对不同的通道配置地址即可。发送端使用相应的地址作为本机地址。接受数据时通过读取 STATU 汕相关位即可得知接收的是哪个通道的数据。以下仅给出多对一的通信代码。至于一对多,以及多对多等情况读者可以自行研究了。只给出相关部分,其他部分请参考前两篇文章接受端uintconstADDRESS0ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;/uintconstADDRESS1ADR_WIDTH=0 xc4,0 xc3,0 xc2,0 xc1,0 xc0;/频道 0 接收地址频道 1 接收地址ucharwho=0

2、xff;/*/*NRF24L01 初始化/*/voidinit_NRF24L01(void)us(100);CE=0;/chipenableCSN=1;/SpidisableSCK=0;/SpiclocklineinithighSPI_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 地址SP

3、I_RW_Reg(WRITE_REG+EN_AA,0 x03);/频道 0、1 自动应答SPI_RW_Reg(WRITE_REG+EN_RXADDR,0 x03);/允许频道 0、1SPI_RW_Reg(WRITE_REG+RF_CH,0);/设置信道工作为 2.4GHZ,收发必须一SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);/谖收数谖收数据长度SPI_RW_Reg(WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);接接收数据长度SPI_RW_Reg(WRITE_REG+RF_SETUP,0 x07);/设置发射速率为 1MH

4、Z 发射功率为最大值 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&am

5、p;0 x0e;who|=0 xf0;/通道 0:who=0 xf0;通道 1:who=0 xf2SPI_RW_Reg(WRITE_REG+STATUS,0 xff);/接收至 U 数据后 RX_DR,TX_DS,MAX_PtB 置高为 1,通过写 1 来清楚中断标志CSN=0;SPI_RW(FLUSH_RX);CSN=1;returnrevale;voidmain(void)uchari;ucharRxBufTX_PLOAD_WIDTH;init_NRF24L01();StartUART();ms(6000);while(1)/如果接收到数据,发往 PCSetRX_Mode();if(nRF

6、24L01_RxPacket(RxBuf)R_S_Byte(who);ms(10000);for(i=0;iTX_PLOAD_WIDTH;i+)R_S_Byte(RxBufi);ms(10000);))发送1-uintconstADDRESS0ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;其余与双工通信相同发送2-uintconstADDRESS1ADR_WIDTH=0 xc4,0 xc3,0 xc2,0 xc1,0 xc0;/频道 1 接收地址其余与双工通信相同以上就是简要的代码。也是重要的地方。如果发送端要发送数据的话,可能在配置自动应答的接受地址时会遇到

7、一些问题。(因为是以通道 0 作为应答通道,而发送模式又必须使得接收发送地址一致,这样给两台发送机发数据就要对 0 实时配置地址)笔者尝试过配置,没有成功,只好不配置了,都是这样接收端无法接收到自动应答的信号24l01双向通讯2010-11-1921:28一周的时间过去了,终于搞出来了双向通讯,中间出了点莫名奇妙的情况,导致我迷惘了很久。上次发的头文件和.c文件有个模式设置的选项。在做双向通信的时候发现这个有点多余。所以就删掉了,内容也做了些小改动。所以就只发修改的部分24l01.h这个文件和之前的一样。只去掉#defineTMODE这几行24l01.c修改了三个地方。分别是1、*/*NRF2

8、4L01初始化/*这里不用设置什么模式,等需要接受或发送数据时指定模式/*/voidinit_NRF24L01(void)us(100);CE=0;/chipenableCSN=1;/SpidisableSCK=0;/SpiclocklineinithighSPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);同本应地址SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTHf/接遍!地址SPI_RW_Reg(WRITE_REG+EN_AA,0 x01);/频道0自动ACK应

9、答允许SPI_RW_Reg(WRITE_REG+EN_RXADDR,0 x01);施许接收地址只有频道0,如果需要多而道可以参考Page21SPI_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,0 x07);/设置发射速率为1MHZ发射功率为最大值0dB)2、/*/*函数:voidSetRX_Mode(void)/*功能:数据接收配乐/*/voidSetRX_Mod

10、e(void)(CE=0;SPI_RW_Reg(WRITE_REG+CONFIG,0 x0f);/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_

11、PLOAD,tx_buf,TX_PLOAD_WIDTH);/装载数据SPI_RW_Reg(WRITE_REG+CONFIG,0 x0e);/IRQ收发完成中断响应,16位CRC主发送CE=1;/置高CE激发数据发送us(10);以上就是全部的修改。这两个文件同样适用于单工通信。以下给出这次测试用的两个主函数。为了方便与上次的文章对应。这里还是以接收,发送区分。接收#includenrf24l01.h#includedelay.hucharTxBufTX_PLOAD_WIDTH=0 x55,0 xaa;*串口初始化*voidStartUART(void)/波特率2400SCON=0 x50;TM

12、OD=0 x20;TH1=0 xF3;TL1=0 xF3;PCON=0 x00;TR1=1;H*voidR_S_Byte(ucharR_Byte)SBUF=R_Byte;while(TI=0);/查询法TI=0;通过用将接收到数据发送给PC端/*主函数*voidmain(void)uchari;ucharRxBufTX_PLOAD_WIDTH;init_NRF24L01();StartUART();ms(6000);while(1)/如果接收到数据,发往PCSetRX_Mode();if(nRF24L01_RxPacket(RxBuf)for(i=0;iTX_PLOAD_WIDTH;i+)R_

13、S_Byte(RxBufi);/发送0 x55,0 xaa要求发送端发数据nRF24L01_TxPacket(TxBuf);/SPI_RW_Reg(WRITE_REG+STATUS,0XFF)加上这句后,会出现接收到几组数据后停了B收的现象,疝因未知ms(130);/这个延时很重要,延时过短,数据包丢失。/延时过长,减慢速度,甚至无法接收(实验时出现的问题,原因未知)RxBuf0=0;RxBuf1=0;发送includenrf24l01.h#includedelay.hucharTxBufTX_PLOAD_WIDTH=0 x01,0 x02;voidmain()charRxBufTX_PLOA

14、D_WIDTH=0;init_NRF24L01();nRF24L01_TxPacket(TxBuf);ms(6000);while(1)SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)/将收到的数据发回接收端检验是否正确/如果设置的数据较长,应使用for循环TxBuf0=RxBuf0;TxBuf1=RxBuf1;nRF24L01_TxPacket(TxBuf);SPI_RW_Reg(WRITE_REG+STATUS,0XFF);ms(90);/这个延时一样很重要RxBuf0=0;RxBuf1=0;)以上就是这周忙活的东西了,高手不要见笑。PS:原先想要使用自动重

15、发功能的,结果发现自动重发的话,传输速率很慢,没有延时的快。也可能是我自动重发的延时没设置好。另外最开始几天一直在做中断通信,如果使用IRQ上中断来接受数据,可以明显减轻MCU勺负担。可是我测试了几天下来发现一个无语的结果。在中断里读出来的STATUS的值是0 x00,顿时心灰意冷。网上有其他人貌似做出来了,可惜我写的跟他们一样也不行啊一,不知道问题在哪。但有一点是肯定的:接收到数据时必然引起中断。过几天继续贴出多机通信的代码。nrf24l01的51驱动程序2010-11-1318:58随着物联网时代的到来,无线通信技术日趋重要。nrf24l01是适合初学入门的无线模块。于是乎我就一头埋进去,

16、苦干一周有余。发现网上的程序都是抄来抄去的,不甚寒心。抄也就算了,光抄错的!后来自己动手研究,完成了SPI接口的操作,继续攻克无线模块,最终无果,只好再找代码。终于找到了一个可以的。本来想直接贴出来的,但为了许多和我曾经一样迷茫的同胞可以顺利进入无线领域。我特意修改代码,整理出nrf24l01.h与nrf24l01.c,一则便于模块化管理,二则,便于使用,便于二次开发。同时,增加了许多注释。代码中应该还有许多不足的,甚至多余的东西,后续将会继续发表一篇关于无线模块开发的注意事项。/nrf24l01.h#ifndefNRF24L01_H#defineNRF24L01_H#include#defi

17、neTMODEtypedefunsignedcharuchar;typedefunsignedcharuint;*sbitCE=P1A0;3sbitSCK=P1A1;/5sbitMISO=P1A2;/7sbitCSN=P1A5;/4sbitMOSI=P1A6;/6sbitIRQ=P1A7;/8*#defineTX_ADR_WIDTH5/5uintsTXaddresswidth#defineRX_ADR_WIDTH5/5uintsRXaddresswidth#defineTX_PLOAD_WIDTH32/20uintsTXpayload#defineRX_PLOAD_WIDTH32/20uint

18、sTXpayload*配置收发状态,CRCK验模式以及收发状态自动应答功能设置可用信道设置收发地址宽度设置自动重发功能设置工作频率设置发射速率、功耗功能设置状态寄存器发送监测功能地址检测频道0接收数据地址频道1接收数据地址*SPI-IO端口地址、数据长度*NRF24L01寄存器指令#defineREAD_REG0 x00/#defineWRITE_REG0 x20/#defineRD_RX_PLOAD0 x61/#defineWR_TX_PLOAD0 xA0/#defineFLUSH_TX0 xE1/#defineFLUSH_RX0 xE2/#defineREUSE_TX_PL0 xE3/#d

19、efineNOP0 xFF/*读寄存器指令写寄存器指令读取接收数据指令写待发数据指令冲洗发送FIFO指令冲洗接收FIFO指令定义重复装载数据指令保留寄存器地址*SPI(nRF24L01)#defineCONFIG0 x00/响应方式#defineEN_AA0 x01/#defineEN_RXADDR0 x02/#defineSETUP_AW0 x03/#defineSETUP_RETR0 x04/#defineRF_CH0 x05/#defineRF_SETUP0 x06/#defineSTATUS0 x07/#defineOBSERVE_TX0 x08/#defineCD0 x09/#def

20、ineRX_ADDR_P00 x0A/#defineRX_ADDR_P10 x0B/0 x0C/频道2接收数据地址0 x0D/频道3接收数据地址0 x0E/频道4接收数据地址0 x0F/频道5接收数据地址0 x10/发送地址寄存器0 x11/接收频道0接收数据长度0 x12/接收频道0接收数据长度0 x13/接收频道0接收数据长度0 x14/接收频道0接收数据长度0 x15/接收频道0接收数据长度0 x16/接收频道0接收数据长度0 x17/FIFO栈入栈出状态寄存器设置/*voidinit_NRF24L01(void);uintSPI_RW(uintuchar);ucharSPI_Read(

21、ucharreg);voidSetRX_Mode(void);uintSPI_RW_Reg(ucharreg,ucharvalue);uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars);uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars);unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf);voidnRF24L01_TxPacket(unsignedchar*tx_buf);/*#endif/nrf24l01.c#includenrf24l01.h#

22、includedelay.huintbdatasta;/状态标志sbitRX_DR=staA6;sbitTX_DS=staA5;sbitMAX_RT=staA4;uintconstTX_ADDRESSTX_ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;/本地地址uintconstRX_ADDRESSRX_ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;/接收地址*#defineRX_ADDR_P2#defineRX_ADDR_P3#defineRX_ADDR_P4#defineRX_ADDR_P5#defineTX_ADDR#d

23、efineRX_PW_P0#defineRX_PW_P1#defineRX_PW_P2#defineRX_PW_P3#defineRX_PW_P4#defineRX_PW_P5#defineFIFO_STATUS/nrf24l01.h结束/*NRF24L01初始化*/voidinit_NRF24L01(void)(us(100);CE=0;/chipenableCSN=1;/SpidisableSCK=0;/SpiclocklineinithighSPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);/g本地地址SPI_Write_B

24、uf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTHf/接遍!地址SPI_RW_Reg(WRITE_REG+EN_AA,0 x01);/频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG+EN_RXADDR,0 x01);施许接收地址只有频道0,如果需要多而道可以参考Page21SPI_RW_Reg(WRITE_REG+RF_CH,0);/设置信道工作为2.4GHZ;收无必须一致SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH)置掇收数据长度, 本次设3为32字节SPI_RW_Reg(WRITE_R

25、EG+RF_SETUP,0 x07);/设置发射速率为1MHZ发射加率为最大值0dB#ifdefRMODESPI_RW_Reg(WRITE_REG+CONFIG,0 x0f);/IRQ收发完成中断响应,16位CRC,主接收#endif#ifdefTMODESPI_RW_Reg(WRITE_REG+CONFIG,0 x0E);/IRQ收发完成中断响应,16位CRC,主接收#endif)/*/*函数:uintSPI_RW(uintuchar)/*功能:NRF24L0酌SPI写时序/*/uintSPI_RW(uintuchar)(.uintbit_ctr;for(bit_ctr=0;bit_ctr8

26、;bit_ctr+)/output8-bit(MOSI=(uchar&0 x80);/outputuchar,MSBtoMOSIuchar=(uchar1);/shiftnextbitintoMSB.SCK=1;/SetSCKhigh.uchar|=MISO;/capturecurrentMISObitSCK=0;/.thensetSCKlowagainreturn(uchar);/returnreaduchar/*/*函数:ucharSPI_Read(ucharreg)/*功能:NRF24L0宿SPI时序/*/ucharSPI_Read(ucharreg)(.ucharreg_val

27、;CSN=0;/CSNlow,initializeSPIcommunication.SPI_RW(reg);/Selectregistertoreadfrom.reg_val=SPI_RW(0);/.thenreadregistervalueCSN=1;/CSNhigh,terminateSPIcommunication/*/*功能:NRF24L0慎写寄存器函数/*/uintSPI_RW_Reg(ucharreg,ucharvalue)(一一uintstatus;CSN=0;/CSNlow,initSPItransactionstatus=SPI_RW(reg);/selectregister

28、SPI_RW(value);/.andwritevaluetoit.CSN=1;/CSNhighagainreturn(status);/returnnRF24L01statusuchar/*/*函数:uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)/*功能:用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数/*/uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)(uintstatus,uchar_ctr;return(reg_val);/returnreg

29、istervalueCSN=0;/SetCSNlow,initSPItranactionstatus=SPI_RW(reg);/Selectregistertowritetoandreadstatusucharfor(uchar_ctr=0;uchar_ctruchars;uchar_ctr+)pBufuchar_ctr=SPI_RW(0);/CSN=1;return(status);/returnnRF24L01statusuchar)/*/*函数:uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)/*功能:用于写或据:Z寄存器地址,pBuf

30、:为待写入数据地址,uchars:写入数据的个数/*/uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)(一一uintstatus,uchar_ctr;CSN=0;/SPI使能status=SPI_RW(reg);for(uchar_ctr=0;uchar_ctruchars;uchar_ctr+)/SPI_RW(*pBuf+);CSN=1;/关闭SPIreturn(status);/)/*/*函数:voidSetRX_Mode(void)/*功能:数据接收配A/*voidSetRX_Mode(void)CE=0;#ifdefTMODESPI_

31、RW_Reg(WRITE_REG+CONFIG,0 x0f);/IRQ收发完成中断响应,16位CRC,主接收#endifCE=1;us(130);/*/*函数:unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/*/unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)unsignedcharrevale=0;sta=SPI_Read(STATUS);/读取状态寄存其来判断数据接收状况if(RX_DR)/CE=0;/SPISPI_Read_Buf(RD

32、_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);/readreceivepayloadfromRX_FIFObufferSPI_RW_Reg(WRITE_REG+STATUS,sta);/掇收至U数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志returnrevale;/*/*函数:voidnRF24L01_TxPacket(unsignedchar*tx_buf)/*功能:发送tx_buf中数据/*/voidnRF24L01_TxPacket(unsignedchar*tx_buf)CE=0;/StandByI模式SPI_Write_Buf(WR

33、ITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH装/载向I攵端地址SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);/装载数据#ifdefRMODESPI_RW_Reg(WRITE_REG+CONFIG,0 x0e);/IRQ收发完成中断响应,16位CRC主发送#endifCE=1;/置高CE激发数据发送判断是否接收到数据使能revale=1;/读取数据完成标志us(10);/nrf24101c结束文中用到的“delay.h”中一个us延时,一个ms延时,读者可以自己写。(由于晶振不同,延时函数不同,这里就不列出了)这两个文件同时包含了收发模式。通过/模式选择#defineRMODE/#defineTMODE进行切换。以下顺便给出接收,发送主函数,便于

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论