uint32 nrf_rx(uint8 *rxbuf, uint32 len) { uint32 tmplen = 0; uint8 tmp; while( (nrf_rx_flag != QUEUE_EMPTY) && (len != 0) ) { if(len < DATA_PACKET) { vcan_cpy(rxbuf, (uint8 *)&(NRF_ISR_RX_FIFO[nrf_rx_front]), len); NRF_CE_LOW(); //进入待机状态 nrf_rx_front++; //由于非空,所以可以直接出队列 if(nrf_rx_front >= RX_FIFO_PACKET_NUM) { nrf_rx_front = 0; //重头开始 } tmp = nrf_rx_rear; if(nrf_rx_front == tmp) //追到屁股了,接收队列空 { nrf_rx_flag = QUEUE_EMPTY; } NRF_CE_HIGH(); //进入接收模式 tmplen += len; return tmplen; } vcan_cpy(rxbuf, (uint8 *)&(NRF_ISR_RX_FIFO[nrf_rx_front]), DATA_PACKET); rxbuf += DATA_PACKET; len -= DATA_PACKET; tmplen += DATA_PACKET; NRF_CE_LOW(); //进入待机状态 nrf_rx_front++; //由于非空,所以可以直接出队列 if(nrf_rx_front >= RX_FIFO_PACKET_NUM) { nrf_rx_front = 0; //重头开始 } tmp = nrf_rx_rear; if(nrf_rx_front == tmp) //追到屁股了,接收队列空 { nrf_rx_flag = QUEUE_EMPTY; } else { nrf_rx_flag = QUEUE_NORMAL; } NRF_CE_HIGH(); //进入接收模式 } return tmplen; }
//由中断服务函数调用 void NRF_ISR_Rx_Handler(void) { u8 state; NRF_CE_LOW(); //进入待机状态 /*读取status寄存器的值 */ state=NRF_ReadReg(STATUS); /* 清除中断标志*/ NRF_WriteReg(NRF_WRITE_REG+STATUS,state); if(re_flag == QUEUE_FULL) //满了就直接清FIFO,退出 { NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器 NRF_CE_HIGH(); //进入接收模式 return; //接收队列满了,不进行处理 } //还没满,则继续接收 /*判断是否接收到数据*/ if(state & RX_DR) //接收到数据 { NRF_ReadBuf(RD_RX_PLOAD,(u8 *)&(RX_ISR_FIFO[rear]),RX_PLOAD_WIDTH); //读取数据 NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器 rear++; if(rear >= RX_ISR_FIFO_PACKET) { rear=0; //重头开始 } if(rear == front) //追到屁股了,满了 { re_flag = QUEUE_FULL; } else { re_flag = QUEUE_NORMAL; } } else { //没收到任何数据 } NRF_CE_HIGH(); //进入接收模式 }
/* * 函数名:NRF_RX_Mode * 描述 :配置并进入接收模式 * 输入 :无 * 输出 :无 * 调用 :外部调用 */ 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,接收模式 #if 1 /* 清除中断标志*/ NRF_WriteReg(NRF_WRITE_REG+STATUS,0xff); NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器 #endif /*CE拉高,进入接收模式*/ NRF_CE_HIGH(); nrf_mode = RX_MODE; }
/*! * @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 nrf_send_frame (uint8_t * frame, int send_mode) { int ret; if (mode != MODE_NOMODE) return; UART2PutStr ("sf\n\r"); nrf_write_reg (R_CONFIG, R_CONFIG_PWR_UP | R_CONFIG_EN_CRC); NRF_CS_LOW (); mLED_2_On (); SPI2_xmit (C_W_TX_PAYLOAD); SPI2_transmit (frame, 32); mLED_2_Off (); NRF_CS_HIGH (); NRF_CE_HIGH (); while (1) { ret = nrf_read_reg (R_FIFO_STATUS); if (send_mode) { if ((ret & R_FIFO_STATUS_TX_EMPTY) == R_FIFO_STATUS_TX_EMPTY) break; } else { if ((ret & R_FIFO_STATUS_TX_FULL) == 0) break; } } NRF_CE_LOW (); }
//传输一次,数据最长为 32字节 static u8 NRF_TX_Dat_Once(u8 *txbuf) { u8 state; /*ce为低,进入待机模式1*/ NRF_CE_LOW(); /*写数据到TX BUF 最大 32个字节*/ NRF_WriteBuf(WR_TX_PLOAD,txbuf,MAX_ONCE_TX_NUM); /*CE为高,txbuf非空,发送数据包 */ NRF_CE_HIGH(); /*等待发送完成中断 */ while(NRF_Read_IRQ()!=0); /*读取状态寄存器的值 */ state = NRF_ReadReg(STATUS); /*清除TX_DS或MAX_RT中断标志*/ NRF_WriteReg(NRF_WRITE_REG+STATUS,state); NRF_WriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器 /*判断中断类型*/ return state; }
/** * @brief 用于从NRF的接收缓冲区中读出数据 * @param * @arg rxBuf :用于接收该数据的数组,外部定义 * @retval * @arg 接收结果 */ u8 NRF_Rx_Dat(u8 *rxbuf) { u8 state; u16 link_count=0; NRF_CE_HIGH(); //进入接收状态 /*等待接收中断*/ while(NRF_Read_IRQ()!=0) { link_count ++; if(link_count == 5000) //5000为最大重连次数 return ERROR; } NRF_CE_LOW(); //进入待机状态 /*读取status寄存器的值 */ state=SPI_NRF_ReadReg(STATUS); /* 清除中断标志*/ SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); /*判断是否接收到数据*/ if(state&RX_DR) //接收到数据 { SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 SPI_NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器 return RX_DR; } else return ERROR; //没收到任何数据 }
/* * 函数名:NRF_Rx_Dat * 描述 :用于从NRF的接收缓冲区中读出数据 * 输入 :rxBuf:用于接收该数据的数组,外部定义 * 输出 :接收结果, * 调用 :外部调用 */ u8 NRF_Rx_Dat(u8 *rxbuf) { u8 state; if( nrf_mode != RX_MODE) { NRF_RX_Mode(); } NRF_CE_HIGH(); //进入接收状态 /*等待接收中断*/ while(NRF_Read_IRQ()!=0); NRF_CE_LOW(); //进入待机状态 /*读取status寄存器的值 */ state=NRF_ReadReg(STATUS); /* 清除中断标志*/ NRF_WriteReg(NRF_WRITE_REG+STATUS,state); /*判断是否接收到数据*/ if(state & RX_DR) //接收到数据 { NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器 return RX_DR; } else { return ERROR; //没收到任何数据 } }
/** * @brief Set ACK payload for RX device * @note require NRF_ACK_PAY_ENABLE, NRF_DPL_ENABLE and enable DynamicPayload on a specific datapipe * @param Pointer to nRF24L01P_Object. * @retval STATUS register in nRF24L01P. */ uint8_t NRF_SetACKPayload(nRF24L01P_Object* nrf) { uint8_t bytecnt, status; if(nrf->MasterMode == NRF_MASTER_MODE_RX) { /* Reset CE pin to enable register write */ NRF_CE_LOW(nrf); /* Reset CS pin to initiate an SPI transmission */ NRF_CS_LOW(nrf); /* Send NRF_W_ACK_PAYLOAD command */ assert_param(nrf->ACKPayload.PayloadWidth <= NRF_MAX_PAYLOAD_WIDTH); status = NRF_SPI_SendByte(nrf, NRF_W_ACK_PAYLOAD); /* Send payload contents */ for(bytecnt = 0; bytecnt < nrf->ACKPayload.PayloadWidth; bytecnt++) { NRF_SPI_SendByte(nrf, nrf->ACKPayload.Payload[bytecnt]); } /* Set CS pin to complete transmission */ NRF_CS_HIGH(nrf); NRF_CE_HIGH(nrf); } return status; }
/* * 函数名:NRF_Tx_Dat * 描述 :用于向NRF的发送缓冲区中写入数据 * 输入 :txBuf:存储了将要发送的数据的数组,外部定义 * 输出 :发送结果,成功返回TXDS,失败返回MAXRT或ERROR * 调用 :外部调用 */ u8 NRF_Tx_Dat(u8 *txbuf) { u8 state; /*ce为低,进入待机模式1*/ NRF_CE_LOW(); /*写数据到TX BUF 最大 32个字节*/ SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); /*CE为高,txbuf非空,发送数据包 */ NRF_CE_HIGH(); /*等待发送完成中断 */ while(NRF_Read_IRQ()!=0); /*读取状态寄存器的值 */ state = SPI_NRF_ReadReg(STATUS); /*清除TX_DS或MAX_RT中断标志*/ SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state); SPI_NRF_WriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器 /*判断中断类型*/ if(state&MAX_RT) //达到最大重发次数 return MAX_RT; else if(state&TX_DS) //发送完成 return TX_DS; else return ERROR; //其他原因发送失败 }
/** * @brief Send a payload which does not require acknowledgement from RX device. * @note * @param Pointer to nRF24L01P_Object. * @retval STATUS register in nRF24L01P. */ uint8_t NRF_SendPayload_NOACK(nRF24L01P_Object* nrf) { uint8_t bytecnt, status; /* Reset CE pin to enable register write */ NRF_CE_LOW(nrf); /* Reset CS pin to initiate an SPI transmission */ NRF_CS_LOW(nrf); /* Send NRF_W_TX_PAYLOAD_NOACK command */ assert_param(nrf->PayloadToSend.PayloadWidth <= NRF_MAX_PAYLOAD_WIDTH); status = NRF_SPI_SendByte(nrf, NRF_W_TX_PAYLOAD_NOACK); /* Send payload contents */ for(bytecnt = 0; bytecnt < nrf->PayloadToSend.PayloadWidth; bytecnt++) { NRF_SPI_SendByte(nrf, nrf->PayloadToSend.Payload[bytecnt]); } /* Set CS pin to complete transmission */ NRF_CS_HIGH(nrf); /* Hold CE high for at least 10us to send payload */ NRF_CE_HIGH(nrf); return status; }
u8 NRF_ISR_Rx_Dat(u8 *rxbuf) { if( nrf_mode != RX_MODE) { NRF_RX_Mode(); } else { NRF_CE_HIGH(); //进入接收状态 } if(re_flag == QUEUE_EMPTY) //空,直接返回0 { return 0; } //复制数据 nrf_cpy(rxbuf,(u8 *)&(RX_ISR_FIFO[front]),MAX_ONCE_TX_NUM); NRF_CE_LOW(); //进入待机状态 front++; //由于非空,所以可以直接出队列 if(front >= RX_ISR_FIFO_PACKET) { front=0; //重头开始 } if(front == rear) //追到屁股了,接收队列空 { re_flag = QUEUE_EMPTY; // front=0; //重头开始(可以省掉) // rear=0; } NRF_CE_HIGH(); //进入接收模式 return RX_DR; }
void nrf_receive_stop (void) { if (mode != MODE_RECEIVE_POLL) return; NRF_CE_HIGH (); /* nrf_write_reg (R_STATUS, R_STATUS_RX_DR); */ // nrf_cmd (C_FLUSH_RX); mode = MODE_NOMODE; }
void nrf_receive_start (void) { if (mode != MODE_NOMODE) return (-1); /* nrf_write_reg (R_CONFIG, R_CONFIG_PRIM_RX | R_CONFIG_PWR_UP | R_CONFIG_EN_CRC); */ // nrf_cmd (C_FLUSH_RX); nrf_write_reg (R_STATUS, 0); NRF_CE_HIGH (); mode = MODE_RECEIVE_POLL; }
//中断发送函数,仅仅发送一次,就等待中断发送 void NRF_ISR_Tx_Dat_Once(void) { if(isr_L > 0) { /*ce为低,进入待机模式1*/ NRF_CE_LOW(); /*写数据到TX BUF 最大 32个字节*/ NRF_WriteBuf(WR_TX_PLOAD,(u8 *)isr_addr,MAX_ONCE_TX_NUM); /*CE为高,txbuf非空,发送数据包 */ NRF_CE_HIGH(); isr_L--; } }
/* * 函数名:NRF_Init * 描述 :SPI的 I/O配置 * 输入 :无 * 输出 :无 * 调用 :外部调用 */ void NRF_Init(void) { //配置NRF管脚复用 spi_init(NRF_SPI,MASTER); //初始化SPI,主机模式 gpio_init(PORTE,28, GPO,LOW); //初始化CE,默认进入待机模式 //gpio_init(PORTE,27, GPI,LOW); //初始化IRQ管脚为输入 gpio_init(PORTA,14, GPO,HIGH); //初始化PCSN管脚为输出,低电平选中 #if IS_USE_ISR exti_init(PORTE,27, falling_up); //初始化IRQ管脚为 :下降沿触发,内部上拉 #else gpio_init(PORTE,27, GPI,LOW); //初始化IRQ管脚为输入 #endif //配置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的有效数据宽度 //TX模式配置 //NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址 ,主要为了使能ACK NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x0F); //设置自动重发间隔时间:250us + 86us;最大自动重发次数:15次 #if IS_AUTO_RX_MODE NRF_RX_Mode(); //默认进入接收模式 #endif NRF_CE_HIGH(); while(NRF_Check() == 0); //检测无线模块是否插入:如果卡在这里,说明没检测到无线模块 }
/** * @brief Initializes the nRF24L01P according to the specified * parameters in the NRF_InitStructure. * @note * @param Pointer of NRF_InitTypeDef type. * @retval STATUS register in nRF24L01P. */ uint8_t NRF_Init(nRF24L01P_Object* nrf) { uint8_t status; NRF_LowLevel_Config(nrf); NRF_EXTI_Config(nrf); NRF_NVIC_Config(nrf); NRF_SPI_Config(nrf); status = NRF_Device_Config(nrf); if(nrf->MasterMode == NRF_MASTER_MODE_RX) { NRF_CE_HIGH(nrf); } return status; }
/*! * @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_TX_Mode * 描述 :配置发送模式 * 输入 :无 * 输出 :无 * 调用 :外部调用 */ void NRF_TX_Mode(void) { u32 i; NRF_CE_LOW(); 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(); i=0xffff; while(i--); //CE要拉高一段时间才进入发送模式 //DELAY_MS(1); nrf_mode = TX_MODE; }
/* * 函数名:NRF_RX_Mode * 描述 :配置并进入接收模式 * 输入 :无 * 输出 :无 * 调用 :外部调用 */ void NRF_RX_Mode(void) { NRF_CE_LOW(); SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址 SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址 SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通信频率 SPI_NRF_WriteReg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 /*CE拉高,进入接收模式*/ NRF_CE_HIGH(); }
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; } }
void nrf_send_frame (uint8_t * frame) { int ret; nrf_write_reg (R_CONFIG, R_CONFIG_PWR_UP | R_CONFIG_EN_CRC); for (ret = 0; ret < 32; ret++) { UART2PutHex (frame[ret]); UART2PutStr (" "); } UART2PutStr ("\n\r"); NRF_CS_LOW (); SPI2_xmit (C_W_TX_PAYLOAD); SPI2_transmit (frame, 32); NRF_CS_HIGH (); NRF_CE_HIGH (); while (1) { ret = nrf_read_reg (R_FIFO_STATUS); if ((ret & R_FIFO_STATUS_TX_EMPTY) == R_FIFO_STATUS_TX_EMPTY) break; } NRF_CE_LOW (); nrf_write_reg (R_STATUS, R_CONFIG_MASK_RX_DR | R_CONFIG_MASK_TX_DS | R_CONFIG_MASK_MAX_RT); ret = nrf_cmd_status (C_NOP); }
/* * 函数名:NRF_TX_Mode * 描述 :配置发送模式 * 输入 :无 * 输出 :无 * 调用 :外部调用 */ void NRF_TX_Mode(void) { NRF_CE_LOW(); SPI_NRF_WriteBuf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址 SPI_NRF_WriteBuf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK SPI_NRF_WriteReg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 SPI_NRF_WriteReg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 SPI_NRF_WriteReg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 SPI_NRF_WriteReg(NRF_WRITE_REG+RF_CH,CHANAL); //设置RF通道为CHANAL SPI_NRF_WriteReg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 SPI_NRF_WriteReg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,发射模式,开启所有中断 /*CE拉高,进入发送模式*/ NRF_CE_HIGH(); Delay(0xffff); //CE要拉高一段时间才进入发送模式 }
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"); } }