nrf24l01传输距离接收端能直接连到电脑上吗?

NRF24L01双向数据传输基本规则_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
&&¥2.00
喜欢此文档的还喜欢
NRF24L01双向数据传输基本规则
N​R​F4​L1​低​速​数​据​网​络​结​构
阅读已结束,如果下载本文需要使用
想免费下载本文?
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
你可能喜欢您现在的位置: &
ARM和WinCE6.0下nRF24L01的驱动设计
ARM和WinCE6.0下nRF24L01的驱动设计
  nRF24L01是一款工作在2.4~2.5 GHz世界通用ISM频段的单片无线收发器芯片。它在无线数据通讯、无线门禁、遥感勘测、工业传感器和玩具中都有应用。
  随着测控技术的发展,nRF24L01与单片机组成的系统进行无线测控的实例已经有很多,如基于nRF24L01的无线温度监测系统、基于nRF24 L01的近距离无线数据传输系统等等。近年来,随着arm和嵌入式WinCE系统的迅速发展,由于在WinCE系统下nRF24L01和arm的通信缺乏驱动,致使两者之间不能直接通信,一般的解决方法是借助于第三方单片机的串行口来进行两者的通信。这种方式的不足之处在于,由于要借助于第三方单片机,使得成本增加且通信速度下降。nRF24L01驱动的设计与实现正好添补了这一空白,使WinCE系统和nRF24L01可以直接通信进行无线数据收发。
  1 WinCE流式驱动模型
  在WinCE系统中有4种驱动模型,其中流式接口设备驱动模型和本地设备驱动模型是可以由用户来开发的。nRF24L01可以看作是一种流式接口设备,所以选用流式接口设备驱动模型来编写驱动较为合适。
  1.1 流式接口驱动程序的体系结构
  如图1所示,流式接口驱动程序的体系结构由5部分组成,分别是应用程序、FileSys.exe、设备管理器、流式接口驱动程序和硬件。
  图1中阴影部分是由用户编写程序来完成,白色部分是由WinCE系统自身提供,用户不能修改。在应用程序使用文件API对设备进行访问时,文件API调用被操作系统转发到FileSys.exe进程中;若发现是对设备的访问,则FileSys.exe就会把操作交给设备管理器;然后,设备管理器根据具体操作调用不同流式接口驱动中提供的接口;最后,由流式接口驱动程序负责与硬件交互。
  从体系结构中可知,流式接口驱动体系是把设备抽象作为文件进行操作的。所以编写流式接口驱动就是将文件操作应有的打开、关闭、读取、写入和移动文件指针的操作在驱动程序中以函数的形式实现,这些函数有其标准的定义形式,称之为流接口函数。但对于驱动程序而言除了和文件一样的标准操作外还需要驱动程序的加载、卸载等流接口函数。下面将介绍nRF24L01驱动中主要用到的流接口函数:
  ①XXX_Open()函数,功能是打开设备准备读写,对应的文件操作函数是CreatFile()。
  ②XXX_Close()函数,功能是关闭设备,对应文件操作函数是CloseHandle()。
  ③XXX_Init()函数,功能是初始化设备,在系统启动时由设备管理器渊用。
  ④XXX_Read()函数,功能是读取设备中的数据,对应文件操作函数为ReadFile()。
  ⑤XXX_Write()函数,功能是写入数据到设备中,对应文件操作函数为WriteFile()。
  ⑥XXX_IOControl()函数,功能是对设备发送控制命令,对应文件操作DeviceIOControl()。
  其中XXX是驱动程序在注册表中注册的设备名称。
  2 硬件设计
  arm芯片选择三星公司生产的S3C2440,该芯片工作频率为400 MHz,最高可达533 MHz,可稳定运行WinCE 6.0操作系统。nRF24L01是通过SPI总线协议和单片机进行通信的,在WinCE 6.0中SPI通信的实现可以通过arm的SPI接口,也可以通过GPIO端口软件模拟的方式实现。在本次设计中选用了GPIO端口软件模拟的方式。硬件连接如图2所示。
  3 nRF24L01驱动的实现
  3.1 主要实现的函数
  (1)NRF_Init()设备初始化函数
  在该函数中主要进行GPF端口的初始化,接收完成同步事件和接收线程的创建主要的核心代码如下:
  为了方便映射虚拟地址,在本驱动中将所用到的特殊功能寄存器的虚拟地址由自定义类CS3c2440SFR来进行组织。其中“sfr”是类CS3c2440SFR的实例,D()是一个自定义宏,其源码为“#define D(v_add)(*(volatile unsigned long*)v_add)”。
  (2)NRF_Open()函数
  NRF Open()函数主要实现了对初始化是否成功的判断及对nRF24L01进行初始配制。核心代码如下:
  SPI_Write_Bur(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);
  SPI_RW_Reg(WRITE_REG+EN_RXADDR,0x01);
  SPI_RW_Reg(WRITE_REG+RF_CH,0);//设置信道工作为2.4 GHz,收发必须一致
  SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOADWIDTH);//设置接收数据长度
  SPI_RW_Reg(WRITE_REG+RF_SETUP,0x07);//设置发射速率为1 MHz,发射功率为最大值0 dB
  (3)NRF_Read()函数
  NRE_Read()函数实现了对接收缓冲区的读取并传送至应用程序。由于nRF24L01一次最多能接收32个字节的信息,所以该函数一次最多能传送32字节的信息。主要核心代码如下:
  (4)NRF_Write()函数
  NRE_Write()函数主要实现发送数据写入发送缓冲区并发送的功能。主要核心代码如下:
  (5)NRF_IOControl()函数
  NRF_IOControl()函数主要实现了对本机地址的配置、接收方地址的配置、发送模式和接收模式的配置等。
  3.2 驱动设计重点
  (1)如何实现特殊功能寄存器的虚拟地址映射
  由于WinCE 6.0对虚拟地址的映射住安全性方面提高了要求,所以WinCE 6.0中地址映射不能再使用以前版本中常用的VirtualAlloc()和VirtualFree()函数来分配和释放虚拟地址,它们的使用会产生编译错误。解决方式是使用CEDDK库中的MmMapIoSpace()函数和MmUnmapIo Space()函数来实现虚拟地址的分配和释放。
  (2)如何实现数据的接收
  在数据接收中采用多线程编程,在设备初始化时调用CreateThread()函数创建一新线程对应线程函数DWORD AcceptThread()。
  (3)AcceptThread()函数的实现
  在该函数中主要进行中断配置、中断同步事件的创建、中断的撤除等。使用的API函数主要有:KernclIoControl()用来获取逻辑巾断号;InterruptInitialize()逻辑中断和同步事件关联;WaitForSingleObject()阻塞线程并等待中断同步事件发生,中断同步事件发生即接收完一次数据,则使接收完成同步事件有效,可通知应用程序数据已接收完成;(InterruptDone)函数中断结束,并撤除相应的中断标志位准备响应下次中断。
  4 驱动测试程序
  4.1 数据发送
  数据发送步骤如下:
  ①调用CreateFile()函数打开设备,核心代码如下:
  NRFdriver=CreateFilc(L“NRF1:”,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN EXISTING,0,NULL);
  ②通过DeviceIoControl()函数设置为发送模式并使用默认地址(默认地址在驱动程序中配置完成),核心代码如下:
  DevlccIoControl(NRFdriver.IS SEND STATUS,NULL,0,NULL,0.NULL,NULL);
  ③调用WriteFile函数完成发送,核心代码如下:
  WriteFile(NRFdriver,(LPCVOID)p,strL,NULL,NULL);
  4.2 数据接收
  数据接收步骤如下:
  ①打开设备,方法同4.1节步骤①。
  ②通过DeviceIocontrol()函数设置为接收模式并使用默认地址,核心代码如下:
  DeviceIoControl(NRFdrivcr,IS_ACCEPT_STATUS,NULL,0,NULL,0,NULL,NULL);
  ③创建接收线程及与驱动中同名的接收完成同步事件,在接收线程中调用WaitForSingleObject()函数等待有效。如有效,则调用ReadFi le()函数读取数据并显示。核心代码如下:
  以上驱动及测试程序均是在VC2008环境中完成。在WinCE6.0系统中运行测试程序还应该在注册表中导入如下注册信息:
  [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\NRF24L01]
  “Prefix”=“NRF”
  “Dll”=“NRFDriver.DLL”
  以上内容中,驱动程序注册的设备名称为“NRF”,驱动程序名为“NRFDriver.dll”。
  5 测试效果
  5.1 接收测试
  采用MSP430F149开发板和nRF24L01模块搭建发射端,然后利用该发射端每秒发送32个字节的数据,数据内容为1~32。arm接收端接收到数据并将它显示到LCD上。
  5.2 发送测试
  用MSP430F149开发板和nRF24L01模块搭建接收端,然后利用MSP430F149的串行口将接收到的数据发送到计算机,通过串口调试助手就可以观察到arm端发送来的数据。
  驱动程序的编写是嵌入式系统开发的重要核心步骤。文中详细阐述了nRF24L01驱动程序和测试程序的开发,通过测试该驱动程序能够较好地完成无线通信的功能,满足实际需求。
&&&主编推荐
&&&热门试卷
&&&最新视频
&&&热门阅读
&&&最新问答
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-6584人阅读
&&&&&&&两个星期之前,我就完成了 nRF24l01的收发。但是可能正是由于太早出结果,导致了一些深层次的问题没有被发现。后来做声音引导的时候发现只能发送,不能接收数据。开一还以为是硬件坏了。真是晕。下面是我的nRF24L01中断处理程序
#pragma vector=PORT2_VECTOR//24L01中断
__interrupt void IRQ_ISP(void)
& i++;&
& nRF24L01_Statues=SPI_Read(STATUS);&&
& nRF24L01_Statues_Flag=0;
& if(nRF24L01_Statues&RX_DR)/**接收正常**/
&&& SPI_Read_Buf(RD_RX_PLOAD,RX_BUF,TX_PLOAD_WIDTH);
&&& nRF24L01_Statues_Flag=1;
&&& nRF24L01_CEL; //进入待机模式&&
& else if(nRF24L01_Statues&TX_DR)//发送完毕
&&& nRF24L01_Statues_Flag=2;&&&
& else if(nRF24L01_Statues&MAX_RT)//发送失败
&&& nRF24L01_Statues_Flag=3;&
& P2IFG&=~BIT5;
& SPI_RW_Reg(WRITE_REG+STATUS,nRF24L01_Statues);
& 然后再有
& nRF24L01_Statues_Flag=0;
& nRF24L01_Init(nRF24L01_TRA);//发送采样命令
& while(nRF24L01_Statues_Flag!=2);//第一次发送
& nRF24L01_Statues_Flag=0;
& nRF24L01_Transmit(TX_BUF);//第二次发送
&&&&&& 这么处理下,就解决了问题。
&&&&&&&我一开始的设定的是发送端每次发送一次。结果接收端只能接收一次,但发送端却显示发送成功。
又来改成发送端发送两次以上。结果,正常接收了。问题是,为什么会这样?
&&&&&& 可能是这样的,我们第一次时能够将PID(数据包识别)进行对比,但是我们没有在初始化时将数据包识别这个PID置零。而发送端如果只有发送一次,那么很有可能会使得接收端对比的两个PID值相同,使得nRF24L01误认为时重发的数据包。这时候,我们可以发现,只有在断电复位之后才能接收到一次值。
&&&&&& 这儿的高手比较多。我大胆地把我的想法提了出来。不知道是不是这样。还请前辈们多多指教。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:26052次
排名:千里之外
原创:14篇
评论:15条
(4)(1)(1)(1)(2)(5)(2)NRF24l01跟STC89C52RC单片机P1口连接,还用串联电阻吗,我自己焊了一个3.3V电源给NRF24L01供电.好象P1口里面有上拉电阻,数据口要串电阻吗或者直接告诉我怎么接电路(P0,P2口已用在别的地方了)_百度作业帮
NRF24l01跟STC89C52RC单片机P1口连接,还用串联电阻吗,我自己焊了一个3.3V电源给NRF24L01供电.好象P1口里面有上拉电阻,数据口要串电阻吗或者直接告诉我怎么接电路(P0,P2口已用在别的地方了)
您可能关注的推广带你认识更牛的人下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
阅读(397)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'nRF24L01接收程序',
blogAbstract:'\r\n#include &reg52.h&#include &intrins.h&\r\ntypedeftypede//****************************************NRF24L01端口定义***************************************sbit &MISO&=P1^4;sbit &MOSI&=P1^3;sbit&SCK&&&& =P1^2;sbit&CE&&&& =P1^0;sbit&CSN&&=P1^1;',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:6,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}}

我要回帖

更多关于 nrf24l01接收不到数据 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信