/*! * @brief NRF24L01+进入发送模式 * @since v5.0 */ void nrf_tx_mode(void) { volatile uint32 i; NRF_CE_LOW(); //DELAY_MS(1); nrf_writebuf(NRF_WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //写TX节点地址 nrf_writebuf(NRF_WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //设置RX节点地址 ,主要为了使能ACK nrf_writereg(NRF_WRITE_REG + CONFIG, 0x0A | (IS_CRC16 << 2)); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断 /*CE拉高,进入发送模式*/ NRF_CE_HIGH(); nrf_mode = TX_MODE; i = 0x0fff; while(i--); //CE要拉高一段时间才进入发送模式 //DELAY_MS(1); }
void RX_Mode(void) { DrvGPIO_ClrBit(E_GPB, 0x01); nrf_writebuf(W_REGISTER+TX_ADDR,(uchar*)TxAddr,5);//写TX节点地址 nrf_writebuf(W_REGISTER+RX_ADDR_P0,(uchar*)RxAddr,5); //设置TX节点地址,主要为了使能ACK nrf_write(W_REGISTER + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 nrf_write(W_REGISTER + EN_RXADDR, 0x01); // Enable Pipe0 nrf_write(W_REGISTER + RF_CH, 40); // Select RF channel 40 nrf_write(W_REGISTER + RX_PW_P0, 4); nrf_write(W_REGISTER + RF_SETUP, 0x0f); nrf_write(W_REGISTER + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 bytes) DrvGPIO_SetBit(E_GPB,1); // This device is now ready to receive one packet of 16 bytes payload from a TX device // '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and }
/*! * @brief NRF24L01+初始化,默认进入接收模式 * @return 初始化成功标记,0为初始化失败,1为初始化成功 * @since v5.0 * Sample usage: while(!nrf_init()) //初始化NRF24L01+ ,等待初始化成功为止 { printf("\n NRF与MCU连接失败,请重新检查接线。\n"); } printf("\n NRF与MCU连接成功!\n"); */ uint8 nrf_init(void) { //配置NRF管脚复用 spi_init(NRF_SPI, NRF_CS, MASTER,12500*1000); //初始化SPI,主机模式 gpio_init(NRF_CE_PTXn, GPO, LOW); //初始化CE,默认进入待机模式 gpio_init(NRF_IRQ_PTXn, GPI, LOW); //初始化IRQ管脚为输入 port_init_NoALT(NRF_IRQ_PTXn, IRQ_FALLING | PULLUP); //初始化IRQ管脚为下降沿 触发中断 //配置NRF寄存器 NRF_CE_LOW(); nrf_writereg(NRF_WRITE_REG + SETUP_AW, ADR_WIDTH - 2); //设置地址长度为 TX_ADR_WIDTH nrf_writereg(NRF_WRITE_REG + RF_CH, CHANAL); //设置RF通道为CHANAL nrf_writereg(NRF_WRITE_REG + RF_SETUP, 0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 nrf_writereg(NRF_WRITE_REG + EN_AA, 0x01); //使能通道0的自动应答 nrf_writereg(NRF_WRITE_REG + EN_RXADDR, 0x01); //使能通道0的接收地址 //RX模式配置 nrf_writebuf(NRF_WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //写RX节点地址 nrf_writereg(NRF_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //选择通道0的有效数据宽度 nrf_writereg(FLUSH_RX, NOP); //清除RX FIFO寄存器 //TX模式配置 nrf_writebuf(NRF_WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //写TX节点地址 nrf_writereg(NRF_WRITE_REG + SETUP_RETR, 0x0F); //设置自动重发间隔时间:250us + 86us;最大自动重发次数:15次 nrf_writereg(FLUSH_TX, NOP); //清除TX FIFO寄存器 nrf_rx_mode(); //默认进入接收模式 NRF_CE_HIGH(); return nrf_link_check(); }
/*****************NRF????????????******************************/ void NRFSetTxMode(uchar *TxDate) {//???? char ret; DrvGPIO_ClrBit(E_GPB, 1); nrf_writebuf(W_REGISTER+TX_ADDR,(uchar*)TxAddr,5);//写TX节点地址 nrf_writebuf(W_REGISTER+RX_ADDR_P0,(uchar*)TxAddr,5); //设置TX节点地址,主要为了使能ACK ret=nrf_read(STATUS); delay_s(); nrf_write(W_REGISTER+STATUS,0x10); //使能通道0的自动应答 ret=nrf_read(STATUS); nrf_write(W_REGISTER+EN_AA,0x01); //使能通道0的自动应答 nrf_write(W_REGISTER+EN_RXADDR,0x01); //使能通道0的接收地址 nrf_write(W_REGISTER+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 nrf_write(W_REGISTER+RF_CH,40); //设置RF通道为40 nrf_write(W_REGISTER+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 nrf_write(W_REGISTER+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 DrvGPIO_SetBit(E_GPB,1); // This device is now ready to receive one packet of 16 bytes payload from a TX device }
uint8 nrf_tx(uint8 *txbuf, uint32 len) { nrf_irq_tx_flag = 0; //复位标志位 if((txbuf == 0 ) || (len == 0)) { return 0; } if(nrf_irq_tx_addr == 0 ) { // nrf_irq_tx_pnum = (len - 1) / DATA_PACKET; // 进 1 求得 包 的数目 nrf_irq_tx_addr = txbuf; if( nrf_mode != TX_MODE) { nrf_tx_mode(); } //需要 先发送一次数据包后才能 中断发送 /*ce为低,进入待机模式1*/ NRF_CE_LOW(); /*写数据到TX BUF 最大 32个字节*/ nrf_writebuf(WR_TX_PLOAD, txbuf, DATA_PACKET); /*CE为高,txbuf非空,发送数据包 */ NRF_CE_HIGH(); return 1; } else { return 0; } }
/*! * @brief NRF24L01+进入接收模式 * @since v5.0 */ void nrf_rx_mode(void) { NRF_CE_LOW(); nrf_writereg(NRF_WRITE_REG + EN_AA, 0x01); //使能通道0的自动应答 nrf_writereg(NRF_WRITE_REG + EN_RXADDR, 0x01); //使能通道0的接收地址 nrf_writebuf(NRF_WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); //写RX节点地址 nrf_writereg(NRF_WRITE_REG + CONFIG, 0x0B | (IS_CRC16 << 2)); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 /* 清除中断标志*/ nrf_writereg(NRF_WRITE_REG + STATUS, 0xff); nrf_writereg(FLUSH_RX, NOP); //清除RX FIFO寄存器 /*CE拉高,进入接收模式*/ NRF_CE_HIGH(); nrf_mode = RX_MODE; }
unsigned char NRF24L01_TxPacket(unsigned char *txbuf) { unsigned char sta; DrvGPIO_ClrBit(E_GPB, 1); nrf_writebuf(W_TX_PAYLOAD,txbuf,TX_DATA_WITDH);//写数据到TX BUF 32个字节 DrvGPIO_SetBit(E_GPB,1); // This device is now ready to receive one packet of 16 bytes payload from a TX device while(DrvGPIO_GetBit(E_GPB, 2)!=0);//等待发送完成 sta=nrf_read(STATUS); //读取状态寄存器的值 nrf_write(W_REGISTER+STATUS,sta); //清除TX_DS或MAX_RT中断标志 if(sta&0x10)//达到最大重发次数 { nrf_wf(FLUSH_TX);//清除TX FIFO寄存器 nrf_write(W_REGISTER+STATUS,sta); //清除TX_DS或MAX_RT中断标志 sta=nrf_read(STATUS); //读取状态寄存器的值 return 0x10; } if(sta&0x20)//发送完成 { return 0x20; } return 0xff;//其他原因发送失败 }
void nrf_handler(void) { uint8 state; uint8 tmp; /*读取status寄存器的值 */ nrf_readreg(STATUS, &state); /* 清除中断标志*/ nrf_writereg(NRF_WRITE_REG + STATUS, state); if(state & RX_DR) //接收到数据 { NRF_CE_LOW(); if(nrf_rx_flag != QUEUE_FULL) { //还没满,则继续接收 //printf("+"); nrf_readbuf(RD_RX_PLOAD, (uint8 *)&(NRF_ISR_RX_FIFO[nrf_rx_rear]), RX_PLOAD_WIDTH); //读取数据 nrf_rx_rear++; if(nrf_rx_rear >= RX_FIFO_PACKET_NUM) { nrf_rx_rear = 0; //重头开始 } tmp = nrf_rx_front; if(nrf_rx_rear == tmp) //追到屁股了,满了 { nrf_rx_flag = QUEUE_FULL; } else { nrf_rx_flag = QUEUE_NORMAL; } } else { nrf_writereg(FLUSH_RX, NOP); //清除RX FIFO寄存器 } NRF_CE_HIGH(); //进入接收模式 } if(state & TX_DS) //发送完数据 { if(nrf_irq_tx_pnum == 0) { nrf_irq_tx_addr = 0; // 注意: nrf_irq_tx_pnum == 0 表示 数据 已经全部发送到FIFO 。 nrf_irq_tx_addr == 0 才是 全部发送完了 //发送完成后 默认 进入 接收模式 #if 1 if( nrf_mode != RX_MODE) { nrf_rx_mode(); } #endif //发送长度 为 0个包,即发送完成 //nrf_writereg(FLUSH_TX, NOP); //清除TX FIFO寄存器 } else { if( nrf_mode != TX_MODE) { nrf_tx_mode(); } //还没发送完成,就继续发送 nrf_irq_tx_addr += DATA_PACKET; //指向下一个地址 nrf_irq_tx_pnum --; //包数目减少 /*ce为低,进入待机模式1*/ NRF_CE_LOW(); /*写数据到TX BUF 最大 32个字节*/ nrf_writebuf(WR_TX_PLOAD, (uint8 *)nrf_irq_tx_addr, DATA_PACKET); /*CE为高,txbuf非空,发送数据包 */ NRF_CE_HIGH(); } } if(state & MAX_RT) //发送超时 { nrf_irq_tx_flag = 1; //标记发送失败 nrf_writereg(FLUSH_TX, NOP); //清除TX FIFO寄存器 //有可能是 对方也处于 发送状态 //放弃本次发送 nrf_irq_tx_addr = 0; nrf_irq_tx_pnum = 0; nrf_rx_mode(); //进入 接收状态 //printf("\nMAX_RT"); } if(state & TX_FULL) //TX FIFO 满 { //printf("\nTX_FULL"); } }