/******************************************************************************/ /* -- 深圳安信可科技有限公司 -- */ /* // 文件名: // 说明: // 编写人员: // 编写日期: // 程序维护: // 维护记录: // // */ // 免责声明:该程序仅用于学习与交流 // (c) Anxinke Corporation. All rights reserved. /******************************************************************************/ //#include "typedef.h" #include #include #include "NRF_24L01.h" //#include "UART.H" #include "delay.h" #define uchar unsigned char uchar const TX_ADDRESS[TX_ADR_WIDTH] = {0x34, 0x43, 0x10, 0x10, 0x01}; // Define a static TX address idata uchar rx_buf[TX_PLOAD_WIDTH]; idata uchar tx_buf[TX_PLOAD_WIDTH]; uchar flag; /**************************************************/ //sbit LED1= P3^7; /**************************************************/ unsigned char bdata sta; sbit RX_DR = sta ^ 6; sbit TX_DS = sta ^ 5; sbit MAX_RT = sta ^ 4; /**************************************************/ /************************************************** Function: init_io(); Description: flash led one time,chip enable(ready to TX or RX Mode), Spi disable,Spi clock line init high /**************************************************/ #define KEY 0xaa void init_nrf24l01_io ( void ) { CE = 0; // chip enable CSN = 1; // Spi disable SCK = 0; // Spi clock line init high } /************************************************** Function: SPI_RW(); Description: Writes one byte to nRF24L01, and return the byte read from nRF24L01 during write, according to SPI protocol /**************************************************/ bdata unsigned char st = 0; sbit st_1 = st ^ 0; sbit st_2 = st ^ 1; sbit st_3 = st ^ 2; sbit st_4 = st ^ 3; sbit st_5 = st ^ 4; sbit st_6 = st ^ 5; sbit st_7 = st ^ 6; sbit st_8 = st ^ 7; bdata unsigned char st1 = 0; sbit st_11 = st1 ^ 0; sbit st_12 = st1 ^ 1; sbit st_13 = st1 ^ 2; sbit st_14 = st1 ^ 3; sbit st_15 = st1 ^ 4; sbit st_16 = st1 ^ 5; sbit st_17 = st1 ^ 6; sbit st_18 = st1 ^ 7; /* uchar SPI_RW(uchar byte) { uchar bit_ctr; for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit { MOSI = (byte & 0x80); // output 'byte', MSB to MOSI byte = (byte << 1); // shift next bit into MSB.. SCK = 1; // Set SCK high.. MISO=1; byte |= MISO; // capture current MISO bit SCK = 0; // ..then set SCK low again } return(byte); // return read byte } */ uchar SPI_RW ( uchar byte ) { //uchar bit_ctr; st = byte; MOSI = st_8; SCK = 1; st_18 = MISO; SCK = 0; MOSI = st_7; SCK = 1; st_17 = MISO; SCK = 0; MOSI = st_6; SCK = 1; st_16 = MISO; SCK = 0; MOSI = st_5; SCK = 1; st_15 = MISO; SCK = 0; MOSI = st_4; SCK = 1; st_14 = MISO; SCK = 0; MOSI = st_3; SCK = 1; st_13 = MISO; SCK = 0; MOSI = st_2; SCK = 1; st_12 = MISO; SCK = 0; MOSI = st_1; SCK = 1; st_11 = MISO; SCK = 0; return ( st1 ); // return read byte } /**************************************************/ /************************************************** Function: SPI_RW_Reg(); Description: Writes value 'value' to register 'reg' /**************************************************/ uchar SPI_RW_Reg ( BYTE reg, BYTE value ) { uchar status; CSN = 0; // CSN low, init SPI transaction status = SPI_RW ( reg ); // select register SPI_RW ( value ); // ..and write value to it.. CSN = 1; // CSN high again return ( status ); // return nRF24L01 status byte } /**************************************************/ /************************************************** Function: SPI_Read(); Description: Read one byte from nRF24L01 register, 'reg' /**************************************************/ BYTE SPI_Read ( BYTE reg ) { BYTE reg_val; CSN = 0; // CSN low, initialize SPI communication... SPI_RW ( reg ); // Select register to read from.. reg_val = SPI_RW ( 0 ); // ..then read registervalue CSN = 1; // CSN high, terminate SPI communication return ( reg_val ); // return register value } /**************************************************/ /************************************************** Function: SPI_Read_Buf(); Description: Reads 'bytes' #of bytes from register 'reg' Typically used to read RX payload, Rx/Tx address /**************************************************/ uchar SPI_Read_Buf ( BYTE reg, BYTE *pBuf, BYTE bytes ) { uchar status, byte_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW ( reg ); // Select register to write to and read status byte for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ ) pBuf[byte_ctr] = SPI_RW ( 0 ); // Perform SPI_RW to read byte from nRF24L01 CSN = 1; // Set CSN high again return ( status ); // return nRF24L01 status byte } /**************************************************/ /************************************************** Function: SPI_Write_Buf(); Description: Writes contents of buffer '*pBuf' to nRF24L01 Typically used to write TX payload, Rx/Tx address /**************************************************/ uchar SPI_Write_Buf ( BYTE reg, BYTE *pBuf, BYTE bytes ) { uchar status, byte_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW ( reg ); // Select register to write to and read status byte for ( byte_ctr = 0; byte_ctr < bytes; byte_ctr++ ) // then write all byte in buffer(*pBuf) SPI_RW ( *pBuf++ ); CSN = 1; // Set CSN high again return ( status ); // return nRF24L01 status byte } /**************************************************/ /************************************************** Function: RX_Mode(); Description: This function initializes one nRF24L01 device to RX Mode, set RX address, writes RX payload width, select RF channel, datarate & LNA HCURR. After init, CE is toggled high, which means that this device is now ready to receive a datapacket. /**************************************************/ void power_off() { CE = 0; SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0D ); CE = 1; Timer3_Delay10us ( 2 ); } void ifnnrf_rx_mode ( void ) { power_off(); CE = 0; SPI_Write_Buf ( WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH ); // Use the same address on the RX device as the TX device SPI_RW_Reg ( WRITE_REG + EN_AA, 0x01 ); // Enable Auto.Ack:Pipe0 SPI_RW_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); // Enable Pipe0 SPI_RW_Reg ( WRITE_REG + RF_CH, 40 ); // Select RF channel 40 SPI_RW_Reg ( WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH ); // Select same RX payload width as TX Payload width SPI_RW_Reg ( WRITE_REG + RF_SETUP, 0x27 ); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0f ); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled.. CE = 1; // 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. } /**************************************************/ /************************************************** Function: TX_Mode(); Description: This function initializes one nRF24L01 device to TX mode, set TX address, set RX address for auto.ack, fill TX payload, select RF channel, datarate & TX pwr. PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX. ToDo: One high pulse(>10us) on CE will now send this packet and expext an acknowledgment from the RX device. /**************************************************/ void ifnnrf_tx_mode ( void ) { power_off(); CE = 0; SPI_Write_Buf ( WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH ); // Writes TX_Address to nRF24L01 SPI_Write_Buf ( WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH ); // RX_Addr0 same as TX_Adr for Auto.Ack SPI_Write_Buf ( WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH ); // Writes data to TX payload SPI_RW_Reg ( WRITE_REG + EN_AA, 0x01 ); // Enable Auto.Ack:Pipe0 SPI_RW_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); // Enable Pipe0 SPI_RW_Reg ( WRITE_REG + SETUP_RETR, 0x1a ); // 500us + 86us, 10 retrans... SPI_RW_Reg ( WRITE_REG + RF_CH, 40 ); // Select RF channel 40 SPI_RW_Reg ( WRITE_REG + RF_SETUP, 0x27 ); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0e ); // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled.. CE = 1; } void SPI_CLR_Reg ( BYTE R_T ) { CSN = 0; if ( R_T == 1 ) // CSN low, init SPI transaction SPI_RW ( FLUSH_TX ); // ..and write value to it.. else SPI_RW ( FLUSH_RX ); // ..and write value to it.. CSN = 1; // CSN high again } void ifnnrf_CLERN_ALL() { SPI_CLR_Reg ( 0 ); SPI_CLR_Reg ( 1 ); SPI_RW_Reg ( WRITE_REG + STATUS, 0xff ); IRQ = 1; } /*测试*/ bool nrf24l01_send ( BYTE *pBuf, BYTE bytes ) { BYTE time = 100; // IRQ = 1; //中断=1 SPI_RW_Reg ( WRITE_REG + STATUS, 0xff ); //清写寄存器 //发送 memcpy ( tx_buf, pBuf, bytes < TX_PLOAD_WIDTH ? bytes : TX_PLOAD_WIDTH ); ifnnrf_tx_mode(); //返回状态 while ( IRQ && time>0 ){time--;} sta = SPI_Read ( STATUS ); //读取状态 SPI_RW_Reg ( WRITE_REG + STATUS, 0xff ); //清写寄存器 if ( ! ( sta & STA_MARK_TX ) ) //发送成功 { ifnnrf_CLERN_ALL(); return 0; } //切换接收模式 ifnnrf_rx_mode(); IRQ = 1; return 1; } BYTE nrf24l01_recv ( BYTE *pBuf ) { BYTE time = 100; // if ( IRQ == 0 ) //中断信号 { sta = SPI_Read ( STATUS ); SPI_RW_Reg ( WRITE_REG + STATUS, 0xff ); //清写寄存器 if ( sta & STA_MARK_RX ) //接收成功 { SPI_Read_Buf ( RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH ); //处理rx_buf //清理rx_buf memset ( rx_buf, 0, TX_PLOAD_WIDTH ); } else { ifnnrf_CLERN_ALL(); ifnnrf_rx_mode(); while ( IRQ == 0 && time>0 ){time--;} } } } void if_main ( void ) { Timer3_Delay100ms ( 1 ); init_nrf24l01_io(); ifnnrf_rx_mode(); }