nRF24L01是NORDIC公司生产的一款无线通信芯片,采用FSK调制,内部集成NORDIC自己的Enhanced ShortBurst协议。可以实现点对点或者是1对6的无线通信。无线通信速度可以达到2Mbps。 但是具体如何实现一对六通信,芯片手册中也只是简单的介绍只要6路数据通道的发送地址和接收地址匹配即可。但是如何匹配并没有给出明确的说明。这就产生了一个问题。对于0和1通道,接收端和发送端的地址是可以都写成5个字节的地址,当然可以两端是同样的地址,很容易就实现了通信;但是对于2、3、4、5通道,接收端的地址只有低字节可以设置,发送端的发送地址却是5个字节的。如何相同是个问题。 查找网络上有很多人分享的程序,虽然他们说着是1对6的程序,但是下载下来试了2~5通道都不能用,其中包括广为流传的Bluebird的程序也是不能用的。FLY2000开发板的技术部人员说不能实现一对六,他们只做过点对点;迅通科技的工程师说需要组网和跳频才能实现。我只能说我很无语。 通过求教他人和仔细阅读数据手册,最后把一对六调通了,其中也遇到了一个小问题,就是如何判断接收数据通道号的问题。芯片的状态寄存器STATUS,其中RX_P_NO这三位就是代表了接收数据通道号,在我们读这个寄存器的值得时候却一直出现0x0E这个值,数据明明是接收到了,这个值却是错了,下面也会给出原因和解决方法。 下面想把已经调试通过的NRF24L01一对六的程序写出来,但是eeeeeee额,不知道为么,最重要的地址部分一提交博文就看不到了,难道内容**??那我只能把需要注意的点提出来: 接收部分的地址设置: uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x78,0x78,0x78,0x78,0x78}; // 本地地址
uchar code RX_ADDRESS0[TX_ADR_WIDTH] = {0x78,0x78,0x78,0x78,0x78};//写地址寄存器是先写低字节,因此后面几个字节相同
uchar code RX_ADDRESS1[TX_ADR_WIDTH] = {0xF1,0xB6,0xB5,0xB4,0xB3};//写地址寄存器是先写低字节,因此后面几个字节相同
uchar code RX_ADDRESS2[1] = {0xCD};
uchar code RX_ADDRESS3[1] = {0xA3};
uchar code RX_ADDRESS4[1] = {0x0F};
uchar code RX_ADDRESS5[1] = {0x05};
void init_NRF24L01(void)
{
inerDelay_us(600);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; //
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
_nop_();
_nop_();
_nop_();
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS0, TX_ADR_WIDTH); // 写接收端0地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P1, RX_ADDRESS1, TX_ADR_WIDTH); // 写接收端1地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P2, RX_ADDRESS2, 1); // 写接收端2地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P3, RX_ADDRESS3, 1); // 写接收端3地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P4, RX_ADDRESS4, 1); // 写接收端4地址
SPI_Write_Buf(WRITE_REG + RX_ADDR_P5, RX_ADDRESS5, 1); // 写接收端5地址
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 接收通道0选择和发送通道相同有效数据宽度,32字节长度
SPI_RW_Reg(WRITE_REG + RX_PW_P1, TX_PLOAD_WIDTH);//32字节长度
SPI_RW_Reg(WRITE_REG + RX_PW_P2, TX_PLOAD_WIDTH);//32字节长度
SPI_RW_Reg(WRITE_REG + RX_PW_P3, TX_PLOAD_WIDTH);//32字节长度
SPI_RW_Reg(WRITE_REG + RX_PW_P4, TX_PLOAD_WIDTH);//32字节长度
SPI_RW_Reg(WRITE_REG + RX_PW_P5, TX_PLOAD_WIDTH);//32字节长度
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + EN_AA, 0x3f); // 所有通道自动 ACK应答允许
_nop_();
_nop_();
_nop_();
//SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x3f); //使能所有接受通道
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0F); //设置发射速率为1MHZ,发射功率为最大值0dB
CE=1;
}
发送端的库函数:因为0和1通道的发送端的发送地址(本地地址)和接收端的P0、P1一样即可,现只给出2通道的例子,剩下的3、4、5通道的设置就和2的类似。uint const TX_ADDRESS[TX_ADR_WIDTH] = {0xCD,0xB6,0xB5,0xB4,0xB3}; //本地地址
uint const RX_ADDRESS[TX_ADR_WIDTH] = {0xCD,0xB6,0xB5,0xB4,0xB3}; //接收地址
void init_NRF24L01(void)
{
inerDelay_us(600);
CE=0; // chip enable
CSN=1; // Spi disable
SCK=0; //
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址
_nop_();
_nop_();
_nop_();
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动 ACK应答允许
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
_nop_();
_nop_();
_nop_();
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0F); //设置发射速率为1MHZ,发射功率为最大值0dB
CE=1;
}
|