// Send data packet // input: // pBuf - buffer with data to send // return: // nRF24_MASK_MAX_RT - if transmit failed with maximum auto retransmit count // nRF24_MAX_TX_DS - if transmit succeed // contents of STATUS register otherwise uint8_t nRF24_TXPacket(uint8_t * pBuf, uint8_t TX_PAYLOAD) { uint8_t status; CE_L(); nRF24_WriteBuf(nRF24_CMD_WREG | nRF24_REG_TX_ADDR,nRF24_TX_addr,nRF24_TX_ADDR_WIDTH); // Set static TX address nRF24_WriteBuf(nRF24_CMD_WREG | nRF24_REG_RX_ADDR_P0,nRF24_RX_addr,nRF24_RX_ADDR_WIDTH); // Set static RX address for auto ack nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_EN_AA,0x01); // Enable auto acknowledgement for data pipe 0 nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_SETUP_RETR,0x1A); // Automatic retransmission: wait 500us, 10 retries nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RF_CH,0x6E); // Set frequency channel 110 (2.510MHz) nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RF_SETUP,0x07); // Setup: 1Mbps, 0dBm, LNA on nRF24_WriteBuf(nRF24_CMD_W_TX_PAYLOAD,pBuf,TX_PAYLOAD); // Write specified buffer to FIFO nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_CONFIG,0x0E); // Config: CRC on (2 bytes), Power UP, RX/TX ctl = PTX CE_H(); // CE pin high => Start transmit // Delay_us(10); // Must hold CE at least 10us //while(PB_IDR_bit.IDR2 != 0); // Wait for IRQ from nRF24L01 CE_L(); status = nRF24_ReadReg(nRF24_REG_STATUS); // Read status register nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_STATUS,status | 0x70); // Clear RX_DR, TX_DS, MAX_RT flags if (status & nRF24_MASK_MAX_RT) { // Auto retransmit counter exceeds the programmed maximum limit. FIFO is not removed. nRF24_RWReg(nRF24_CMD_FLUSH_TX,0xFF); // Flush TX FIFO buffer return nRF24_MASK_MAX_RT; }; if (status & nRF24_MASK_TX_DS) { // Transmit ok nRF24_RWReg(nRF24_CMD_FLUSH_TX,0xFF); // Flush TX FIFO buffer return nRF24_MASK_TX_DS; } // Some banana happens return status; }
void vNrfSend(uint8_t * addr, uint8_t *data, uint8_t len) { uint8_t status; while (g_uNrfTx) // this should be never executed code! { status = uNrfReadReg(STATUS); if (status & ( (1 << TX_DS) | (1 << MAX_RT) ) ) { uNrfWriteReg(STATUS, (1 << TX_DS) | (1 << MAX_RT)); g_uNrfTx=0; break; } } uNrfWriteBuf(TX_ADDR, addr, NRF_ADR_LEN); uNrfWriteBuf(RX_ADDR_P0, addr, NRF_ADR_LEN); CE_L(); vNrfPowerUpTx(); vNrfFlushTx(); uNrfWriteBuf(W_TX_PAYLOAD, data, len); CE_H(); // vTimerDelayUs(20); // CE_L(); }
u8 ANO_NRF::NRF_Tx_Dat(u8 *txbuf,u8 *AckPacket) { u8 state; /*ce为低,进入待机模式1*/ CE_L(); /*写数据到TX BUF 最大 32个字节*/ Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); /*CE为高,txbuf非空,发送数据包 */ CE_H(); /*等待发送完成中断 */ while(NRF_Read_IRQ()!=0); state = Read_Reg(NRFRegSTATUS);/*读取状态寄存器的值 */ Write_Reg(NRF_WRITE_REG+NRFRegSTATUS,state); if(state&RX_DR) { Read_Buf(RD_RX_PLOAD, AckPacket, 32); } Write_Reg(FLUSH_TX,NOP);//清除TX FIFO寄存器 return state; }
void ANO_NRF::TxPacket(uint8_t * tx_buf, uint8_t len) { CE_L(); //StandBy I模式 Write_Buf(NRF_WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址 Write_Buf(WR_TX_PLOAD, tx_buf, len); // 装载数据 CE_H(); //置高CE,激发数据发送 }
// Put nRF24 in Power Down mode void nRF24_PowerDown(void) { uint8_t conf; CE_L(); // CE pin to low conf = nRF24_ReadReg(nRF24_REG_CONFIG); conf &= ~(1<<1); // Clear PWR_UP bit nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_CONFIG,conf); // Go Power down mode }
// Put nRF24L01 in TX mode void nRF24_TXMode(void) { CE_L(); nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_EN_AA,0x01); // Enable ShockBurst for data pipe 0 nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_SETUP_RETR,0x1A); // Auto retransmit: wait 500us, 10 retries nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RF_CH,0x6E); // Set frequency channel 110 (2.510MHz) nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RF_SETUP,0x06); // Setup: 1Mbps, 0dBm, LNA off nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_CONFIG,0x0E); // Config: CRC on (2 bytes), Power UP, RX/TX ctl = PTX }
void vNrfPowerUpRx(void) { g_uNrfTx = 0; CE_L(); uNrfWriteReg(CONFIG, NRF_CONFIG | ((1<<PWR_UP) | (1<<PRIM_RX))); uNrfWriteReg(EN_RXADDR, (0<<ERX_P0) | (1<<ERX_P1)); CE_H(); uNrfWriteReg(STATUS, (1 << TX_DS) | (1 << MAX_RT)); // need delay!!! but inside interrupt!! }
// Put nRF24L01 in RX mode void nRF24_RXMode(uint8_t RX_PAYLOAD) { CE_L(); nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_EN_AA,0x01); // Enable ShockBurst for data pipe 0 nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_EN_RXADDR,0x01); // Enable data pipe 0 nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RF_CH,0x6E); // Set frequency channel 110 (2.510MHz) nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RX_PW_P0,RX_PAYLOAD); // Set RX payload length nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_RF_SETUP,0x06); // Setup: 1Mbps, 0dBm, LNA off nRF24_RWReg(nRF24_CMD_WREG | nRF24_REG_CONFIG,0x0F); // Config: CRC on (2 bytes), Power UP, RX/TX ctl = PRX nRF24_WriteBuf(nRF24_CMD_WREG | nRF24_REG_RX_ADDR_P0,nRF24_RX_addr,nRF24_RX_ADDR_WIDTH); // Set static RX address CE_H(); // Delay_us(10); // Hold CE high at least 10us }
// GPIO and SPI initialization void nRF24_init() { // IRQ --> PB2 // CE <-- PB3 // CSN <-- PB4 // SCK <-- PB5 // MOSI <-- PB6 // MISO --> PB7 // SCK,MOSI,CSN,CE pins set as output fiwth push-pull at 10MHz PB_DDR |= 0x78; // Set PB3..PB6 as output PB_CR1 |= 0x78; // Configure PB3..PB6 as output with push-pull PB_CR2 |= 0x78; // Set 10MHz output speed for PB3..PB6 pins //PB_CR2 &= ~(0x78); // Set 2MHz output speed for PB3..PB6 pins // MISO pin set as input with pull-up PB_DDR_bit.DDR7 = 0; // Set PB7 as input PB_CR1_bit.C17 = 1; // Configure PB7 as input with pull-up PB_CR2_bit.C27 = 0; // Disable external interrupt for PB7 // IRQ pin set as input with pull-up PB_DDR_bit.DDR2 = 0; // Set PB2 as input PB_CR1_bit.C12 = 1; // Configure PB2 as input with pull-up PB_CR2_bit.C22 = 0; // Disable external interrupt for PB2 // Configure SPI CLK_PCKENR1_bit.PCKEN14 = 1; // Enable SPI peripherial (PCKEN14) /* SPI1_CR1_bit.BR = 0; // Baud = f/2 (1MHz at 2MHz CPU) SPI1_CR1_bit.CPHA = 0; // CPHA = 1st edge SPI1_CR1_bit.CPOL = 0; // CPOL = low (SCK low when idle) SPI1_CR1_bit.LSBFIRST = 0; // first bit is MSB SPI1_CR1_bit.MSTR = 1; // Master configuration SPI1_CR1_bit.SPE = 0; // Peripherial enabled */ SPI1_CR1 = 0x04; // SPI: MSB first, Baud=f/2, Master, CPOL=low, CPHA=1st edge //SPI1_CR1 = 0x24; // SPI: MSB first, Baud=f/32, Master, CPOL=low, CPHA=1st edge /* SPI1_CR2_bit.BDM = 0; // 2-line unidirectional data mode SPI1_CR2_bit.BD0E = 0; // don't care when BDM set to 0 SPI1_CR2_bit.RXOnly = 0; // Full duplex SPI1_CR2_bit.SSI = 1; // Master mode SPI1_CR2_bit.SSM = 1; // Software slave management enabled */ SPI1_CR2 = 0x03; // SPI: 2-line mode, full duplex, SSM on (master mode) SPI1_CR1_bit.SPE = 1; // SPI peripherial enabled CSN_H(); CE_L(); // CE pin low -> power down mode at startup }
void RX_Mode(void) { CE_L(); NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址 NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF24L01_Write_Reg(WRITE_REG+RF_CH,40); //设置RF通信频率 NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 ? NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 CE_H(); //CE为高,进入接收模式 }
void TX_Mode(void) { CE_L(); NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址 NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 NRF24L01_Write_Reg(WRITE_REG+RF_CH,40); //设置RF通道为40 NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 ? NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 CE_H(); //CE为高,10us后启动发送 }
void ANO_NRF::Init(u8 model, u8 ch) { CE_L(); Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //写RX节点地址 Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址 Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a); //设置自动重发间隔时间:500us;最大自动重发次数:10次 2M波特率下 Write_Reg(NRF_WRITE_REG+RF_CH,ch); //设置RF通道为CHANAL Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 //Write_Reg(NRF_WRITE_REG+RF_SETUP,0x07); //设置TX发射参数,0db增益,1Mbps,低噪声增益开启 ///////////////////////////////////////////////////////// if(model==1) //RX { Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //选择通道0的有效数据宽度 Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收 } else if(model==2) //TX { Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //选择通道0的有效数据宽度 Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送 } else if(model==3) //RX2 { Write_Reg(FLUSH_TX,0xff); Write_Reg(FLUSH_RX,0xff); Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断开启,16位CRC,主接收 RW(0x50); RW(0x73); Write_Reg(NRF_WRITE_REG+0x1c,0x01); Write_Reg(NRF_WRITE_REG+0x1d,0x06); } else //TX2 { Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断开启,16位CRC,主发送 Write_Reg(FLUSH_TX,0xff); Write_Reg(FLUSH_RX,0xff); RW(0x50); RW(0x73); Write_Reg(NRF_WRITE_REG+0x1c,0x01); Write_Reg(NRF_WRITE_REG+0x1d,0x06); } CE_H(); delayms(50); }
void vNrfInit(uint8_t channel, uint8_t * rx_addr) { // memcpy(g_RxAddr, rx_addr, NRF_ADR_LEN); CE_L(); uNrfWriteBuf(RX_ADDR_P1, rx_addr, NRF_ADR_LEN); CE_H(); uNrfWriteReg(RF_CH, channel); // Select RF channel uNrfWriteReg(RX_PW_P0, 4); uNrfWriteReg(RX_PW_P1, 4); uNrfWriteReg(SETUP_RETR, 0x1F); // 15 retries // uNrfWriteReg(RF_SETUP, 0xF); // 2 mbps + max gain + LNA vNrfSetDynamicPayload(); vNrfPowerUpRx(); vNrfFlushRx(); }
void RX_Mode(void) { CE_L(); SPI2_writeBuf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); SPI2_writeReg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 SPI2_writeReg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 SPI2_writeReg(WRITE_REG + RF_CH, 40); // Select RF channel 40 SPI2_writeReg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); SPI2_writeReg(WRITE_REG + RF_SETUP, 0x07); SPI2_writeReg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 bytes) //& Prim:RX. RX_DR enabled.. CE_H(); // Set CE pin high to enable RX device // This device is now ready to receive one packet of 16 bytes payload from a TX device //sending to address // '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and //datarate = 2Mbps. }
u8 NRF24L01_TxPacket(u8 *txbuf) { u8 sta; CE_L(); NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF 32个字节 CE_H(); //启动发送 ? // while(GPIOC->IDR&1<<5); //等待发送完成 Delay(0xEFFFF); sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 ? NRF24L01_Write_Reg(WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志 if(sta&MAX_TX)//达到最大重发次数 { NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 return MAX_TX; } if(sta&TX_OK)//发送完成 { return TX_OK; } return 0xff;//其他原因发送失败 }
// GPIO and SPI initialization void nRF24_init() { #if _SPI_PORT == 1 // SPI1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA,ENABLE); #elif _SPI_PORT == 2 // SPI2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); #elif _SPI_PORT == 3 // SPI3 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // Disable JTAG for use PB3 #endif GPIO_InitTypeDef PORT; // Configure SPI pins PORT.GPIO_Speed = GPIO_Speed_50MHz; PORT.GPIO_Pin = SPI_SCK_PIN | SPI_MISO_PIN | SPI_MOSI_PIN; PORT.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(SPI_GPIO_PORT,&PORT); // Configure CS pin as output with Push-Pull PORT.GPIO_Pin = SPI_CS_PIN; PORT.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(SPI_GPIO_PORT,&PORT); // Configure CE pin as output with Push-Pull PORT.GPIO_Pin = nRF24_CE_PIN; PORT.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(nRF24_CE_PORT,&PORT); // Configure IRQ pin as input with Pull-Up PORT.GPIO_Pin = nRF24_IRQ_PIN; PORT.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(nRF24_IRQ_PORT,&PORT); nRF24_SPI_Init(SPI_BaudRatePrescaler_2); // Which SPI speed do we need? SPI_Cmd(SPI_PORT,ENABLE); CSN_H(); CE_L(); }
void vNrfHwInit(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = NRF_CE_PIN | NRF_CS_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // configure interrupt pin GPIO_InitStructure.GPIO_Pin = NRF_INT_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // pull-up, default is 1 GPIO_Init(NRF_GPIO, &GPIO_InitStructure); vSpiInit(); SPI1_H(); CE_L(); // add int exti handler vExtiAddCb(GPIO_PortSourceGPIOB, GPIO_PinSource0, vNrfCbState); }
// GPIO and SPI initialization void nRF24_init() { // GND --> PB1 // IRQ --> NC(?!) // CE <-- PB2 // CSN <-- PC4 // SCK <-- PC5 // MOSI <-- PC6 // MISO --> PC7 // SCK,MOSI,CSN,CE pins set as output fiwth push-pull at 10MHz // Set PB1, PB2 as output // CE, GND GPIOB->DDR |= 0x06; GPIOB->CR1 |= 0x06; GPIOB->CR2 |= 0x06; GPIOB->ODR &= ~(0x2); // GND // Set PC4..PC6 as output // MOSI, SCK, CSN GPIOC->DDR |= 0x70; GPIOC->CR1 |= 0x70; GPIOC->CR2 |= 0x70; // MISO pin set as input with pull-up // Set PC7 as input GPIOC->DDR &= ~0x80; // Configure PC7 as input with pull-up GPIOC->CR1 |= 0x80; // Disable external interrupt for PC7 GPIOC->CR2 &= ~0x80; // IRQ pin set as input with pull-up // Set PC1 as input GPIOB->DDR &= ~0x02; // Configure PC1 as input with pull-up GPIOB->CR1 |= 0x02; // Disable external interrupt for PC1 GPIOB->CR2 &= ~0x02; // Configure SPI /*CLK_PCKENR1_bit.PCKEN14 = 1; // Enable SPI peripherial (PCKEN14)*/ // Enable SPI (PCKEN11) CLK->PCKENR1 |= 0x02; /* SPI_CR1_bit.BR = 0; // Baud = f/2 (1MHz at 2MHz CPU) SPI_CR1_bit.CPHA = 0; // CPHA = 1st edge SPI_CR1_bit.CPOL = 0; // CPOL = low (SCK low when idle) SPI_CR1_bit.LSBFIRST = 0; // first bit is MSB SPI_CR1_bit.MSTR = 1; // Master configuration SPI_CR1_bit.SPE = 0; // Peripherial enabled */ SPI->CR1 = 0x04; // SPI: MSB first, Baud=f/2, Master, CPOL=low, CPHA=1st edge //SPI_CR1 = 0x24; // SPI: MSB first, Baud=f/32, Master, CPOL=low, CPHA=1st edge /* SPI_CR2_bit.BDM = 0; // 2-line unidirectional data mode SPI_CR2_bit.BD0E = 0; // don't care when BDM set to 0 SPI_CR2_bit.RXOnly = 0; // Full duplex SPI_CR2_bit.SSI = 1; // Master mode SPI_CR2_bit.SSM = 1; // Software slave management enabled */ SPI->CR2 = 0x03; // SPI: 2-line mode, full duplex, SSM on (master mode) /*SPI_CR1_bit.SPE = 1; // SPI peripherial enabled*/ SPI->CR1 |= 0x40; CSN_H(); CE_L(); // CE pin low -> power down mode at startup }
void NRF24L01_Init(void) { CE_L(); //使能24L01 CSN_H(); //SPI片选取消 }
void ANO_NRF::TxPacket_AP(uint8_t * tx_buf, uint8_t len) { CE_L(); //StandBy I模式 Write_Buf(0xa8, tx_buf, len); // 装载数据 CE_H(); //置高CE }
void nRF24L01_Enable(void) { CE_L(); // chip enable SPI2_releaseChip(); // Spi disable //SCK=0; // Spi clock line init high }