多对一通信功能(ACK模式,ACK带PAYLOAD)
nRF24L01无线通信芯片可以实现多个发射端对一个接收端通信方式,接收方需要同时开启多个pipe来接收来自不同发射端的数据,每个pipe设置不同的地址,最多可以设置六个pipe,然后配置工作方式,包括信道(RF_CH)、CRC、地址、动态负载、动态负载长度使能。
发射端工作方式需要与接收方一致,包括信道(RF_CH)、CRC、地址、是否为动态负载、动态负载长度使能等,都需要与接收方保持一致。
参考方案:
如图
RX
TX0
TX1
TX2
TX3
TX4
TX5
Pipe0
Pipe1
Pipe2
Pipe3
Pipe4
Pipe5
接收方同时开启六个pipe。地址长度为5字节,分别为:
Pipe0[39:0]:0x65 , 0x54 , 0x43 , 0x32 , 0xA0
Pipe1[39:0]:0xE9 , 0xD8 , 0xC7 , 0xB6 , 0xA1
Pipe2[39:0]:0xE9 , 0xD8 , 0xC7 , 0xB6 , 0xA2
Pipe3[39:0]:0xE9 , 0xD8 , 0xC7 , 0xB6 , 0xA3
Pipe4[39:0]:0xE9 , 0xD8 , 0xC7 , 0xB6 , 0xA4
Pipe5[39:0]:0xE9 , 0xD8 , 0xC7 , 0xB6 , 0xA5
注:pipe0地址可以任意取值,pipe1-pipe5地址的低字节共用。
配置过程:
接收端:(步骤2—9顺序可任意)
(1) CE = 0 ,进入shutdown模式。
CE = 0;
(2) 设置地址宽度,SETUP_AW
spi_rw_reg(W_REGISTER + SETUP_AW, 0x03); // 5 byte Address width
(3) 配置不同pipe的地址,RX_ADDR_PX。
spi_write_buf(W_REGISTER + RX_ADDR_P0, RX_ADDRESS, TX_ADR_WIDTH);
spi_write_buf(W_REGISTER + RX_ADDR_P1, RX_ADDRESS1, TX_ADR_WIDTH); spi_rw_reg(W_REGISTER + RX_ADDR_P2, 0xA2);
spi_rw_reg(W_REGISTER + RX_ADDR_P3, 0xA3);
spi_rw_reg(W_REGISTER + RX_ADDR_P4, 0xA4);
spi_rw_reg(W_REGISTER + RX_ADDR_P5, 0xA5);
(4) 开启所有pipe的自动确认(复位默认值为开启状态,可以不配置)
spi_rw_reg(W_REGISTER + EN_AA , 0x3F); //开启所有pipe的自动确认
(5) 使能6个pipe的接收地址
spi_rw_reg(W_REGISTER + EN_RXADDR, 0x3F); //使能6个pipe的接收地址
(6) 使能动态负载长度及对应pipe的动态负载长度,FEATURE及DYNPD
spi_rw_reg(W_REGISTER + FEATURE, 0x06); //使能动态负载长度及ACK_PAYLOAD
spi_rw_reg(W_REGISTER + DYNPD, 0x3F) ; //使能6个pipe的动态负载长度
(7) 设置射频信道,RF_CH
spi_rw_reg(W_REGISTER + RF_CH, 0x40); // 选择射频信道0x40
(8) 设置通信速率及发射功率,RF_SETUP
spi_rw_reg(W_REGISTER + RF_SETUP, 0x0f ) ; //设置通信速率为2Mbps,
//发射功率为7dbm
(9) 配置CRC,使能CRC及配置CRC长度,设置屏蔽中断模式,进入standby模式
spi_rw_reg(W_REGISTER + CONFIG, 0x0B); //设置为接收模式,使能CRC并设置为1字节(要与发射端匹配),产生RF_IRQ硬件中断
(10)写ACK PAYLOAD,使用
spi_write_buf(0xA9 , TX_BUF, TX_PLOAD_WIDTH);//TX_BUF为PAYLOAD数据指针
(11)CE = 1 ,拉高CE,进入接收模式
CE = 1;
接收到数据后可以通过中断或查询方式,使用R_RX_PAYLOAD命令读FIFO。按以上配置,芯片从shutdown模式直接进入接收模式,所以,从CE = 1 到能正常接收到数据至少需要2ms。
说明:收到数据后要重新写入ACKPAYLOAD。
发射端以pipe 1为例(步骤2—11顺序可任意)
(1) CE = 0 ,进入shutdown模式
CE = 0;
(2) 配置地址宽度,SETUP_AW
spi_rw_reg(W_REGISTER + SETUP_AW, 0x03); // 地址长度为5字节
(3) 配置发射地址,TX_ADDR,pipe3地址
spi_write_buf(W_REGISTER + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写入发送地址
(4) 配置接收地址,pipe1地址(用来接收ACK信号)。
spi_write_buf(W_REGISTER + RX_ADDR_P0, TX_ADDRESS , TX_ADR_WIDTH);
(5) 设置射频信道,RF_CH
spi_rw_reg(W_REGISTER + RF_CH, 0x40);
(6) 使能动态负载
spi_rw_reg(W_REGISTER + FEATURE, 0x06);//使能动态负载长度及ACKPAYLOAD
spi_rw_reg(W_REGISTER + DYNPD,0x01); //使能信道0的动态负载长度,接收ACK
(7) 设置自动重发延时ARD 和最大重发次数ARC
spi_rw_reg(W_REGISTER + SETUP_RETR , 0x13) ; //自动重发延时为500us,最多
//重发次数为3次
(8) 设置通信速率及发射功率,RF_SETUP
spi_rw_reg(W_REGISTER + RF_SETUP, 0x0f ) ; //设置通信速率为2Mbps,
//发射功率为7dbm
(9) 开启pipe0接收ACK,EN_AA
spi_rw_reg(W_REGISTER + EN_AA , 0x01); //开启所有pipe0的自动确认,复
//位值默认开启
(10)用W_TX_PAYLOAD写FIFO
spi_write_buf(W_TX_PAYLOAD, buf, TX_PLOAD_WIDTH); // 写数据到TX FIFO
(11)使能CRC,设置屏蔽中断,进入TX-STB模式
spi_rw_reg(W_REGISTER + CONFIG, 0x0A); // 8位CRC校验,配置为发射端
(12)发射数据
CE = 1;
注:以上配置方式为shutdown模式直接进入发射模式,CE高脉冲维持时间至少为2ms,如果是从TX-STB模式进入发射模式,CE只需要10us左右的高脉冲即可。
说明:发射成功,收到ACK后,可以用R_RX_PAYLOAD命令读RX FIFO。
附:
(1)全局变量定义:
// SPI commands (Si24R1)
#define R_REGISTER 0x00 // Define Read command to register
#define W_REGISTER 0x20 // Define Write command to register
#define R_RX_PAYLOAD 0x61 // Define Read RX payload register address
#define W_TX_PAYLOAD 0xA0 // Define Write TX payload register address
#define FLUSH_TX 0xE1 // Define Flush TX register command
#define FLUSH_RX 0xE2 // Define Flush RX register command
#define REUSE_TX_PL 0xE3 // Define Reuse TX payload register command
#define R_RX_PL_WID 0x60 // Define Read RX payload width for the
//R_RX_PAYLOAD in the RX FIFO
#define W_ACK_PAYLOAD 0xA8 // Define Write Payload to be transmitted //together with ACK packet on PIPExxx xxx valid in the range from 000 to 101)
#define W_TX_PAYLOAD_NOACK 0xB0 // Define Write TX Disables AUTOACK
//on this specific packet
// SPI registers address(Si24R1)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
#define DYNPD 0x1C // 'Enable dynamic paload length' register address
#define FEATURE 0x1D // Feature Register address
(2)接收端代码
#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址
#define TX_PLOAD_WIDTH 32
//---------------------------- ----------------------------------
uchar code RX_ADDRESS[TX_ADR_WIDTH] = {0xA0,0x32,0x43,0x54,0x65}; //
//定义一个静态发送地址
uchar code RX_ADDRESS1[TX_ADR_WIDTH] = {0xA1,0xB6,0xC7,0xD8,0xE9 };
void rx_mode(void)
{
CE = 0;
spi_rw_reg(W_REGISTER + SETUP_AW, 0x03); // 5 byte Address width
spi_write_buf(W_REGISTER + RX_ADDR_P0, RX_ADDRESS, TX_ADR_WIDTH);
spi_write_buf(W_REGISTER + RX_ADDR_P1, RX_ADDRESS1, TX_ADR_WIDTH); //
//接收设备接收信道4使用和发送设备相同的发送地址
spi_rw_reg(W_REGISTER + RX_ADDR_P2, 0xA2);
spi_rw_reg(W_REGISTER + RX_ADDR_P3, 0xA3);
spi_rw_reg(W_REGISTER + RX_ADDR_P4, 0xA4);
spi_rw_reg(W_REGISTER + RX_ADDR_P5, 0xA5);
spi_rw_reg(W_REGISTER + EN_AA , 0x3F); // 开启所有pipe的自动确认,
//复位值默认开启
spi_rw_reg(W_REGISTER + EN_RXADDR, 0x3F); //使能6个pipe的接收地址
spi_rw_reg(W_REGISTER + FEATURE, 0x06) ; // 使能动态负载长度及ACKPAYLOAD
spi_rw_reg(W_REGISTER + DYNPD, 0x3F); //使能6个pipe的动态负载长度
spi_rw_reg(W_REGISTER + RF_CH, 0x40); // 选择射频信道0x40
spi_rw_reg(W_REGISTER + RF_SETUP, 0x0f ) ; //设置通信速率为2Mbps,
//发射功率为7dbm
spi_rw_reg(W_REGISTER + CONFIG, 0x0B); //设置为接收模式,
//使能CRC并设置为1字节(要与发射端匹配),不屏蔽中断
CE = 1; //拉高CE启动接收设备
}
说明:在开启接收模式前或新接收一帧数据之前,必须保证TX FIFO里有ACKPAYLOAD,用以下命令写FIFO:
spi_write_buf(W_ACK_PAYLOAD+NUM , TX_BUF, TX_PLOAD_WIDTH);//表示写入的数据为pipe号为NUM的ACKPAYLOAD,TX_BUF为写入数据指针
(3)发射端代码
#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址
#define TX_PLOAD_WIDTH 32 //设置写入FIFO数据长度
uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0xA1,0xB6,0xC7,0xD8,0xE9};//发射端
//所对应pipe的地址
void tx_mode(uchar *tx_buf)
{
CE = 0;
spi_rw_reg(W_REGISTER + SETUP_AW, 0x03); // 5 byte Address width
spi_write_buf(W_REGISTER + TX_ADDR, TX_ADDRESS , TX_ADR_WIDTH);
//配置发射地址
spi_write_buf(W_REGISTER + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
//配置接收地址
spi_rw_reg(W_REGISTER + RF_CH, 0x40); // 选择射频信道0x40
spi_rw_reg(W_REGISTER + FEATURE, 0x06); //使能动态负载长度及ACKPAYLOAD
spi_rw_reg(W_REGISTER + DYNPD,0x01); //使能pipe0动态负载长度
spi_rw_reg(W_REGISTER + SETUP_RETR , 0x13); //自动重发延时为500us,
//最多重发次数为3次
spi_rw_reg(W_REGISTER + RF_SETUP, 0x0f ); //设置通信速率为2Mbps,
//发射功率为7dbm
spi_rw_reg(W_REGISTER + EN_AA , 0x01); //开启pipe0的自动确认,复位值默认开启
spi_write_buf(W_TX_PAYLOAD, buf, TX_PLOAD_WIDTH);//写数据到TX FIFO
spi_rw_reg(W_REGISTER + CONFIG, 0x0A); //8位CRC校验,上电, 发射模式
CE = 1;
}
详细全部资料可以留言博主。可以提供更多的技术支持。