STM32驱动NRF24L01一对多的通信---可变数据包宽度

 

既然是一对多可变payload宽度的通信,肯定是包含两个方面: 
(1)能进行一对多通信(同个频道下一般最多是一对六) 
(2)发送的数据包宽度是可变的 
配置NRF24L01进行一对多通信,前提是一对一通信机制必须要清楚。 
我个人的理解是这样的


PTX端需要配置的地址TX_ADDR和RX_ADDR 
PRX端需要配置的地址RX_ADDR 
至于以上地址在这个机制中是怎么用的,为什么会相同,下面会解释。 
进入正题 
ShockBurst™下数据包格式: 
这里写图片描述 
PTX端发送数据前,会先对数据进行打包。在这个数据包红色框中的就是PTX发射端的地址TX ADDR。当PRX接收到一包有效的数据时,它会解析这个数据包中的Address地址是否跟它自身RX_ADDR相同,如果是相同的,那它就认为这是个发给我的包,如果不相同呢,那肯定是发给别人的包,就会被丢弃。好的,发送和接收都搞明白了,还有应答信号(前提是使能了自动应答)。前面说了PRX会对比Address地址是否跟自身RX_ADDR相同,一旦对比成功,PRX会自动转换到发送模式并以这个地址作为发送地址发送应答信号。那么PTX是怎么接收这个应答信号的呢(前提是使能了自动应答),PTX在发送了一包数据后会自动转换为接收模式,等待接收PRX发过来的应答信号。那PTX是怎么知道需要接收哪个从机发送过来的应答信号呢,PTX端的RX_ADDR就起作用了,PTX也会检测应答包中的地址是不是跟自身的RX_ADDR地址相同,相同就表示这是个正确的应答包,TX_DS中断被触发,MCU通过识别中断号就能知道发送成功。 
明白了一对一通信的机制,也就明白了为什么PTX端的TX_ADDR,RX_ADDR,和PRX端的RX_ADDR是相同的。其实这三个地址说白了就是一个地址,就是PRX某个PIPEx的地址,这就是一对多通信的基础


一般来说一对多说的是,一个接收N个发送 
MultiCeiver(多方通信): 
MultiCeiver 是接收模式下的一个功能,包含了一组共六个并行的数据通道,每个通道都拥有独一无二的地址。一个RF通道对应一个逻辑数据通道。在NRF24L01+中,每个数据通道都有其自身的物理地址。 
这里写图片描述 
NRF24L01+配置成PRX(接收者)后,在同一通信频道中,可以接收6个不同数据通道的数据。6个NRF24L01+被配置为PTX(发送者),他们能与同一个PRX通信。PRX能同时搜寻所有的数据通道。但是同一时刻只有一个数据通道能接收数据包。所有的数据通道都能工作在Enhanced ShockBurst™下。 
以下配置所有的数据通道都一样:

CRC使能/失能(CRC在Enhanced ShockBurst™下一般都是被使能的) 
CRC编码 
RX地址宽度 
通信频道 
传输速率 
LNA增益

数据通道的使能在EN_RXADDR寄存器。默认情况下只有数据通道0和1被使能。每个数据通道的地址在RX_ADDR_Px寄存器中设置。 
NOTE:确保每个数据通道的地址都是不同的。否则GG

每个通道有5个字节的可配置地址。数据通道0有独一无二的5个字节的地址。数据管道1~5共享4地址字节。但是6个通道的最低字节必须是不同的。如图13的例子所示: 
这里写图片描述 
PRX使用MultiCeiver™ 和 Enhanced ShockBurst™与多个PTX通信。为了确保从PRX发送的应答包能被正确的PTX接收,PRX会获取当前接收到的数据包中的通道地址,然后以这个地址作为发送地址发送应答数据包。图14中的例子解释了PRX和PTX的地址配置详情。在PRX中RX_ADDR_Pn是管道地址,必须是独一无二的。在PTX中TX_ADDR是指定通道的通道地址,必须跟RX_ADDR_P0(没错就是RX_ADDR_P0不是RX_ADDR_Pn)中设置的地址相同。也就是说假如有6个PTX跟1个PRX建立通信,这6个PTX的TX ADDR1~TX ADDR6就必须要一一对应PRX端通道0~通道5的地址,而每个PTX端的接收通道0(RX_ADDR_P0)必须跟其对应的TX ADDR相同。 
这里写图片描述 
只有当一个数据通道接收一个正确的数据包时,其他的通道才能开始接收数据。 
 配置可变宽度的数据包 
Enhanced ShockBurst™有两种可供选择的payload长度: 
(1)static length,通过设置接收端的RX_PW_Px寄存实现,接收端TX FIFO中的数据长度必须跟接收端设置的想等。 
(2)Dynamic payload length(DPL):DPL允许PTX端发送可变长度payload给接收端,而接收端不需要使用RX_PW_Px寄存器,MCU使用R_RX_PL_WID命令能读出payload的长度。 
使用DPL模式,必须使能FREATURE寄存器的EN_DPL位,在接收模式下,DYNPD寄存器的DPL_Px必须要设置。 
NOTE:MCU最好能每次都检查一下接收到的payload的长度是不否大于32字节,如果大于32字节可能是接收到看错误的信息,需要丢弃。丢弃一帧数据包使用Flush_RX命令。 
注意:PTX和PRX同时需要设置FREATURE寄存器的EN_DPL位和DYNPD寄存器的DPL_Px位。 
举个一对六的配置 

接收节点

 

const u8 PIPE0_RX_ADDRESS[RX_ADR_WIDTH]={0x78,0x78,0x78,0x78,0x78};//接收通道0地址
const u8 PIPE1_RX_ADDRESS[RX_ADR_WIDTH]={0xF1,0xB3,0xB4,0xB5,0xB6};//接收通道0地址
const u8 PIPE2_RX_ADDRESS[1]={0xCD};//接收通道0地址,PIPE2~5共用PIPE1的4字节地址,低字节地址在前,下同
const u8 PIPE3_RX_ADDRESS[1]={0xA3};//接收通道0地址
const u8 PIPE4_RX_ADDRESS[1]={0x0F};//接收通道0地址
const u8 PIPE5_RX_ADDRESS[1]={0x05};//接收通道0地址
void NRF24L01_RX_Mode(void)
{
    NRF24L01_CE_L();      
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)PIPE0_RX_ADDRESS,RX_ADR_WIDTH);//写通道0地址
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P1,(u8*)PIPE1_RX_ADDRESS,RX_ADR_WIDTH);//写通道1地址
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P2,(u8*)PIPE2_RX_ADDRESS,1);//写通道2地址
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P3,(u8*)PIPE3_RX_ADDRESS,1);//写通道3地址
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P4,(u8*)PIPE4_RX_ADDRESS,1);//写通道4地址
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P5,(u8*)PIPE5_RX_ADDRESS,1);//写通道5地址
    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,0x40);        //设置发送频道24.064Ghz 
//  NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//通道0数据宽度,DPL不需要设置接收数据宽度所以注释掉,下同
//  NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);//通道1数据宽度
    NRF24L01_Write_Reg(NRF_WRITE_REG+FEATURE,0x04|0x02);    //配合DPL功能使用
    NRF24L01_Write_Reg(NRF_WRITE_REG+DYNPD,0x3f);    //使能所有通道DPL功能
    NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x07); 
    NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//主接收
    NRF24L01_CE_H(); //启动接收
}       


发送节点0的代码,1~5只要更换本地地址和接收地址就行啦,6个不同的地址下面都列出来了

 

 

 

 

u8 const PIPE0_TX_ADDRESS[TX_ADR_WIDTH]= {0x78,0x78,0x78,0x78,0x78};    //PTX0本地地址
u8 const PIPE0_RX_ADDRESS[RX_ADR_WIDTH]= {0x78,0x78,0x78,0x78,0x78};    //PIPE0接收地址

u8 const PIPE1_TX_ADDRESS[TX_ADR_WIDTH]= {0xF1,0xB3,0xB4,0xB5,0xB6,};   //PTX1本地地址
u8 const PIPE1_RX_ADDRESS[RX_ADR_WIDTH]= {0xF1,0xB3,0xB4,0xB5,0xB6,};   //PIPE1接收地址

u8 const PIPE2_TX_ADDRESS[TX_ADR_WIDTH]= {0xCD,0xB3,0xB4,0xB5,0xB6};        //PTX2本地地址
u8 const PIPE2_RX_ADDRESS[RX_ADR_WIDTH]= {0xCD,0xB3,0xB4,0xB5,0xB6};        //PIPE2接收地址

u8 const PIPE3_TX_ADDRESS[TX_ADR_WIDTH]= {0xA3,0xB3,0xB4,0xB5,0xB6};        //PTX3本地地址
u8 const PIPE3_RX_ADDRESS[RX_ADR_WIDTH]= {0xA3,0xB3,0xB4,0xB5,0xB6};        //PIPE3接收地址

u8 const PIPE4_TX_ADDRESS[TX_ADR_WIDTH]= {0x0F,0xB3,0xB4,0xB5,0xB6};        //PTX4本地地址
u8 const PIPE4_RX_ADDRESS[RX_ADR_WIDTH]= {0x0F,0xB3,0xB4,0xB5,0xB6};        //PIPE4接收地址

u8 const PIPE5_TX_ADDRESS[TX_ADR_WIDTH]= {0x05,0xB3,0xB4,0xB5,0xB6};        //PTX5本地地址
u8 const PIPE5_RX_ADDRESS[RX_ADR_WIDTH]= {0x05,0xB3,0xB4,0xB5,0xB6};        //PIPE5接收地址

void NRF24L01_TX_Mode(void)
{                                                        
    NRF24L01_CE_L();    
    NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)PIPE0_TX_ADDRESS,TX_ADR_WIDTH);//写发送端的地址
    NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)PIPE0_RX_ADDRESS,RX_ADR_WIDTH);//写接收端PIPE0的地址  

    NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);     //使能PIPE0自动应答
    NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能PIPE0接收地址
    NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);
    NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,0x40);
    NRF24L01_Write_Reg(NRF_WRITE_REG+FEATURE,0x04|0x02);    //配合DPL功能使用
    NRF24L01_Write_Reg(NRF_WRITE_REG+DYNPD,0x3f);    //使能所有通道DPL功能
    NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x07); 
    NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);
    NRF24L01_CE_H();
}

制作信标灯 
2017/3/18

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值