void NRF24L01_INIT(void) { //这部分已经在SPI中初始化了 // GPIO_InitTypeDef GPIO_InitStructure; // RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // //24L01的IO初始化 // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; // // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; // GPIO_Init(GPIOA, &GPIO_InitStructure); // // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // GPIO_Init(GPIOA, &GPIO_InitStructure); SPI_CE_L(); //StandBy I模式 SPI_CE_L(); NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址 NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址 NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址 NRF_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通道为CHANAL NRF_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x26); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送 SPI_CE_H(); }
/* ***************************************************************** * 写数据包 ***************************************************************** */ void NRF_TxPacket(uint8_t * tx_buf, uint8_t len) { SPI_CE_L(); //StandBy I模式 NRF_Write_Buf(NRF_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址 NRF_Write_Buf(WR_TX_PLOAD, tx_buf, len); // 装载数据 SPI_CE_H(); //置高CE,激发数据发送 }
/* 24L01初始化 model:24L01 模式 ch: 通道 */ void Nrf24l01_Init(u8 model, u8 ch) { #ifdef NRF24L01_SPI1 Nrf_Spi1_Init(); #elif defined NRF24L01_SPI2 Nrf_Spi2_Init(); #elif defined NRF24L01_SPI0 Nrf_Spi0_Init(); #else #error #endif SPI_CE_L(); NRF_Write_Buf(NRF_WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);//写RX节点地址 NRF_Write_Buf(NRF_WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); //写TX节点地址 NRF_Write_Reg(NRF_WRITE_REG + EN_AA, 0x01); //使能通道0的自动应答 NRF_Write_Reg(NRF_WRITE_REG + EN_RXADDR, 0x01); //使能通道0的接收地址 NRF_Write_Reg(NRF_WRITE_REG + SETUP_RETR, 0x1a); //设置自动重发间隔时间:500us;最大自动重发次数:10次 NRF_Write_Reg(NRF_WRITE_REG + RF_CH, ch); //设置RF通道为CHANAL NRF_Write_Reg(NRF_WRITE_REG + RF_SETUP, 0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 //NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x07); //设置TX发射参数,0db增益,1Mbps,低噪声增益开启 ///////////////////////////////////////////////////////// if (model == 1) //RX { NRF_Write_Reg(NRF_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //选择通道0的有效数据宽度 NRF_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收 } else if (model == 2) //TX { NRF_Write_Reg(NRF_WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //选择通道0的有效数据宽度 NRF_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送 } else if (model == 3) //RX2 { NRF_Write_Reg(FLUSH_TX, 0xff); NRF_Write_Reg(FLUSH_RX, 0xff); NRF_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收 Spi_RW(0x50); Spi_RW(0x73); NRF_Write_Reg(NRF_WRITE_REG + 0x1c, 0x01); NRF_Write_Reg(NRF_WRITE_REG + 0x1d, 0x07); } else if (model == 4) //TX2 { NRF_Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送 NRF_Write_Reg(FLUSH_TX, 0xff); NRF_Write_Reg(FLUSH_RX, 0xff); Spi_RW(0x50); Spi_RW(0x73); NRF_Write_Reg(NRF_WRITE_REG + 0x1c, 0x01); NRF_Write_Reg(NRF_WRITE_REG + 0x1d, 0x07); } SPI_CE_H(); }
//发送模式 void SetTX_Mode(void) { SPI_CE_L(); NRF_Write_Reg(FLUSH_TX,0xff); //清除TX FIFO寄存器 NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址 NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通道为40 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 SPI_CE_H(); }
u8 xNRF_TxPacket(void *txbuf,u8 len,void *rxbuf,u8* rxlen) // { u8 sta; NRF_Write_Buf(WR_TX_PLOAD,txbuf,len);//写数据到TX FIFO NRF_CE=1; //启动发送 while(NRF_IRQ == 1); //等待发送完成 sta=NRF_Read_Reg(STATUS); //读取状态寄存器的值 NRF_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除 TX_DS或MAX_RT 中断标志 if(sta&MAX_TX) //达到最大重发次数 { NRF_Write_Reg(FLUSH_TX,0xff);//清除 TX FIFO 寄存器 return MAX_TX; } if(sta&RX_OK) //收到应答数据包 { *rxlen = NRF_Read_Reg(R_RX_PL_WID); NRF_Read_Buf(RD_RX_PLOAD,rxbuf,*rxlen);//读取数据 NRF_Write_Reg(FLUSH_RX,0xff);//清除 RX FIFO 寄存器 ??? return RX_OK; } if(sta&TX_OK)//发送完成 { return TX_OK; } return 0;//其他原因发送失败 }
u8 NRF_Check(void) { u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; u8 i; // SPI_SetSpeed(NRF_SPI,SPI_BaudRatePrescaler_8); //spi 速度为 9Mhz NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入 5 个字节的地址. NRF_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 for(i=0;i<5;i++)if(buf[i]!=0XA5)break; if(i!=5)return 1; //检测 24L01 错误 return 0; //检测到 24L01 }
//NRF2401+ 设置动态数据宽度,带数据包应答, void xNRF_RX_Mode(void* txbuf,u8 len) { NRF_CE=0; NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写入接收地址 /*建立自动重发*/ NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道 0 的自动应答 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道 0 的接收地址 NRF_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1F);//设置自动重发参数:自动重发延时 500+86us,重发上限15次 NRF_Write_Reg(NRF_WRITE_REG+FEATURE,0x06); //使能动态数据宽度和带数据包应答 NRF_Write_Reg(NRF_WRITE_REG+DYNPD,0x01); //使能通道1的动态数据宽度(带数据包应答的功能所必须) NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置 RF 通信频率 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置 TX 发射参数:0db增益,2Mbps,低噪声增益开启 NRF_Write_Reg(NRF_WRITE_REG+NRF_CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 NRF_Write_Reg(FLUSH_RX,0xff); NRF_Write_Reg(FLUSH_TX,0xff); //清空FIFO NRF_Write_Buf(W_ACK_PAYLOAD,txbuf,len); //写入应答时携带的数据包 NRF_CE = 1; //CE 为高,进入接收模式 }
/* ***************************************************************** * 检测NRF是否正常,向nRF的写寄存器写入buf,然后读出来,如果nRF不正常,则无法读出或者读出数据不正确。 ***************************************************************** */ u8 NRF_CHECK(void) { u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; u8 i; NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5); buf[0] = 0; NRF_Read_Buf(TX_ADDR,buf,5); for(i=0;i<5;i++)if(buf[i]!=0XA5)break; if(i!=5)return 0; return 1; }
void xNRF_TX_Mode() { NRF_CE=0; NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH); //发送地址 /*建立自动应答*/ NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置 TX 节点地址,主要为了使能 ACK NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道 0 的自动应答 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1F);//设置自动重发参数:自动重发延时 500+86us,重发上限15次 NRF_Write_Reg(NRF_WRITE_REG+FEATURE,0x06); //使能动态数据宽度和带数据包应答 NRF_Write_Reg(NRF_WRITE_REG+DYNPD,0x01); //使能通道1的动态数据宽度(带数据包应答的功能所必须) NRF_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10 次 NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置 RF 通道为 40 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置 TX 发射参数,0db增益,2Mbps,低噪声增益开启 NRF_Write_Reg(NRF_WRITE_REG+NRF_CONFIG,0x0e); //配置基本工作模式的参数;上电,,EN_CRC,16BIT_CRC,发送模式,开启所有中断 NRF_Write_Reg(FLUSH_TX,0xff); NRF_Write_Reg(FLUSH_TX,0xff); NRF_CE=1;//CE 为高,10us 后启动发送 }
//接收函数 u8 NRF24L01_RxPacket(u8 *rxbuf) { u8 sta; //SPI2_SetSpeed(SPI_SPEED_4); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) sta=NRF_Read_Reg(NRFRegSTATUS); //读取状态寄存器的值 NRF_Write_Reg(NRF_WRITE_REG+NRFRegSTATUS,sta); //清除TX_DS或MAX_RT中断标志 if(sta&RX_OK)//接收到数据 { NRF_Write_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//没收到任何数据 }
//接收模式 void SetRX_Mode(void) { SPI_CE_L(); NRF_Write_Reg(FLUSH_RX,0xff);//清除TX FIFO寄存器 NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(uint8_t*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址 NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址 NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通信频率 NRF_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);//配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 SPI_CE_H(); printf("NRF24L01设为接收模式...\r\n"); }
//接受数据时放入新数据包 u8 xNRF_RxPacket(void *rxbuf,u8* rxlen,void *txbuf,u8 txlen) { u8 sta; sta=NRF_Read_Reg(STATUS); //读取状态寄存器的值 NRF_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除 TX_DS 或MAX_RT 中断标志 if(sta&RX_OK)//接收到数据 { *rxlen = NRF_Read_Reg(R_RX_PL_WID); NRF_Read_Buf(RD_RX_PLOAD,rxbuf,*rxlen);//读取数据 NRF_Write_Reg(FLUSH_RX,0xff);//清除 RX FIFO 寄存器 NRF_Write_Buf(W_ACK_PAYLOAD,txbuf,txlen); //写入应答时携带的数据包 return 0; } return 1;//没收到任何数据 }
void NRF_RX_Mode(void) { // u8 sta; NRF_CE=0; NRF_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); NRF_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道 0 的自动应答 NRF_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);//使能通道 0 的接收地址 NRF_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置 RF 通信频率 NRF_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0 的有效数据宽度 NRF_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);//设置 TX 发射参数,0db 增益,2Mbps,低噪声增益开启 NRF_Write_Reg(NRF_WRITE_REG+NRF_CONFIG, 0x0f); //配置基本工作模式的参 //数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 NRF_Write_Reg(FLUSH_RX,0xff); NRF_CE = 1; //CE 为高,进入接收模式 }
uint8_t NRF_Check(void) { uint8_t buf1[5]; uint8_t i; /*写入5个字节的地址. */ NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,5); /*读出写入的地址 */ NRF_Read_Buf(TX_ADDR,buf1,5); /*比较*/ for(i=0;i<5;i++) { if(buf1[i]!=TX_ADDRESS[i]) break; } if(i==5) return 1; //MCU与NRF成功连接 else return 0; //MCU与NRF不正常连接 }
u8 Nrf24l01_Check(void) { u8 buf1[5]; u8 i; /*写入5个字节的地址. */ NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,5); /*读出写入的地址 */ NRF_Read_Buf(TX_ADDR,buf1,5); /*比较*/ for(i=0;i<5;i++) { if(buf1[i]!=TX_ADDRESS[i]) break; } if(i==5) return SUCCESS ; //MCU与NRF成功连接 else return ERROR ; //MCU与NRF不正常连接 }
u8 NRF_TxPacket(void *txbuf) { u8 sta; NRF_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32 个字节 while(NRF_IRQ == 1); //等待发送完成 sta=NRF_Read_Reg(STATUS); //读取状态寄存器的值 NRF_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除 TX_DS 或MAX_RT 中断标志 if(sta&TX_OK)//发送完成 { return TX_OK; } if(sta&MAX_TX) //达到最大重发次数 { NRF_Write_Reg(FLUSH_TX,0xff);//清除 TX FIFO 寄存器 return MAX_TX; } return 0xff;//其他原因发送失败 }
//判断SPI接口是否接入NRF芯片是否可用 u8 NRF24L01_Check(void) { u8 buf[5]={0xC2,0xC2,0xC2,0xC2,0xC2}; u8 buf1[5]; u8 i=0; /*写入5 个字节的地址. */ NRF_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5); /*读出写入的地址 */ NRF_Read_Buf(TX_ADDR,buf1,5); /*比较*/ for (i=0;i<5;i++) { if (buf1[i]!=0xC2) break; } if (i==5) {printf("初始化NRF24L01成功...\r\n");return 1 ;} //MCU 与NRF 成功连接 else {printf("初始化NRF24L01出错...\r\n");return 0 ;} //MCU与NRF不正常连接 }
/****************************************************************** * 写数据包 ******************************************************************/ void NRF_TxPacket(uint8_t * tx_buf, uint8_t len) { SPI_CE_L(); //StandBy I模式 NRF_Write_Buf(WR_TX_PLOAD, tx_buf, len); // 装载数据 SPI_CE_H(); //置高CE,激发数据发送 }
void NRF_TxPacket_AP(uint8_t * tx_buf, uint8_t len) { SPI_CE_L(); //StandBy I模式 NRF_Write_Buf(0xa8, tx_buf, len); // 装载数据 SPI_CE_H(); //置高CE }
//===================================================================================== void xNRF_ACKPacket(void* txbuf,u8 len) { NRF_Write_Buf(W_ACK_PAYLOAD,txbuf,len); }