![51单片机 NRF24L01 无线模块_第1页](http://file4.renrendoc.com/view/609a28c4616720f9cc055f73b211f568/609a28c4616720f9cc055f73b211f5681.gif)
![51单片机 NRF24L01 无线模块_第2页](http://file4.renrendoc.com/view/609a28c4616720f9cc055f73b211f568/609a28c4616720f9cc055f73b211f5682.gif)
![51单片机 NRF24L01 无线模块_第3页](http://file4.renrendoc.com/view/609a28c4616720f9cc055f73b211f568/609a28c4616720f9cc055f73b211f5683.gif)
![51单片机 NRF24L01 无线模块_第4页](http://file4.renrendoc.com/view/609a28c4616720f9cc055f73b211f568/609a28c4616720f9cc055f73b211f5684.gif)
![51单片机 NRF24L01 无线模块_第5页](http://file4.renrendoc.com/view/609a28c4616720f9cc055f73b211f568/609a28c4616720f9cc055f73b211f5685.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、NRF24L01+NEic公司生产的一个单芯片射频收发器件,是NRF24LO:的升级版,也称耐24LO氓是目前应用比较广泛的一款无线通讯芯片,与前而的版本兼容,具体手册资料网上非常多。它工作在2.4.5GHS频段,数据传输率:1或2MbpS,自动应答圧自动重发功能,可接受丽电平的输入.工作电压1.9飞6讥详细的资料我不多说了,芯片见下图;VDDVSSANT2ANTIVDDPA由于高频电路的设计在元件的摆就位置、,电路的走线方法都有很高的套求,因此我们直接便用现在成品模块。这样拢们就不用去芳虑高频电路的设计间题了。下面是NRF24L02+模块的PCB图和实物图.GNDIUCCICECSNSCKn
2、csiMISOIRQ引脚号名称接口性质描述1GND接电源地电源地2VCC接电源正(+刃)电源正。范围在19一3即3CE模块输入信号由单片机给出信号控制NRF24L01模块商部身寸频电路工作与否4:CSN模块输入信号模块的片选信号,单片机发岀信号来控制允许向模块读或写数据5SCK模块输入信号串行时钟信号。由单片机发出,来控制模块的读或写的运作节拍。6MOSI模块输入信号是单片机NRF24L01模块发送数据的接口7MISO模块输岀信号是NRF24L01模块向单片机送数据的接口111.丄人lI-X-1ti-f、111.il.K1亠f11liJki1IJl亠F面说说模块的各引脚的功能:;接单片机电源j
3、单片机:!(MCU):I;接单片机I/O口:iIVCIN4007X3ZFUdITGNDNRF24L01+VCC模块CECSN HYPERLINK l bookmark2 SCKMOSIMISOIRQ我们要做的电路很简单,元件就接了3个二极管降压,一个电阴,一个瓷片电容.降压后电压为3V左右。下图为实物:插上NRF24L.01模块这样我就可以直接将这个电路插上拢的A789C2051最小系统板了我2051板子的引线挑列和原来IC排列基本一致:曰5+L.O心0LL0N021202193184175166157148139121011RST/YPP匚(RXD)P3.0匚(TXD)P3.1匚XTAL2L
4、XTAL1匚O)P3.4匚1)P3.5LIGMDvccP1.7Pk6P1.5P1.4Pk3P1.2P1.1(AIN1)P1.0(AINO)二IP3.72-*0-7赳卩备豈+o6o6o6o6o6o6c6+caCLCLCLCLCLCLCL00O0拢再将串行控制的LCD12飯4也插上,就可囚坐下来写程序调试啦!电路的制做就基本完戚了,接下来就是软件的活了在打开电脑前还是得要蹲蹲马歩“先说说单片机如何与旺F2虹01+进行通讯以便能完戚各种指第,时圉L01+与很多模块一样采用串行设备接(SPI)协谊来进行通讯的口它一股是通过四根线:1根输出线、1根输入线、1根串行时钟线和一根控制线来Cn-SPI指令笹S
5、n-状态寄存器位Dn-据位(备注:由低字节到高字节每个字节中高位在前)CSNsck_rLrmTmjTrLrLrLmTnjirLrLnrLrLTLrLrLrLrmmsoS可可可並X可匚口0000000卫Z回Hi迥回叵I可一SPI读操作CSNSCKruwwwuwwwuuwwwuLmosi3叵(門匡回叵回可卫二回可叵叵回門邑CZE更)門E阿門可叵SPI写操作上图就是服F24L01模块与单片机建立通讯的时序图。看懂它,是你用单片机控制这个模块,与它建立通讯的基础条件。很多串行通讯设备都采用这种方式,也SP匚它一股有四根连线:第一根是片选信号线,单片机可以同时连接多个功能相同或不同的模块,为了节省输入输
6、出仃/0)信号线的资源,一般都将多个模块连接在相同的SCKsMOSL皿SO线上,这叫串行总线。那单片机发出指令后,模块怎么知道指令是发给自己的而不是发给其它模块的呢?这就靠每个模块上和单片机专线连接的CSN片选信号线,平时CSM是高电位的,当把这根线的电位拉低那一时刻,模块就知道单片机妾给自己发指令了。接下来单片机就可以把指令数据皴在MOST线上了,指令一般是1个字节长度,1个字节罡&个位,一个位可以代表0或1的馥据,对于物理意义上的一根连线血S:来说就是低电位或是高电位,单片机将1条个指令的8个位,从最高位C7开始,逐位将数据旗上MOSI线,如果C7是0,那单片机就将MOSI线电们拉底,如果
7、是1,就将MOSI线首高电位,如此一位一位的进行。那模块是如何知道单片机什么时候已将数据畝好,模块可以取走数据了呢,这就靠时钟线了,时钟线在CS1碗低前也应该是低电位做好准备的,当单片机将一位数据啟好后,就将时钟线电位直为1来通知模块.这时模块接收到时钟线由0转为1时,知道单片机已将数据诙好在HOSI线上了,就将线上的电位数据0或:Lii取后存入数据寄存器內。同时模块也在时钟信号还是底电位时将自己的状态信息馥据所对应位数据啟在M珈线上,等到单片机将时钟信号萱1时便可以读取MISO线上的数据了.这就是单片机在写馥据给模块的同时也读取到模块的状态息.就这样时钟信号拉低就畝数据在线上,当时钟信号转为
8、L,孜方就读取,一个位,一个位地完成一个字节的指令发送。在通讯过程中单片机杲完全的指挥考,无论是妾写数据到模块还是想从模块读取相应馥据,都是由单片机先发出指令,所以从上图可以看到无论是读操作还杲写操作,都杲由恥久向模块发送第一个宇节的数据(也就挹令名称挹令格式操作RREGISTER00OAAMA读配寄存器。AAAAA指所要i卖操作寄存器的5个位的地址.REGISTER001AAAAA写配寄存器MAAA是所要写操作的寄存器的5个位的地址只有在掉电模式和待机模式下可操作R_RX_PAYLOxW01100001读RX有效数据12字节;读操作从字节0开始。当RX有效数据读取完成后,FIFO寄存器中有效
9、数据被清除。应用于接收模式下XTX_PAYLOAD10100000写TX有效数据,1-32字节。写操作从字节0开始。应用于发射模式下FLUSHTX11100001清除TXFIFO寄存器。应用于发射模式下FLUSH_RX11100010清除RXFIFO寄存器,应用于接收模式下在传输应答信号过程中不应执行此指令,也就是说若传输应答信号过程中执行此指令的话将使得应答信号不能被完整的传输REUSE_TX_PL11100011重新使用上一包有效数据。当CE为咼过程中,数据包被不断的重新发射。在发射数据包过程中必须禁止数据包重利用功能。NOPmimi空操作。可以用来饯状态寄存器我们先对这些指令分析一下,从
10、上面的指令列表可以看出,指令种类芥不多,扌旨令加上蔑操作的寄存器地址才一个宇节的长度,其中高3位是指令的种类,如OOOB(B表示二进制)代表读取寄存器指令,而00佃代表写寄存器指令.后面的5位用来指定要操作的寄存器地址,因为只有5位,所以寄存器地址也就在32范围內。这是前两条读和写寄存器指令,后面的R_RX_PAYLOAD、VLRX_PAYL0AD就是专用指令,就是连续谯出和写入需要接收或发送的数据包内容,一个数据包最大可以容纳贮个宇节。指令巩USHJC、F1USH_RX也是专用指令,就是清除发送数据包寄存器OXFIJg)或接收数据包寄存器FIFO)里的内容。REUSE_TX_PL指令也是专用
11、指令,是当模块发送裁据不成功,可以再次把发送馥据包寄存器(位FIFO)里的数据再进行使用而不用再次重新写入了。恥P指令罡个空操作,指令的整字节都是L就相当于片选信号线CSN拉飯后,将MOSI苴为1,然后只控制时钟信号的高和低,以便从MISO上逐位读出一个字节的状态数据.这样只用一个字节的时间就完成了模块状态的读取,并且在这个指令操作过程中MOSI线上始终是1,没有再操作过,所以就是空操作。下面我们看SWRF24L01P里面的寄存器都是做什么用的;地址参数名称位复位值类型描述00HCONHG配置寄存器reserved70R用固定为0”MASK_RX_DR60R/W是否屏蔽RX_RD产生中断信号1
12、:IRQ引脚不产生RX_RD中断0:RXRD中断使IRQ转为低电平产生中断信号MASK_TX_DS50R/W是否屏蔽TDJRS产生中断信号1;IRQ引胸不生产TX_RS中断0:巧JRS中断使哝Q焦为低电平产生中断信号MASKAX_RT40R/W是否屏就MA戈RT产生中断信号1:IRQ引脚禾产生中断0=MA*RT中断使吸Q弟脚转为低电平产生中断CRCO20R/W0:为g位CRC胶验1:为16位CRC校验PWRJJP10R州对射频电路是否给电;1:上电0;掉电PRIfLRX0R/W设定射频电路的工作模式;1:接收模式0;发射模式资料列表很多,我就不一_列出了,想详细了解的就下载模块说明书,或向我要
13、,我也可以发给你,这里我只说说如何使用。从列表可以看出大部分的的寄存器都是单字节的。只有两种寄存器是多字节的,_类是有救数据据缓沖寄存器戈FIFO和RXFIFO,它最长罡贮个字节,也就是说,模块一次最大可发送贮个字节的馥据。不过它们都是由专用指令R_RX_PimOd和V_TZ_PAYLOAD来操作,不用给出具体的寄存器地址”还有_类就是发送或接收地址寄存器,如发送机地址T3LADDR、0通道接收地址RX_ADDR_PO等六个接收通道地址。地址最长可以有5个字节,具体操作和时序表上描述的一样,具体操作:前面介绍时序图时已经讲过单片机是如何用串行方式实现通过恥肛和MISO来读写一个字节的数据过程。
14、现在我们就讲这具体的每个字节都怎么用,从前面的指令表里我们看到了只有那么几种指令方式,如读寄存器指令化REGISTER它的指令码就是最高三位的000再加上后5位的寄存器地址,例如寄存器SETUP雇用来设置发送和接收机的地址宽度的。它的地址是03,也就是二进制的口,壤满5位就是00011,和前蔚的3位指令加在一起就是00000011.这就是_个字节。你只要把这个字节数据写到模块里,接下来你就可以读出代表接收和发送机的地址宽度的数据了。再比如我们要设:H模块的配買寄存器(就是上面列出的那个寄存器),它的地址是0填满二逬制的5位就是00000,再和高3位的写指令001相加,就是00100000o这样
15、你先写进这个字节的指令再接着写迸你要设萱的数据值。这样我们一谀操作都是两个字节,第一个字节是写指令(包括要操作的寄存器地址),第二个字节是读取或写入所需的获据。如果罡设置发送机地址的话,就是设MADDR地址是迈,十六进制是:LOH。二进制就杲10000,那么再加上高$位的指令001*00110000,先写这个字节进模块,然后接着写5个字节的地址数据。同样,要读出发送机地址,就先写一个字节的扌旨令00010000,接着就读出那5个地址数据。如果罡从接收缓沖寄存器读取接收到的数据包,那就直接用指令R_RX_PAYLOAD,就是二进制01100001,然后就读取最长贮个字节的馥据就可以了,写将宴发送
16、的数据到发送缓沖寄存器也是一样的,先写发送指令10100000o接着再写进最长贮个字节的数据就可以了好了丨上面说的都是完成单片机与NKF24L01+之间的通讯,下面说说当拢们设苴好了模块的所有数据后如果发送或者说发射这些数据呢?先看下表:模式PWRUPPRIIRXCEFIFO寄存器状:态按收模式111模块进行对无线信号检测接收发送模式101将TXFIFO中的数据发送,直至发送完特机模式2101TXFIFO中的数据发送完了,为空待机模式110无数据倍输理巩_感也是配叠寄存器CONFIG里的参数,T表示接收模式,G表示发射模式。CE则是我们模块上的一根物理上的连接线,从表中可以看出,当它设宣为匕时
17、,相对应表搭里的模式条件就全都满足了。所以,它是我们设苴完所有寄存器后,最后启动的开关。当我们想妾发送数据时,把吏发送数据畝到宓FIFO里,设首好自己的本机地址,给射频电路上电,设为发送模式,最洽将CE置为1。这时发射电路就会启动将数据打包加上CRC校验码,发送出去”当我们要接收数据时也一样,先设置好接收通道地址,给射频电路上电,设苴为捋收模式,最后将CE设置为fr这时射频电路就接收无线信号了。NRF24LO1模块说明书里说,模块在接收模式下可以接收6路不同通道的数据,每一个数据通道使用不同的地址,但杲共用相同的频道。见下虱PTX3PTX4PTX1PTX2PTX5PTX6PRXFrequenc
18、yChannelN原来一个发送过程并不只是发逶机独自一个人的事情。一开始,发送机发送连同身份地址在內的馥据包给接收机,接收机收到数据并确认正确后,就以剛才发送机发来的身份地址回发一个确认信号,而此时发送机会自动切换到接收状态,当收到确认信号与通道0的地址进行比较,地址相吻合,就知道对方收到数据,这样一袂发送馥据才算完毕。当拔,这个过程是模块內割自动完成的,不用人为干预因此这就叫做増强模式。在这个过程中发迸收方都最少各有一次发迸和接收的过程。这样就保证了数据可靠收到.如果发送一次,接收机没肓收到,模块具有允讦重发,和重发次数设置寄存器,当你设置了允讦重发,并设置好重发次数.在发迸机发迸完一个数据
19、包,等待一会儿,如果没有接收到应答信号,发送机就会重发一次,如此直到重发完你设定的次数,再收不到它就产生一个中断信号给IRQ,告诉模块没有发送成功,由程序根据情况再决定是否重发。下面我们归纳一下设叠一次发送数据的歩骤=lx写本机身份地址到TXADDR。2、写0通道接收地址到RX_ADDR_PO(与宓DDR地址一样,是为了接收应答信号)3s设直自动应答允许,EN.AA-厶设苴0通道允讦接收,ENRXADDR.5、配首自动重发次数SETUP.RETRo6、选择通信频道RF_CHb(要求发送接收的一组通信机使用同一个频道)Ts配買发射参数(如发射功率、数据传输速率)RF_SETUP设首0通道有数馥据
20、宽度RX_PV_PO(就是要传送数据包的长度)9、设宣模块配置寄存器CONFIG到发送模式./VlCrt将要传送的数据写入发送缓沖寄存器TXFIFOik,进入发送状态.设置接收数据飽步骤=写发送机身份地址到0通道接收地址RX_ADDR_POo龙2、卜樓置自动应答允许EM_AA设置允许0通道接收数据EN_RXADDRo4、选择通信频道RF.CH5、选择0通道有效数掳宽度RX_FW_POG、配置发射参数(发射功率数据传输速率RR_SETUP二U设置模块的配置寄存器CONFIG在接收模式8、将CE设置为T,进入接收状态。好!有了以上这些知识,我们便可以进入实际的上机调试了!今天刚调试好,先看图吧!这
21、张是AT89C2051控制NRF24L01+做发射调试。看看NRF24L01细节吧!这是LCD屏显示AT89S52做接收测试:正在接收时的显示:接收到数据后显示32个数据值:411X-t41t05050B35110.-239II3-:X4Q493-税49-H-J七21-10一0Fy3HL301122x-J4T-2-F2TE了ZR2711223r(八丄4-.1ITO这一篇要讲NRF24L01+模块的实际电路调试,在操作前还要说说关于模块说明书上的几点注意;1、与51系列单片机P0连接时,需要加10K的上接电阻,其余连接时不需要。这一直应该很好理解对逹接逻辑模块来说,51系列单片机郤需要逹接上拉电
22、阻,否则就无法有效输出高电位,而会出现“悬空,的不稳定状态。不清楚的可以看我轉客的第16篇&谈谈AT29S51的上拉电阻间题2、其它系列单片机,如果是冈的,请参考该系列单片机10输出电流大小,如果超过lOrnA,需要串联电阻分压,否则容易烧毁模块!如果是3.3的,可以直接和模块的10口线连接,比如职R系列单片机如杲是刃的,一股串联2K的电阻。这一点要从单片机输出电路来分析,看下圈:说明书上说单片机输出不能超过10血,也就是说在模块內的Rx上不能超过10皿的电流,否则就烧毀模块了。这就要看我们单片机綸出的电路了,要向Rx输出电流,那单片机的控制管就在截止状态,输出高电位,这时电源电压讥工通过R向
23、Rx输出电流,如果VCC是3.3E的,模块说明书上说了是安全的,可以直接连接,就是说肯定不会超过它规定的10皿,如果VCC是弭电压,那就要看我们单片机输岀口內的上拉电阻R的大小了,上拉电阻太小就会使RX超电流。囲此大家在使用时可以看具体单片机的说明书,如杲输出口是强电流型,那么输出口內部的这个上拉电阻可能就很小甚至是三极管直接输出。如果是逻辑输出型,那一般输出电流很小,不会对模块造成伤害的,如AT89C2051,我把P1口置高电忆然后用电流表接4P1.7和地之间看看它能输出多少电流,测得的值是25皿,折算一下,上拉电阻R大约为200K欧姻。因此是安全的,具体煙接见下閤:TRAP1上團就是实物连
24、接團下面我们打开电脑编写程序,首先我们要将LCDL2864模块的程序调试正常才能为后面的NRF24L01模块调试在KEIL坏境里我加入了两个C模块,一个是LCD12864模块程序,还有一个就是要调试的主程序NRF24L01m主程序如下:/W24L01+模块发射程序单独调试/TxzOOl2011.09.289f入*L*入入入入*入入入1111a11L111asIITT(TJTT(|!|TT|T)T(T!T|TTexternLcd_Clr(void):/清屏,清屏后需16ins延时externvoidLcd_Init(void);/LCD初始化externvoidhanzi_Disp(ucharx
25、,uchary,uchar*s):/在设定位資显示字符串uchar*uchaxtstr(ucharururi);/将一个字节数据unm值转緞字符串ucharstr4;/作为存储上面uchartostir函数转换:的字符串将char值转成字符串函数uchar*uchartostr(ucharunm)ucharxOO,xx,xO,x,n;x00=umn/100;xx=uirfl00;x0=xx/10;x=xx%10;n=0;if(x00=0)strnxOO+48;/值加船艮卩为字符n+;)if(I(xOO二二0&x0=0)strn=x叶48;n+;strn=x+48;n+;strn=W;retur
26、nstr;/*水水水*主函gr*;*voidmain()(ucharimp;/定义一个l|缶肘变量tmp二251;hanzi_Disp(O50,W24LO1发射测试”);显示hanzi_Disp(2,0,BLOG:http:/hi);hanzi_Disp(3503/txzQl);while(1)hanzi_Disp(1,3,uchartostr(tinp);/显示数值变蜀delayms(800);/delayms(800);/hanZi_DiSp(1,0/“);清馀上次的显示delayms(800);最上面用外部定义语句extern定义了3ELCD12864程序模块里的函数,以便在主程序里能调
27、用它。目前在这个主程序里实际上没有一句关fliRF24L01的语句。只是初始化LCD,然后在屏幕上显示标题和我的博客信息字符,在后面的whileO循坏里也是在屏皋上闪烁显示用uchartostrO函数转换变蜀tnp的值。就是通过这些语句,可$测试LCD模块接口定义的正确与否、显示字符是否正常、数据转字符函数运行正确与否。如果一切正常,那么显示应如下團所示。这样我们就完成了第一步:LCD模块的测试,后面我们调试W24L01模块葱可以不用考虑LCD显示的问题了。接下来我们就往主程序里添力DNRF24L01的语句,接著外部定义函数后面,我们定义NRF24L01的接口:/*nrf24L01模块10端口
28、定义材林水*sbitCE二Pl;sbitCSN二Pl飞;/NRF24L01+模块发射程序单独调试/TxzOOl2011.09.28/A=M=M=4=H=M=M=M=m=M=m=M=M=M=M=M=H:?include#includeintrins.htypedefunsignedcharuchar;/W无符号字节类型重宦义为uchartypedefunsignedintuint;/将无符号整魏类型重定义为Uintextexnvoiddelayms(uintt);/7莹秒延时,在LCD12864里定义exteznLcd_Clr(void);/清屏,清屏后需1-6ms延时extexnvoidLcd
29、_Init(void);/LCD初始化extexnvoidhanziDisp(ucharx,uchar兀uchar=t=s);/在设定位置见示字蒋車uchar*uchartostx(ucharuron);/W个字节数据unm值转成字符串uchar航工4;/作为存储上百uchaitostr函馥转换的字符串/柑=t=t*M=tNRF24LO:L模块10端口定义柑*t=M=t=t=样样的sbitCE=P17;sbitCSN=?r6;sbitSCK=P1a5;sbitMOSI二Pl4;sbitMISO=P1a3;sbitIRQ=P1A2;ucharstatus,定义一个变量用来装读取到的STATUS数
30、值/char值转成宇符串函馥uchar*uchaztostz(ucharuron)ucharxOO,x禺*0,n;xOO二unn/lOO;xx=unjn%100;x0=xx/10;x=xx%10;11=0;if(x001=0)strn-xOO+48;/值加48即为字符屮;if(Hx00=0&x0=0)strn=x0+48;十;strn=x+48;片strn=y;工etuxn.str;/=w=m*+=+=m=i=m=+=m=t=m*w=m=i=m=i=i=m=w=i=w=m函数;uintSPI_RV(uintuchar)/*功能:NRF24L01的SPI写时序/:M=m=H=m=t=t=m=t=
31、t=m=m=m=t=w=m=t=t=m=m=t=i=f=t=tc/ucharSPI_RW(ucharuuchar)ucharbit_ci:r;for(bi-t_ctr=O;bit_ctr8;bit_ctr+)/输出8个位uuchar=(uucharSCK=1;uuchar|=MISO;SCK=0;return(uuchar);1);/肚移一位/将时钟线置仔/侗时读取STATUS/撚后再将时丰中线苴心返回读取的值A=m=m=M=M=M=M=+=M=4=M=M=4=M=M=l=m=m=M=M=M=4=+=m/=+函数:ucharSPI_Read(ucharxeg)/*功能;NRF24L01厨SPI
32、决取一个卓节时厚A=m=t=t=m=t=t=m=M=t=t=M=m=m=M=t=m=t=i=m=m=t=M=m/ucharSPI_Read(ucharreg)ucharreg_val;CSN=0;SPI_RV(reg);gNl=SPI_RH(O);读取工eg的值到reg.val/csifB0允讦指令操作/W条reg指令CSN=1;/CSN首f,禁示操作return(regnal);/返回读取的值/样=|=4=|=*=件=样=怒功能二NRF24L01写一个字节到寄存器函数Am=w=t=m=t=i=t=m=t=t=M=m=m=t=t=m=t=t=m=t=m*=m/ucharSPI_RW_Reg(u
33、charreg,ucharvalue)ucharstatus;CSN=0;status=SPIRW(reg);SPI.RV(value?;CSN=1;return(status);/CSN貫0亠,允讦操作/蜃指令,并读STATUS/禺数据值到reg/CSNMj1禁止操作/返回STATUS值卄#卄#卄=t:主函数*卄#卄#卄voidmainOCE二0;CSN=1;SCK二0;IRQ=1;status=O;/statusB0,用于后更保存義脫到的值/CEB0,射频电路停止工作/CSN置1,禁止指令操作/SCK苴0,禁止读写寄存器/IKQ置4中断真位,等待产生中断信号delaynis(100);Lc
34、d_Imt();/LCD864初始优Lcd_CO;漬屏幕delayjks;/極时2奎秒,渚屏指令需要延世1.6竜秒hanzi_Disp6NEF24LO1发射测试);/显示hanzi_Disp(2,0,BLOGlhttp:/hi);hanzi_Disp(3,0,./txzOl);status=SPIRead(OxO7);/读卑寄芳器STATUS的值hanzi_Dispfl,6STA;);/显示提示字符“STA;”while(1)建入循环h.anzi_Disp(1,4,uchartostr(status);显不数值变壘de1ayms(800);/徳时delayms(800);/h.anzi_Dis
35、p(1343delaynLS(800);zz);/m除上伙的显示就是这最简单的读取一个字节NRF24L01模块的状态寄存器值,正确完成这一步,可以说你的调试已完成百分之八十了。为什么这么说呢?因为它标志著你的接口都连接并定义正确、NRF24L01模块已正常工作,你的串行读写程序都能正确运行,你与模块已建立了正常的通讯。说明后面的工作已伸手可及。通过査寄存器表可知,STATUS(07H)在上电复位后的值是1110B,+进制就是14。我们再把读取的寄存器换成CONFIG(OOH,status=SPI_Read(OxOO),看它读出的值是多少,显示的提示我们也改一下,hanzi_Disp(l,0,C
36、ONFIG:,看査寄存器表得知配置寄存器00H)上电复位的值是1000B,就是十时制的汛好!我们完成了第二步:建立与NRF24L01的通巩。下面我们再添加进读写多字节寄存器数据的子函数,以便后面可以对发送和接收机身份地址的读写,以及对要传送的多字节数据进行读写/洪*关決96关決派关关務*关洪英关決派关关務*关浜96关決派关浜共关关浜*关決96关決派关关務*关洪未/函数:uintSPI_Read_Buf(uchaKreg,uchar*pBuf,ucharuchai-s)“功能:用于读数据,冋;为寄存器地址,status=SPI_RW(reg);/Selectregistertowritetoan
37、dredstatusucharfor(uchar_ctr=0;uchar_ctruchars;ucharctr*+)pBufuchar_ctr=SpT_RW(9);/一CSN=1;return(status);/returnnRF24L01statusuchar/*-*/未函数:uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)功能:用于写数rei:为寄在器地址,/*pBuf:为挣写入数聒地址,/*uchars:穹入皱擔阳个薮/董黄黃黄*黄董英黄66黄黄芳黄黄黃董*黄at黄黄芳黄黄黃董*黄ae英黄芳黄黄黃黄*黄董英黄at黄黄芳黄黄黃董*黄ae英
38、黄芳黄黄黃黄*黄董英黄/ucharSPI_Write_BuF(ucharreg,uchar*pBuF,ucharuchars)ucharstatus,uchar_ctr;csn=e;/spi使能status=SPI_RW(reg);For(uchar_ctr=0;uchar_ctruchars;uchar_ctr+)/SPI_RW(*pBuf*+);CSN=1;关闭SPIreturn(status);/黄美芙关黄浜英黄芙芙黄芳芙黄美浜关黄芙芙主函数关黄芙英黄芳黄关美芙关美浜英黄芙芙黄芳芙美uoidrmain()ucharaddr5=,);/显示提示字符TX_ADDR”while(l)/CEJ/
39、CSN/SCK|/IRQI7射频电路不工作盯,禁止捺作禁止读酊中断线han2i_Disp(hanzi_Disp(hanzi_Disp(hanzi_Disp(hanzi_Disp(1,uciiat-tostr(addt-0)显示数值变量,6,uchartostr(addr1);2,0,uchartostr(addr2);2,2,uchartostr(addr3);uchartostr(addr4);delayms(8O0);/delan)s(800);/hanzi_Disp(1,4,hanzi_Disp(2,0,delayms(800);B,);清除上次的显示.这次在主函数里我用SPI_Read
40、_Buf(OxlO,addr,5)函数来读取发送机身份地址寄存器TX.DR(OxlO),把5个字节的数据存在主函数前而定义的数组addr5中。然后在循环中用五条显示语句显示出发送机身份地址的数值,遠样以验证我们刚才添加进去的读和写多字节数据子函数的正确与否。运行正确后如下團:査寄存黠表TX_ADDR上电复位后的缺省值是五个E=十进制就是231,说明我们诸取操作都正确了。前面我们鄱是逹出寄存器內的数据操作,结果鄱正确了,接下来我们写进一组数据,再读出,看能否正确,我们先定义一个常虽数组,ucharconstTX_ADDRESS5=0 x05,0 x04.0 x03,0 x02,0 x01;然后把
41、这些数据写进T5LADDR寄存器,再把它读到数据变虽数组addr并显示出来,这样我们就可以知道写入的操作是否正确了。在主程序里,我们在逮取捋令SPI.Read.BuftOxlO,addr,5)的前面放进一句SPI_Write_Buf(0 x20+0 x10,TX_ADDRESS,5),这是写多个数据到寄存器的捋令。括号里第一个参是是指令亠寄存器地地址,0辺0就是写揺令,前而也说过的,而劝号后面的310就是TX_ADDR寄存器地址。第二个参数就是要写入的数据的数组名,我们在前面已经定义了送个数组常屋,它们的值分别为54,3,2,1.第三个参数是要写入的数据个数,这里是5。这样我们编译,烧写运行后
42、,看下因:kNRF24L01发射测试IITX_ADDR:54txz1(?丨II32112864G-1从上图中看岀TX_ADDR寄存器内的数据內容已由原来的5个鄱是231,变成我们写进的5,4,3,2,1T.说明写入指令正确运行!完成第三步:与NRF24L01+模块的串行通讯操作各种指令调试完成.读和写的操作都正确,下面我们就进行射频发送的调试,前面我己经说过,NRF24L01模块的发送一次数据的过程不仅仅是发送一个数据包那么一个动作,它发送完数据包后还要筹待并接收对方发回来一个应答信号,才算完成一次发送任势,如果收不到,它就不会认可发送完成,也就是说,要调试此模块发送数据,那么对方的接收机也要
43、具备完好的发射功能,因为它是一个交互过程,一呼一答才能完成一次数据传送。可我这个模块都还没调试出来,哪来的对方接收机的完好功能呢?是不是就没有办法完成单独调试了呢?案是可以的!通过查寄存器的功能显示,寄存器EN_AA(0龙01)的功能是设置每个数据通道是否允许自动应答。当为设置为0时,就禁止数据通道的自动应答了。还有一个寄存器SEW_RETR(0 xO4),它的功能是设置模块是否进行数据的自动重发功能,设置为0时就禁止自动重发了。当禁止了自动应答和自动发送后,发送过程就可以只是发送一个数据包的操作了?H那我们按步骤操作完一次发送过程,可是没有接收方的确认,我怎么知道模有没有进行完一次的发射呢?
44、这得靠模块的状态寄存器STATUSC0z07)来显示,它的第5位上,复位后为0,当数据发送完成后,就产生一个中断信号,并在此位显示1,也就是说STATUS复位洁是显示14(00001110B)的,发送数据完毕后在这个字节的第五位就应该为1,即此字节值显示为46(00101110B)o还有一个数据包缓当我们进行一次成功的发送后,它又被自动清空了。根据这两个状态寄存器,我们就可以判断模块是否成功发送数据了。下面我们加进用于发送的子函数:/黃董董黄56英黄黄黄黃黄黄董董黄策黄未黄黄黃董黄董*黄56策黄未黃黄黄黃董黄董英NRF24LX初女合化f/*/uoidinit_NRF24L01(uoid)CE=
45、0;CSH=1;SCK=O;IRQ=1;SPIRMwwwwwRRRRR_IIIIIpppppsssss/射频停止工作/停止誅器读写赠能止涙写RegCWRITEREG*EN_AA,6xOO;Reg(WRITE-Reg(WRITEReg(WRITEReg(WRITEReg(WRITE频道。自动MK应答禁止REG十SETUPRETR,0X00);禁止自动发送REG亠ENRXfiDDR,0X01);/允呑接收地址只有频道dREGRF_CH,1);“设置信道工伍为2-4GHZ,收发必须一瑟REGRX_PW_PO,RX.PLOADjnDTH);设置接收数据长度,为32字节REG*RF_SETUP,0 x8
46、7);/发射逮率为2MH2,发射功率为最大值BdB函数二uoidnRF2UL01_TxPacket(unsignedchar*tx_buF)八功能二废送txbuF中藪壇/关关洪*关決96关芳派关关務关关浜*关关96关芳派关关務*关浜捋关決9G关*派关关兴*关狭96关決96关*派关关務捋关狭/uoidnRF2-UL01xPac畑t(unsi.gnedchar*tx_buf)#关关浜*关決96关芳派关关務关关浜*关決96关*派关关務捋关来*关決英关芳派关关兴茨关狭96关未9G关*关/init_NRF24L01(void)是为了下面主函数简捷易于阅读,我们把一些为了准备发送的语句先写在这儿了。nRF
47、24L01_TxPacket(unsignedchar+tx_buf)函数就是把要发送的数据写进缓冲区,然后设置模块为发送模式,再将CE置为高们,让射频电路进行一次发送操作。下面是主函数:f/关洪*关关来关*派关关兴关关狭*关关来关三函数关狭*关关来关关派关关兴*关狭来关关来关关uoidmain(ucharstatus;ucharfiFo_s;delanis(IOO);Lcd_lnit();LcdZcirO;delans(2);_hanzi_Disp(0,0,-NRF24L01射测试*)7显示标题hanzi_Disp(3,0,txz001139.con_);/4示签名hanziDispCI,0
48、,STATUS:);显示提示字侵*TUSnanziDisp(2JFIFO_S);显示提示学特FIFOJS“init_NRF24L01();NRF24L3初殆化whiled)訂/显丞模块状态hanziDispf254,uchartostr(fifo_s)?/显示FIFO状态-;进行二次发送操作再谏蛾态S);再读取FIFO状态定义一个变量用耒装读取到的STATUS数值定义一个变量用耒存轡取到的FIFO状态延时一会,LCD上电后需要自卷“LCD1286A初始化nRF24L0i_TxPacket(TxBuF)status=SPI_Read(STATUS);fiFo_s=SPI_Read(FIFO_ST
49、ATUS);/hanzi_Disp(1,6,uchartostr(status)j;仃显丞hanzi_Disp(2,6,uchartogtr(Fifo_s):显示主函数先初始化LCD12864,并显示提示字符。然后进行NRF24L01的初始化,接下来进入循环选清除模块状态寄存器的内容,使它们都处于复位洁的状态,再将要发送的数据写入发送缓冲区。这时我们读取一下模块状态寄存器STATUS和FIFCLSTATUS,看它们的结果。然启nRF24L01_T打acket(TzBuf):语句进行一次发送操作。发送完毕后,我们再读取一枚STATUS和FIFCLSTATUS并显示。看它们和发送数据前有什么不同。
50、当我们将程序正确的编译烧写进AT89C2051,运行结果如下;|NRF24L血发射测试STATUS:1446TIFCLS:117Itxz801(?139com从显示的数据来看它们是不同的,STATUS在上电复位后的值为14(00001110),这在前面也读取过,但发送完毕洁它的值变为了46(00101110B,其中第5位上变成了1,它是TX_DS,当数据发送完后产生中断,并将此位置为1。.丫门已再来看看发送与接收数据缓冲区的状态FIFO,它在上电复位后应该为17(00010001B).我们第一次读取之前把数据写入缓冲区了。因此得出的值为1(00000001B),因为在第四位T_EMFTY上代表
51、发送缓冲区为空的1,己经变为了0,就是有数据在里面了。等完成一次发送操作,我们再读取它时,FIFO的值己经变回为17(00010001B)了,说明模块发送完毕,己将缓冲区的数据清空。到此,我们己经完成了第四步:完成NRF24L0M单独发送调试。下一篇将完成NRF24L01+发送和接收端的联调,并演示一个应用的例子。敬请期这篇我们将前面调试好的发送模块与这篇的接收模块进行联调。来完成无线数据传输的工作。这个黄绿屏采用的LCD12864是KS0108控制器的无中文字库。而那个蓝屏LCD是ST7920控制器。但原理还是一样的。插上模块,打幵KEIL对模块的I/O脚进行违义。r幾24UI1RX-tlV
52、isiodZ-D:工作单片机IC51缜习Mj4i:LTestNRJ?24UI!L实验用89药2接收检测CDW.l-|nTx|囹吹件E编辑mmLE程礙试眇卜国设备TXMSVCS嵋口Wftb|fi|x|a色o附踰触码归悻辜&%燧邂dm|BfeRfflaa|厭1目踪i71日扫目标1H3源程序组1旳12884put.c期NRF24L31KX.cincludereg52hA|#includetypedefunsignedcharuchar;ex-ternvoidLcmClear(void);/清屏externvoidLcirtlnit:(void);/初始eocternvoidLcrtiPu七str(u
53、charrow,ucharyruuchar*uchar七05七1:(uch&runm);/charuchars*tr4;/作为存綃有输出uuhaZos七工函数辛I./去吳亠參*4鼻去鼻鸟士4*吳於糸的工O端口定&sbitCE=E1a3;1QOCd.a-匚4rrtT7CVC4丫4r-yTJ=D1Af?下面代码是对LCD12864的外部函数的逹义和对模块功能脚的定文:ttincludettincludetypedefunsignedcharuchar;externuoidLcimClear(uoid);externuoidLcmlnit(uoid);externuoidLcimPutstr(uch
54、arrovj,uchariuchar*str);/在设定位置显示字符串uchar*uchartostr(ucharunn):/將cpucharstr4;”作为存储有输出uchartostrgf/*-*NRF2AL十的10端口定义开*未菇溝次茄溝*旅*未开溝海诉gbitCE=P13;sbitCSN=P12;sbitSCK=P11;sbitMOSI=P1A0;sbitMISO=P0;gbitIRQ=P彳;接下来是定义模块的指令、常量、寄存器地址常量、读写寄存器子函数的定义,这和上篇里的程序是一样的,相同的我就不占用更多空间了,我会在最后把完整的程序放上来,现在只做个说明。定义NRF24LO1初始化
55、子函数、设置接收模式函数、读取接收的数据包函数:/*NRF2iiLB1初攻合化f/*/uoidinit_NRF2UL01(uoid)inerDelay_us(1B0);CE=0;一CSN=1;SCK=OIRQT;中断复位可以接收中断信号SPIWMtjBllFWRITEREG*TX_ADDR,TX_ftDDRESS,TX_ADRJJIDTH);/写本地地址SPIWriteBuFCWRITEREC+RX_ADDR_PQ,RX_fiDDRESS,RX_ADR_WIDTH);/写接皈端地址SPI_RWRegWRITEREG+ENAA,0 x00);频道。自动aEk应答禁止SpTRW_Reg(WRITE
56、_REGEN_RXfiDDR,0 x01);无许_SPI_RWjeg(WRITE_REG+RF_H,1);H丧置信道工企为2:湎收发必须一SPI_RW_Rg(WRITE_REGRX_PW_P0,RX_PLOAD_WIDTH);J.SPI_RW_Reg(WRITE_REG+RF_SETUP,0X07);谡置发/射频停止工作/sp噜作禁止/SPI时钟为0鑰蠶麟长鬆潮加/关关務捋关狭英关決派关*務关关狭捋关決未关关務关关狭捋关決9&关*未关关務*关狭&关決未关芳務关关狭*/函数:voidSetRX_Mode(void)功能设置数据接收模式/关关務*关狭英关決未关*務关关狭捋关決未关*務关关狭茨关決&
57、关*未关关務捋关狭&关決未关关務关米狭*/uoidSetRX_Mode(uoid)CE=O;SPI_RW_Reg(WRITEREG+CONFIG,0 xflf);/IRQ中断响应6位CRC接收模式CE=1?inerDelay_us(200);函数2ucharnRF24L01_RxPacket(uchar*rx_buf)功能;数据谏取后放入忑”接收缓冲区中f关关務*关狭英关決派关*務关关狭捋关決未关*務关关狭茨关決&关*未关关務捋关狭英关決未关決務关关狭*关決&关決派关关共*关米关yucharnRF24L81_RxPacket(uchar*rx_buf)ucharreuale=0;sta=SPI
58、-ReadCSTATUS);/诜取状态寄存其来判断数据接收状况i代RXJ)R)/判断是否接败到数据F面是接收程序的主函数:f/*|*关uoidmain()uchari;ucharBuF05=B);/7显示“旷提示符iHi)如杲接收到载波else如果没有接收到_Lcr)Putstr(4,56,uchartostrCi);显;F检测到的载波信息,昧接收到Delapms(16);LcmClearO;/清屏主程序前面是读取0通道的接收地址数据并显示,在模块初始化函数里,己经写入了0通道地址数据,这里我们是验证一下,读写程序的正确性。地址数据显示延时几秒钟后,寸呈序建X估站SetRX_Mode();语句
59、调用接收函数进行一次数据的接收,接收完后用i=SPI_Read(CD);语句来读取模块接收到的载波信息,这里我要说明一下,“CD”是模块里的一个寄存器(0 x09),当模块在接收过程利如果接收到有前面初始化时RF_CH设定的频率我们前面设的是2.4GHZ的载波号时,就将CD置为1谄右*il&空I栽油住豆古#%八冷卅曲們HFlMQgTT卜笞岳At憎匚孑站報A洽百:耳丕有曲抄千焉体:RXCDAAAUli4AAJ11pQQQe139,comNRF24L01RXDtarfef/_mi卜(/OiiAkiUUAAAIlAXillA且_.Qiii!QJQl(5ol将上一篇我们调试好的发送模块上电运行,再运行
60、我们现在写好程序的接收模块,运行结果如上图,第一张是显示通道0的地址数据。第二张杲接收到了载波数据后显示CD值为1,第三张是当没有接收到载波数据石显云CD为0。这样我们不必对上接收通道号,只要频率是符合接收范围,就知道发送模块真的是在不停地发送着信号。如果不能正确显示通道地址数据,就说明我们的读写程序可能有问题,那就要用与上一篇介绍的方法先进行简单的读写寄存器调试,待程序能够正确与模块进行读写后再进行接收任务的调试。如果调试总收不到载波信号,那就要看看发送模块是不是有问题,或者调整加快发送频度再试试,同时也真调整接收的频度试试,毕竟NRF24L01模块的发送和接收都是突发式的,而不是连续、亠亠
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年智能化高架活动地板项目可行性研究报告
- 2025年排水阀门项目可行性研究报告
- 2025年大红描金粉蜡笺项目可行性研究报告
- 2025年压片机项目可行性研究报告
- 2025年全粒面填充项目可行性研究报告
- 2025年PVC可调电容项目可行性研究报告
- 2025至2030年中国陶瓷纤维浇注料数据监测研究报告
- 2025至2030年中国转动计数器数据监测研究报告
- 2025至2030年中国落地通风柜数据监测研究报告
- 2025至2030年桦木皮项目投资价值分析报告
- 名师工作室建设课件
- 《电子技术应用》课程标准(含课程思政)
- 纸尿裤使用管理制度内容
- 电力储能用集装箱技术规范
- 体检中心员工礼仪培训
- 《工程质量验评培训》课件
- 《课标教材分析》课件
- 筑牢安全防线 创建平安校园
- 医疗器械考试题及答案
- 《中国移动》课件
- 四新安全管理
评论
0/150
提交评论