谁能帮我解释哪一天一下这个24L01的初始化代码?地址怎么理解?

1.单片机控制只需关注6个nRF的控制和数据信号:
CSN:片选,低电平工作
CE:模式控制
SCK:时钟线
IRQ:中断信号
3.Tx与Rx的配置过程
(1)初始化Tx模式
写Tx节点的地址
写Rx节点的地址
使能AUTO ACK
配置自动重发次数
选择通信频率
配置发射参数
配置24L01的基本参数以及切换工作模式
(2)Rx初始化过程
写Rx节点的地址
使能AUTO ACK
选择通信频率
配置发射参数
配置24L01的基本参数以及切换工作模式
没有更多推荐了,要想24L01多通道通讯成功,务必先单通道调试成功,并且懂得这块芯片通讯的一些基本知识。
一、基本的通讯条件
1、接收端的接收地址(RX_ADDR_Px)等于发射端的发射送地址(TX_ADDR)
2、收发端的频道一致(RF_CH)
3、收发端的发射参数一致(RF_SETUP)
二、收发模式初始化的基本步骤
Rx端初始化步骤:
1)写 Rx 节点的地址 RX_ADDR_Px
2)使能 AUTO ACK
3)使能通道的接收地址 EN_RXADDR
4)选择通信频率 RF_CH
5 ) 选择通道有效数据宽度
6)配置发射参数(低噪放大器增益、发射功率、无线速率)
7)配置 24L01 的基本参数以及切换工作模式 CONFIG
Tx端初始化步骤:
1)写 Tx 节点的地址 TX_ADDR
2)写 RX通道P0 的地址 用ACK应答 RX_ADDR_P0
3)使能自动应答 EN_AA
4)使能通道接收地址 EN_RXADDR
5)配置自动重发次数 SETUP_RETR
6)选择通信频率 RF_CH
7)配置发射参数(低噪放大器增益、发射功率、无线速率)
8 ) 选择通道有效数据宽度
9)配置 24L01 的基本参数以及切换工作模式 CONFIG
三、多通道通讯关键代码
const u8 RX_ADDRESS0[] = {0xff,0xff,0xff,0xff,0x00};
const u8 RX_ADDRESS1[] = {0xff,0xff,0xff,0xff,0x01};
void NRF24L01_RX_Mode(void)
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS0,RX_ADR_WIDTH);
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P1,(u8*)RX_ADDRESS1,RX_ADR_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x3f);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x3f);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);
NRF24L01_CE = 1;
delay_us(130);
const u8 TX_ADDRESS0[TX_ADR_WIDTH]={0xff,0xff,0xff,0xff,0x00};
void NRF24L01_TX_Mode(void)
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS0,TX_ADR_WIDTH);
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)TX_ADDRESS0,RX_ADR_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x3f);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x3f);
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);
NRF24L01_CE=1;
delay_us(10);
const u8 TX_ADDRESS1[TX_ADR_WIDTH]={0xff,0xff,0xff,0xff,0x01};
void NRF24L01_TX_Mode(void)
NRF24L01_CE=0;
NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS1,TX_ADR_WIDTH);
NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)TX_ADDRESS1,RX_ADR_WIDTH);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x3f);
NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x3f);
NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40);
NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);
NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);
NRF24L01_CE=1;
delay_us(10);
四、多通道通讯关键点
1、发送端数据通道0被用做接收应答信号,因此不同通道发射端都要必须使能RX_ADDR_P0,因此需要把发送端地址写入里面。(当然除非关掉应答)
2、使能第N个的通道,前N个通道也必须被使能。
3、2~5通道与通道1共用高32位(4字节)地址,只有低8位(1字节)可以改变,且绝不能一样,如下:
const u8 RX_ADDRESS0[] = {0xff,0xff,0xff,0xff,0x00};
const u8 RX_ADDRESS1[] = {0xff,0xff,0xff,0xff,0x01};
const u8 RX_ADDRESS2[] = {0x02,0xff,0xff,0xff,0x01};
const u8 RX_ADDRESS3[] = {0x03,0xff,0xff,0xff,0x01};
const u8 RX_ADDRESS4[] = {0x04,0xff,0xff,0xff,0x01};
const u8 RX_ADDRESS5[] = {0x05,0xff,0xff,0xff,0x01};
PS:如果地址宽度是2(16位),那么高8位(1字节)共用,低8位(1字节)不同。
4、接收端写各通道地址时候,必须先从低通道(通道0开始)开始写,使能地址宽度也是。
NRF24L01作为一块低价格、入门级无线通讯芯片,自身限制还是挺多的,稳定组网还是有一定的难度,还不够成熟于物联网领域,做点小作品还是可以的。
nRF24L01单片机通信的总结--看了就会用了
STM32F103之NRF24L01的发送 接收调试,多通道接收等总结与反思
nRF24L01一对多做到唯一配对使数据相互不影响
2.4G模块NRF24L01调试经验
NRF24L01的使用
STM32驱动NRF24L01一对多的通信---可变数据包宽度
[转载]NRF24L01+的5个通道调试经验
NRF24L01的多对一通信
nrf24l01工作原理
没有更多推荐了,&>&NRF24L01使用说明及初始化代码
NRF24L01使用说明及初始化代码
上传大小:346KB
NRF24L01使用说明及初始化代码,可根据具体应用对程序进行设置
综合评分:4
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有7条
可以,谢谢分享!具有参考意义。
谢谢楼主,基于单片机的
可以,还带有一个串口调试助手,就是我还是没有调试成功,可能是 我的接线不对吧
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
NRF24L01使用说明及初始化代码
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*投诉人姓名:
*投诉人联系方式:
*版权证明:
*详细原因:
NRF24L01使用说明及初始化代码nRF24L01单片机通信的总结
来源:eefocus
1周时间,我从一个没用过STC单片机,不知道什么叫SPI接口的“文盲”,把nRF24L01的整个通信过程弄到完全没有bug.。兴奋之余来小屁一下。给那些正在奋斗着这个牛逼的芯片的小牛们小炫一下。希望有所帮助。屁话少说。正题:基本的东西我理解了,那就是:1.用5根线的SPI接口向2401发送数据或指令。2.芯片在每次上电的时候都需要进行一番配置。这些配置数据,就是所谓的指令了。3.配置完成后知道芯片处在哪个模式。并且知道它将要转向哪个模式。4.通讯协议。5.观察现象。好了,小牛们一定急切想知道自己的程序问题出在哪里了,再小白一点的一定想急切的知道如何配置才能让它工作。更小白一点的一定想知道这个芯片的各个模式之间是怎么联系的。又是如何进行相互转化的。别急,一个一个说。要说什么最重要,你们不会想到其实是4.通讯协议。 为什么呢,你们又知道在这里的通讯协议是作什么用的呢。 举个简单的例子,我刚开始设计的时候,一心想让一个作为发送模块,每隔一秒发送一次数据,而另一个则作为接收模块,不间断的检测收到数据没有。 这就是一个简单的通讯协议,它是我们的目标。是我们的方向。当然真正的通讯协议绝对不会这么简单的几句话。它告诉你,你理想中的模块应该充当什么角色。是接收?是发送?还是接收完了马上发送。作为开发阶段,当然是越简单的协议,正确性就越容易验证,废话不说,那就按我说的“通讯协议”来设计吧。先说发送模式吧。要到发送模式,要经历几个变化。第1,上电,上电完了芯片其实还是在powerDown模式,因为芯片为了省电,它需要通过软件来控制开机或关机。powerDown模式就是所谓的待机模式了。这个模式理所当然是最省电的。它除了省电以外还能干吗呢?配置!对最重要的配置。就是可以通过 SPI口向它发送数据,它是可以接收到的,并且可以正确写入到指定的寄存器中的。一般我们在初始化中一开始就可以配置了,而此时芯片正是处在这个模式。第2.我们的目标是要把它配置的能发送出去数据,而且能被目标设备正确接收。所以这中间涉及的寄存器(当然是2401里自带的寄存器区了)有:1@发送到的目标地址。 说地址其实是虚的,它就相当于一个钥匙和一把锁一样。当你在接收设备里边规定了一个地址以后,那么接收到的数据只有带了这个地址的包才会被正确接收。所以说这里的发送目标地址就是接收设备里的本机地址。只要设计时两个地址相同,就不会接收不到。2@接收到的地址。 这个名字起的不是很好哈,有点误导人。说白了就是一个本机地址了。在纯发射机里,它并不是必要的。因为它从来不接收数据~~~这里写上,是因为:发射模式还有个东西,就是自动应答功能,(当然也是通过配置才能启用的,不配置则不会自动应答,也就不需要知道本机地址了)。3@说到自动应答,那就先说它吧。一般我们会想,发送出一帧数据后是不是应该等待另一方回应个数据呀?想法是好的,但我说了,有通讯协议在控制。因为我们这里只想设计成一直发送而不管对方是否收到。所以自动应答可以不去配置,让它开机默认即可。但实际上我们的通讯协议可能很复杂,肯定不会是一直在发送。并且,它发送完一帧后,确实应该转为接收模式来等待对方发送应答数据过来。我们人为的当然可以自己来个模式跳转,但是有自动应答了,也就是说,当你设定开启自动应答了,那么在它发送完一包数据后,芯片会立即转为接收模式了。 《在这里我也仍有一点没理解,就是,当它收到应答后会变成什么模式呢,是自动再回到发送模式还是停留在接收模式。》 4@有自动应答了,那么就不能少了自动重发功能了。为什么呢。首先理解为什么会自动重发,就因为它处在自动应答模式时,通过接收数据来判定上次的数据是否有接收者成功接收了,就像我送出了一封信,如果你没有回信我是不是会想你可能没收到信,我需要再发一次。就是这个道理 。自动重发寄存器8位被分成两个4位的小区域,高4位存的是重发间隔时间,也就是说总共可以设定为16种不同的间隔,在这个间隔时间过后仍没有回应才再次重发。低4位好说,就是存一个最大重发次数。则最大可以设为15,即重发15次后仍然没回应那就不理你了,不再重发了。并且还会产生一个中断呢。最后再讲中断部分。 这里应该注意的是,当自动应答功能禁止时,就没有自动重发了,不管你设了重发多少次都不管用了。所以是互相影响的。还有就是重发次数设为0次,则相当于禁自动重发了,这不是显然的么。嘿嘿。5@最基本的配置,,频率。这个芯片不光能以2.4Ghz的载波发射呢,它的带宽为2.4G----2.512G呢。这中间有一百多M的频带,可以划分成2M一个的信道。这个寄存器中的值就标明你想工作在哪个信道上啦,只有设置为同频的设备才能接收的到很容易理解吧。比如你设为10信道,则10*2=20M即发送时所用的载波频率就是0MHz。当然也只有设为2420M的接收设备才能接收的到了。     6@功率,数据速率。这是什么呢?原来2401里边也有自动增益控制部分,我们可以设定一个合适的功率来发射数据,第一可以在能耗上有利,另一方面对通信距离的控制也是很重要的。比如我只想在2米内能够通信,但2401最大的通信距离可以达到上百米,显然需要降发射功率来降低通信距离。可选的功率值有 0Dbm,-6dBm, -12dBm,-18dBm, 显然0在这里是最大的发射功率了。开发时尽可能设为0.如果设为0时,接收者都接收不到数据,那肯定是芯片坏了,就不用考虑降低功耗来通信了。这四档功率,通信距离从远到近,从几十米到几cm.并且在通信过程中还可以动态更改这个功率值,以达到最佳匹配的效果。数据速率是什么呢,刚开始我跟SPI接口的速率搞混了,想着,一个4M的单片机跟芯片通信速率怎么可能到这么高的。其实不是,这个速率就是加在载波上的数据的码率了。有两个可选值,1Mb/s,2Mb/s.也就是说,1秒钟能发送出去多少个高低电平。以上这些配置命令之后就可以通过简单的指令转向发送模式了。下面就看一下,配置的伪指令吧:1.sendCommand(TxAddress_5) .因为地址是3到5字节可选的,这里选择了5字节的地址2.sendCommand(LocalAddress_5),本机地址如果想要开启自动应答则必需与发射地址相同,即LocalAddress==TxAddress..不开启则不需要相等。3.sendCommand(EnableAutoAck_0),因为芯片自带了6个通道,可以同时工作同时接收不同的数据,所以这里的自动应答也有相应的6个bit位来分别控制。这里只允许通道0自动应答。4.sendCommand(EnableAutoTransmit) .只要上边一句配置开了自动应答,这句就应答生效。即自动重发.5.sendCommand(RF_CH). 这一句设置发射频率。即设定信道。一般默认的就是0信道了,也即2.4G的载波。6.sendCommand(RF_Power). 设定发射速率,还有发射功率就设成0dBM吧。以上这些是发射模式的必要配置了。如果不涉及接收,那么现在就可以转向发射模式。7.sendCommand(Config); 通过 config寄存器中的开机控制位 powerup=1,转向空闲模式,config^0=0.转向发射模式。8.sendCommand(TxBuffer);  填充发送数据到缓冲区里边。8.CE=1;  这是一个引脚,用来控制从空闲模式向发送或接收模式跳转的.仅将相应位设为发送或接收模式不行,芯片现在只欠东风了,就是CE=1并保持最少10us时间后。就会开始发送数据了。一个帧数据发送完成后会产生中断。这些中断是可以屏蔽的,就像单片机的中断允许控制一样。控制位在config寄存器中。这里还可能产生另一个中断,就是重发次数达到上限了,你设了重发3次,那么重发3次以后还没收到应答就产生中断了。同样也是可屏蔽的。nrf24l01d发射机 接收机 无线通信程序那点事 - 单片机学习小组 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
林超文手把手教你学!
教你1000种电路设计思路
张飞硬件电路之PFC全集
参与免费送VIP+原创视频
运放、ADC、电磁兼容
nrf24l01d发射机 接收机 无线通信程序那点事
等待验证会员
04:54:52  
从号开始做无线通讯的。开始我并没有重视这个无线通信,但是偶尔一次去工地的路上看见一个城建钢筋场地里的龙门吊,那个傻逼竟然用遥控器控制龙门吊!!开始惊奇,转而又想我能不能做呢?我分析其实关于控制部分早在技校里就学了,正反转吗,不难,但是中间你要实现遥控就不易了,我还是模块化思路,我搞到了RF模块,开始进入了漫漫的实验之路,射频信号我在此之前根本不懂,也不知道是个什么东西,只是知道手机里有那个东西,数据手册有两种一种是英文的,一种是翻译的中文,因为在这方面我还是有经验的,不能尽心中文资料,要信英文资料,但是翻译太麻烦了要用中文资料为参考。
& & 我的第一个实验便是RF模块与主控芯片之间的通信问题,因为无线通信的流程大概是这样的:发送端 数据和信号送入模块的数据区,CRC效验后打包,然后打包后的信号送往调制器进行调制,调制完毕后进入射频功率放大,然后通过天线发射出去;接收端 实时监测空中信号,如果有信号那么接收回来,解调处理,然后对包进行逆打包,CRC效验,地址是否匹配,如果一切正确那么就把数据信号送入数据缓冲区。也就完成了一次通信!和电视和收音机差不多,所以模块与主控通信的重要性关系到你能否驾驭它了!!可喜可贺的是我没用几天就解决这一问题了,因为它使用的外围数据接口以前我用的很多,解决了主机和模块之间的对话下一步是对RF模块的设置和通信的程序,我没想到这可是难倒我了,任凭我怎样设置怎样修改,就是无法发射,没有接收,没有任何的检测工具,我开始怀疑芯片的好坏!是不是坏了?那为什么还能读写呢?又上网找资料找朋友,但是这个东西可不像别的,没有任何教学视频可参考,网上的程序也很烂,说实话我看不下去,我只会用我的思路来编程,他们的太精致了,各种猜测,辗转反侧,夜不能寐。很快就过春节了,我和爸爸1月27号回的家,本想着在家里搞,可是到家后没时间搞,和老爸弄自来水管,写春联,收拾房屋,打扫卫生,可以这么说,今年的春节我是最累的,过了春季有忙着和朋友们玩DOTA,走亲戚,来亲戚,转眼初九了,又极不情愿的踏上了北上打工的旅途!哎!!!人啊!!!
/*无线模块定义*/ sbit CE=P1^3;//nrf24l01d的模式控制线在 CSN 为低的情况下,CE 协同NRF24L01 的CONFIG 寄存器共同决定NRF24L01 的状态(参照NRF24L01 的状态机) sbit CSN=P1^4;//nrf24l01d的片选线,低电平有效 sbit IRQ=P1^5;//nrf24l01d的中断信号/*SPI定义*/sbit&&SI=P1^0;//MOSI主出-从入sbit&&SO=P1^1;//MISO主入-从出sbit&&SCK=P1^2;// 时钟信号/*定义无线模块的收发状态位*/unsigned char bdata FLAGE;sbit MAX_RT=FLAGE^4; //达到最大发送次数置1sbit TX_DS=FLAGE^5;//数据发送被置1sbit RX_DR=FLAGE^6;//数据接收被置1/*可谓操作字节dat定义,用来构成最底层的SPT读写函数使用*/unssbit dat_0=dat^0;sbit dat_1=dat^1;sbit dat_2=dat^2;sbit dat_3=dat^3;sbit dat_4=dat^4;sbit dat_5=dat^5;sbit dat_6=dat^6;sbit dat_7=dat^7; /*串口程序*/void InitUART(void){& & TMOD = 0x20;& & SCON = 0x50;& & TH1 = 0xFD;& & TL1 = TH1;& & PCON = 0x00;& & EA = 1;& & ES = 1;& & TR1 = 1;}void UARTInterrupt(void) interrupt 4{& & if(RI)& & {& && &&&RI = 0;&&//add your code here!& & }& & else& && &&&TI = 0;}void SendOneByte(unsigned char c){& & SBUF =& & while(!TI);& & TI = 0;}/*串口程序*//*SPI最底层写一个字节函数无返回值有参带形参H*/void delay1ms(uchar time)//1ms{ unsigned char a,b,c,d;&&for(d=d&0;d--)& && &for(c=8;c&0;c--)& && &&&for(b=197;b&0;b--)& && && && &for(a=2;a&0;a--);}void delay10us(uchar time)//10us{& &unsigned char a,b,c;&&for(c=c&0;c--)& & for(b=1;b&0;b--)& && &&&for(a=52;a&0;a--);}/*************************& && &&&*SPI写一个字节的最底层函数 *有参& && & *无返回值& && &****************************/void write_spi_2401(uchar h)//SPI写一字节函数{& && && && &dat=h;& && && && &SI=dat_7;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && &SI=dat_6;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && &SI=dat_5;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && &SI=dat_4;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && & SI=dat_3;& & delay10us(10);& && &SCK=0;& && &SCK=1;& && & SI=dat_2;& & delay10us(10);& && &SCK=0;& && &SCK=1;& & SI=dat_1;& & delay10us(10);& && &SCK=0;& && &SCK=1;& & SI=dat_0;& & delay10us(10);& && &SCK=0;& && &SCK=1;}/************************SPI最底层读取一个字节&&*返回值是读出的这一个字节 *无参& && &*& && & **************************/uchar read_spi_2401()//SPI读一字节函数{& && && &SO=1;//初始化SO线& && && &SCK=1;& &SCK=0;& & dat_7=SO;&&SCK=1;&&SCK=0;& & dat_6=SO;&&SCK=1;&&SCK=0;& & dat_5=SO;&&SCK=1;&&SCK=0;& & dat_4=SO;& &&&SCK=1;& &&&SCK=0;& & dat_3=SO;& &&&SCK=1;&&SCK=0;& & dat_2=SO;& &&&SCK=1;&&SCK=0;& & dat_1=SO;& &&&SCK=1;&&SCK=0;& & dat_0=SO;& &return (dat);//返回读取数值}/****************************& && & *写入寄存器命令函数& &*有参& && &*无返回值& &&&*& && & *m:表示要操作的寄存器地址 *date:表示要向内不写入的数据 ******************************/void write_rge_nrf24l01(uchar m,uchar date){&&SCK=0;//时钟预选拉低&&CSN=1;&&CSN=0; //SPI开& & write_spi_+m));//写入写寄存器命令& & write_spi_2401(date);//写入date指向的寄存器数据 CSN=1;//SPI关}/*************************& && &&&*度寄存器子函数& &&&*将寄存器的数值读出& & *有参&&M表示要读的寄存器& &*有返回值 返回读出的数据& &*& && && && && && && && &&&***************************/uchar read_reg_nrf24l01(uchar m){&&& &SCK=0;&&CSN=1;&&CSN=0;& & write_spi_2401(m);//读寄存器 date=read_spi_2401(); CSN=1;return (date);}/***************************& && && &*待机模式进入后相关对寄存器 *的设置函数& && && &&&*& && && && && && && && && &*****************************/void set_Register_tx()//&待机-I模式下的对寄存器的设置&&接收机&&接收地址是ABABABABAB,通道0,一字节有效数据{ // 下段是寄存器设置在待机-I模式完成& &write_rge_nrf24l01(0x01,0x3f);/*允许所有自动应答开启*///EN_AA使能自动应答功能& &write_rge_nrf24l01(0x02,0x3f);/*允许所有接收地址开启*///EN_RXADDR接收地址允许& &write_rge_nrf24l01(0x03,0x03);/*所有地址通道的收发地址宽度设为5字节*///STEUP_AW设置地址宽度所有通道& &write_rge_nrf24l01(0x04,0x28);/*允许建立自动重发延时为(750+86us)自动重发计数次数为8次*///STEUP_RETR建立自动重发& &write_rge_nrf24l01(0x11,0x01);/*接收数据通道0 有效数据宽度&&一字节*///RX_PW_P0接收通道0有效数据宽度 /**********************************************/ // 本段是对接收机的地址设置在待机-I模式完成 // /**********************************************/ /*这里有必要说明下,由于以上的设置寄存器都是一个字节的所以我使用了子函数,这个是发射/接收地址 我没使用因为上面的只能写一个字节*/&&SCK=0;//时钟预选拉低&&CSN=1;&&CSN=0; //SPI开& & write_spi_a);//写入写寄存器命令& && & /* RX_ADDR_P0 数据通道0接收地址设为0xABABABABAB */& & write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 CSN=1;//SPI关}void main () //主函数{&&& && & InitUART();//初始化串口& & SendOneByte(0xf8);//发送标志位 FLAGE=read_reg_nrf24l01(0x17);//状态寄存器读取 SendOneByte(FLAGE); FLAGE=read_reg_nrf24l01(0x07);//状态寄存器读取;发射前读取状态寄存器& & SendOneByte(FLAGE);& &delay1ms(200);//开机上电复位延时200毫秒后进入掉电模式& & CSN=1;& & SCK=0;& && &CE=0;& && && &//发射使能关闭或叫初始化& &&&write_rge_nrf24l01(0x00,0x0f);/*只允许中断开启,CRC使能,16位,PWR_UP=1(上电),PRIM_RX=1(接收模式)*///配置寄存器&&delay1ms(50);//此处指着个延时很管用,标志着24L01由掉电模式向待机-I模式转换的过程,以上是掉电模式一下就是待机-I模式了& & set_Register_tx();// 待机1模式下的寄存器配置 while(1)&&{ //***********************************************************************& &&&CE=1;//进入接收模式 //*888888& & do {& && & // SendOneByte(0xe8);//发送标志位 FLAGE=read_reg_nrf24l01(0x07);//状态寄存器读取;& & //SendOneByte(FLAGE); } while((~RX_DR)); //检查是否接收数据?如果接收到向下,接收不到等待& && &&&CE=0;//进入待机一I模式&&write_rge_nrf24l01(0x07,0x4e);/*清除接收中断信号*/ //***********************************& && &//这一步是读FIFO数据,读完FIFO清空& &&&CE=0;& &&&SCK=0;& &&&CSN=1;& &&&CSN=0; write_spi_);//读FIFO寄存器&&i=read_spi_2401();& && && && && &//数据& &&&注意这里我只要发送一个字节的数据,可以最大一次发送32字节 从0字节开始读& && &CSN=1; //**************************************** SendOneByte(0xe8);//发送标志位 FLAGE=read_reg_nrf24l01(0x07);//状态寄存器读取;& & SendOneByte(FLAGE); SendOneByte(i); //发送接收到的数据到PC } }
发射机程序:
/*无线模块定义*/ sbit CE=P1^3;//nrf24l01d的模式控制线在 CSN 为低的情况下,CE 协同NRF24L01 的CONFIG 寄存器共同决定NRF24L01 的状态(参照NRF24L01 的状态机) sbit CSN=P1^4;//nrf24l01d的片选线,低电平有效 sbit IRQ=P1^5;//nrf24l01d的中断信号/*SPI定义*/sbit&&SI=P1^0;//MOSI主出-从入sbit&&SO=P1^1;//MISO主入-从出sbit&&SCK=P1^2;// 时钟信号/*无线模块的状态位定义*/unsigned char bdata FLAGE;sbit MAX_RT=FLAGE^4; //达到最大发送次数置1sbit TX_DS=FLAGE^5;//数据发送被置1sbit RX_DR=FLAGE^6;//数据接收被置1/*可谓操作字节dat定义,用来构成最底层的SPT读写函数使用*/unssbit dat_0=dat^0;sbit dat_1=dat^1;sbit dat_2=dat^2;sbit dat_3=dat^3;sbit dat_4=dat^4;sbit dat_5=dat^5;sbit dat_6=dat^6;sbit dat_7=dat^7; /*串口程序*/void InitUART(void){& & TMOD = 0x20;& & SCON = 0x50;& & TH1 = 0xFD;& & TL1 = TH1;& & PCON = 0x00;& & EA = 1;& & ES = 1;& & TR1 = 1;}void UARTInterrupt(void) interrupt 4{& & if(RI)& & {& && &&&RI = 0;&&//add your code here!& & }& & else& && &&&TI = 0;}void SendOneByte(unsigned char c){& & SBUF =& & while(!TI);& & TI = 0;}/*串口程序*//*SPI最底层写一个字节函数无返回值有参带形参H*/void delay1ms(uchar time)//1ms{ unsigned char a,b,c,d;&&for(d=d&0;d--)& && &for(c=8;c&0;c--)& && &&&for(b=197;b&0;b--)& && && && &for(a=2;a&0;a--);}void delay10us(uchar time)//10us{& &unsigned char a,b,c;&&for(c=c&0;c--)& & for(b=1;b&0;b--)& && &&&for(a=52;a&0;a--);}/**********************SPI写一个字节的最底层函数有参无返回值***********************/void write_spi_2401(uchar h)//SPI写一字节函数{& && && && &dat=h;& && && && &SI=dat_7;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && &SI=dat_6;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && &SI=dat_5;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && &SI=dat_4;& && &delay10us(10);& && &SCK=0;& && &SCK=1;& && & SI=dat_3;& & delay10us(10);& && &SCK=0;& && &SCK=1;& && & SI=dat_2;& & delay10us(10);& && &SCK=0;& && &SCK=1;& & SI=dat_1;& & delay10us(10);& && &SCK=0;& && &SCK=1;& & SI=dat_0;& & delay10us(10);& && &SCK=0;& && &SCK=1;}/*****************************SPI最底层读取一个字节返回值是读出的这一个字节无参******************************/uchar read_spi_2401()//SPI读一字节函数{& && && &SO=1;//初始化SO线& && && &SCK=1;& &SCK=0;& & dat_7=SO;&&SCK=1;&&SCK=0;& & dat_6=SO;&&SCK=1;&&SCK=0;& & dat_5=SO;&&SCK=1;&&SCK=0;& & dat_4=SO;& &&&SCK=1;& &&&SCK=0;& & dat_3=SO;& &&&SCK=1;&&SCK=0;& & dat_2=SO;& &&&SCK=1;&&SCK=0;& & dat_1=SO;& &&&SCK=1;&&SCK=0;& & dat_0=SO;& &return (dat);//返回读取数值}/***************************写入寄存器命令函数有参无返回值m:表示要操作的寄存器地址date:表示要向内不写入的数据****************************/void write_rge_nrf24l01(uchar m,uchar date){&&SCK=0;//时钟预选拉低&&CSN=1;&&CSN=0; //SPI开& & write_spi_+m));//写入写寄存器命令& & write_spi_2401(date);//写入date指向的寄存器数据 CSN=1;//SPI关}/**********************度寄存器子函数将寄存器的数值读出有参&&M表示要读的寄存器有返回值 返回读出的数据************************/uchar read_reg_nrf24l01(uchar m){&&& &SCK=0;&&CSN=1;&&CSN=0;& & write_spi_2401(m);//读寄存器 date=read_spi_2401(); CSN=1;return (date);}/*在待机模式下对发射机的寄存器的设置定义了发送地址和应答信号的接收通道和地址*/void set_Register_tx()//&待机-I模式下的对寄存器的设置&&发射机{& & /**********************************************/ // 本段是寄存器设置在待机-I模式完成 // /**********************************************/& &write_rge_nrf24l01(0x01,0x3f);/*允许所有自动应答开启*///EN_AA使能自动应答功能& &write_rge_nrf24l01(0x02,0x3f);/*允许所有接收地址开启*///EN_RXADDR接收地址允许& &write_rge_nrf24l01(0x03,0x03);/*所有地址通道的收发地址宽度设为5字节*///STEUP_AW设置地址宽度所有通道& &write_rge_nrf24l01(0x04,0x28);/*允许建立自动重发延时为(750+86us)自动重发计数次数为8次*///STEUP_RETR建立自动重发& &write_rge_nrf24l01(0x11,0x01);/*接收数据通道0 有效数据宽度&&一字节*///RX_PW_P0接收通道0有效数据宽度& &/**********************************************/ // 本段是对FIF0写入要发送的数据也在在待机-I模式完成 // /**********************************************/ //***********************************& & for(i=32;i;i--)&&//这一步是写32字节的数据到FIFO中,必须使CE=0;重复一次写一字节,& &{& && && & //重复N此写N字节当然最大是32字节;& &&&CE=0;& && &&&//困扰我多日的写FIFO数据问题解决了/18:47于天津第四项目部宿舍& &&&SCK=0;& && & //原来那个手册里的状态图是这么的重要啊I服了游!!!!(radio control state diagram)& &&&CSN=1;& &&&CSN=0; write_spi_);//写FIFO寄存器& & write_spi_2401(0xcc);//数据& &&&注意这里我只要发送一个字节的数据,可以最大一次发送32字节& && &CSN=1;&&} //**************************************** /**********************************************/ // 本段是对接收机的地址设置在待机-I模式完成 // /**********************************************/ /*这里有必要说明下,由于以上的设置寄存器都是一个字节的所以我使用了子函数,这个是发射/接收地址 我没使用因为上面的只能写一个字节*/&&SCK=0;//时钟预选拉低&&CSN=1;&&CSN=0; //SPI开& & write_spi_a);//写入写寄存器命令& && & /* RX_ADDR_P0 数据通道0接收地址设为0xABABABABAB */& & write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据& && && &/*这里其实是用来接收接收机的应答的所以要和发送的地址一样,*/ write_spi_2401(0xab);//写入date指向的寄存器数据& && &/*你想,你要找王均伟,那么你要发送王均伟,王均伟听见后要回应王均伟*/ write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 CSN=1;//SPI关&&SCK=0;//时钟预选拉低&&CSN=1;&&CSN=0; //SPI开& & write_spi_);//写入写寄存器命令& & write_spi_2401(0xab);//写入date指向的寄存器数据& && & /* TX_ADDR 发送地址设为0xABABABABAB */ write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 write_spi_2401(0xab);//写入date指向的寄存器数据 CSN=1;//SPI关}void main () //主函数{& && & InitUART();//初始化串口& &delay1ms(200);//开机上电复位延时200毫秒后进入掉电模式& &delay1ms(200);//开机上电复位延时200毫秒后进入掉电模式& & CSN=1;& & SCK=0;& && &CE=0;& && &//初始化端口& &SendOneByte(0xf8); //发送个标志& &&&FLAGE=read_reg_nrf24l01(0x17);//状态寄存器读取;发射前读取状态寄存器& & SendOneByte(FLAGE);& & FLAGE=read_reg_nrf24l01(0x07);//状态寄存器读取;发射前读取状态寄存器& & SendOneByte(FLAGE);& &&&write_rge_nrf24l01(0x00,0x0e);/*只允许中断开启,CRC使能,8位,PWR_UP=1(上电),PRIM_RX=0(发射模式)*///配置寄存器&&delay1ms(50);//此处指着个延时很管用,标志着24L01由掉电模式向待机-I模式转换的过程,以上是掉电模式一下就是待机-I模式了& &&&while(1)&&{& & set_Register_tx();// 待机1模式下的寄存器配置 //***********************************************************************& &&&CE=1;&&delay10us(2); //进入发射模式数据进行打包准备发送& && &CE=0;&&delay10us(15); //130微秒后进入发射模式CE=0;发送完毕后转到待机一I模式 //*888888& & do {&&SendOneByte(0x88);//发送标志位 FLAGE=read_reg_nrf24l01(0x07); //P0=FLAGE; SendOneByte(FLAGE); } while((~TX_DS)); //检查是否发送成功?成功向下,否则等待& &//*********************************************& && && &CE=0;//转到待机-I模式&&write_rge_nrf24l01(0x07,0x2e);/*清除发送中断信号*/& &&&SCK=0;& &&&CSN=1;& &&&CSN=0; write_spi_);//清除TX的FIFO寄存器为下一个包发送做准备& && &&&CSN=1;& &SendOneByte(0xe8);//发送标志位 FLAGE=read_reg_nrf24l01(0x17);//状态寄存器读取 SendOneByte(FLAGE); FLAGE=read_reg_nrf24l01(0x07);//状态寄存器读取;发射前读取状态寄存器& & SendOneByte(FLAGE);&&wk=0;& & } while(1); }
只有小组成员才能发言,
155个成员聚集在这个小组
创建小组步骤
创建小组创建自己的地盘
个性设置精心打造小组空间
邀请好友邀请好友加入我的小组
小组升级小组积分升级赢得社区推荐
林超文手把手教你学!
教你1000种电路设计思路
张飞硬件电路之PFC全集
参与免费送VIP+原创视频
运放、ADC、电磁兼容
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司

我要回帖

更多关于 “两不相帮”基本解释 的文章

 

随机推荐