#ifndef __NRF24L01_H #define __NRF24L01_H //#include #include //#include "typedef.h" #include "Common.h" #include "Delay.h" typedef unsigned char uchar; //typedef unsigned char uint8; typedef unsigned char u8; typedef unsigned int uint; //typedef unsigned int uint16; typedef unsigned int u16; /****************************************NRF24L01端口定义***************************************/ #if 0 sbit CE = P2 ^ 3; sbit CSN = P2 ^ 4; sbit SCK = P2 ^ 5; sbit MOSI = P2 ^ 6; sbit MISO = P2 ^ 7; sbit IRQ = P3 ^ 3; //外部中断1 #else #define CE P11 #define CSN P15 #define SCK P10 #define MOSI P00 #define MISO P01 #define IRQ P03 #endif /*********************************************NRF24L01*************************************/ #define TX_ADR_WIDTH 5 // 接收地址宽度,一般设置为 5 不要动它 #define RX_ADR_WIDTH 5 // 接收地址宽度,一般设置为 5 不要动它 #define TX_PLOAD_WIDTH 32 //接收数据的 数据宽度(最大为 32 字节),这里我设置为最小的 1 字节,方便调试 #define RX_PLOAD_WIDTH 32 //发送数据的 数据宽度(最大为 32 字节),这里我设置为最小的 1 字节,方便调试 //uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x35,0x43,0x10,0x10,0x03}; // 这里就是设置了 5 个字节的 本地地址 const u8 TX_ADDRESS[RX_ADR_WIDTH] = {0x34, 0x43, 0x10, 0x10, 0x01}; //发送地址 /* 此处的地址:在IC内部真实地址是 反过来的。即:address = 0310104334 在数据发送时,发送到对方去的数据包括:数据本身+本地地址。与接收地址无关。 */ uchar const RX_ADDRESS[RX_ADR_WIDTH] = {0xEF, 0xEF, 0xEF, 0xEF, 0xEF}; //接收地址 /* 是指接受来自于发送方的地址(指发送方的本地地址),但在自动模式下,得到的应答信息中,包含的不是返回应答信息的对方的(本地地址) 而是 由 发送方(也就是发送原信息的机子一方) 的本地地址 */ // //***************************************NRF24L01寄存器指令******************************************************* #define READ_REG 0x00 // 读寄存器指令 #define WRITE_REG 0x20 // 写寄存器指令 #define RD_RX_PLOAD 0x61 // 读取接收数据指令 #define WR_TX_PLOAD 0xA0 // 写待发数据指令 #define FLUSH_TX 0xE1 // 冲洗发送 FIFO指令 #define FLUSH_RX 0xE2 // 冲洗接收 FIFO指令 #define REUSE_TX_PL 0xE3 // 定义重复装载数据指令 #define NOP 0xFF // 保留 //*************************************SPI(nRF24L01)寄存器地址**************************************************** #define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式 #define EN_AA 0x01 // 自动应答功能设置 #define EN_RXADDR 0x02 // 可用信道设置 #define SETUP_AW 0x03 // 收发地址宽度设置 #define SETUP_RETR 0x04 // 自动重发功能设置 #define RF_CH 0x05 // 工作频率设置 #define RF_SETUP 0x06 // 发射速率、功耗功能设置 #define STATUS 0x07 // 状态寄存器 #define OBSERVE_TX 0x08 // 发送监测功能 #define CD 0x09 // 地址检测 #define RX_ADDR_P0 0x0A // 频道0接收数据地址 #define RX_ADDR_P1 0x0B // 频道1接收数据地址 #define RX_ADDR_P2 0x0C // 频道2接收数据地址 #define RX_ADDR_P3 0x0D // 频道3接收数据地址 #define RX_ADDR_P4 0x0E // 频道4接收数据地址 #define RX_ADDR_P5 0x0F // 频道5接收数据地址 #define TX_ADDR 0x10 // 发送地址寄存器 #define RX_PW_P0 0x11 // 接收频道0接收数据长度 #define RX_PW_P1 0x12 // 接收频道0接收数据长度 #define RX_PW_P2 0x13 // 接收频道0接收数据长度 #define RX_PW_P3 0x14 // 接收频道0接收数据长度 #define RX_PW_P4 0x15 // 接收频道0接收数据长度 #define RX_PW_P5 0x16 // 接收频道0接收数据长度 #define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置 //************************************************************************************** //void Delay(unsigned int s); void inerDelay_us ( unsigned char n ); void init_NRF24L01 ( void ); uint SPI_RW ( uint uchar ); uchar SPI_Read ( uchar reg ); void SetRX_Mode ( void ); uint SPI_RW_Reg ( uchar reg, uchar value ); uint SPI_Read_Buf ( uchar reg, uchar *pBuf, uchar uchars ); uint SPI_Write_Buf ( uchar reg, uchar *pBuf, uchar uchars ); uchar nRF24L01_RxPacket ( unsigned char* rx_buf ); void nRF24L01_TxPacket ( unsigned char * tx_buf ); //****************************************************************************************** uchar bdata sta; //状态标志 sbit RX_DR = sta ^ 6; sbit TX_DS = sta ^ 5; sbit MAX_RT = sta ^ 4; /****************************************************************************************** /*延时函数 /******************************************************************************************/ void inerDelay_us ( unsigned char n ) { for ( ; n > 0; n-- ) _nop_(); } //**************************************************************************************** /*NRF24L01初始化 //***************************************************************************************/ void init_NRF24L01 ( void ) { inerDelay_us ( 100 ); CE = 0; CSN = 1; SCK = 0; SPI_Write_Buf ( WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH ); // 写本地地址 SPI_Write_Buf ( WRITE_REG + RX_ADDR_P0, TX_ADDRESS, RX_ADR_WIDTH ); // 写接收端地址 SPI_RW_Reg ( WRITE_REG + EN_AA, 0x01 ); // 频道0自动 ACK应答允许 SPI_RW_Reg ( WRITE_REG + EN_RXADDR, 0x01 ); // 允许接收地址只有频道0 SPI_RW_Reg ( WRITE_REG + SETUP_RETR, 0x1a ); //设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 SPI_RW_Reg ( WRITE_REG + RF_CH, 40 ); // SPI_RW_Reg ( WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH ); //设置接收数据长度,本次设置为32字节 SPI_RW_Reg ( WRITE_REG + RF_SETUP, 0x0f ); //设置发射速率为1MHZ,发射功率为最大值0dB CE = 1; // 网上很多地方 这里的 CE=1 都没有设置,不过也能正常工作。 } /**************************************************************************************************** /*函数:uint SPI_RW(uint uchar) /*功能:NRF24L01的SPI写时序 /****************************************************************************************************/ uint SPI_RW ( uint uchar ) { uint bit_ctr; for ( bit_ctr = 0; bit_ctr < 8; bit_ctr++ ) { MOSI = ( uchar & 0x80 ); uchar = ( uchar << 1 ); SCK = 1; uchar |= MISO; SCK = 0; } return ( uchar ); } /**************************************************************************************************** /*函数:uchar SPI_Read(uchar reg) /*功能:NRF24L01的SPI时序 /****************************************************************************************************/ uchar SPI_Read ( uchar reg ) { uchar reg_val; CSN = 0; SPI_RW ( reg ); reg_val = SPI_RW ( 0 ); CSN = 1; return ( reg_val ); } /****************************************************************************************************/ /*功能:NRF24L01读写寄存器函数 /****************************************************************************************************/ uint SPI_RW_Reg ( uchar reg, uchar value ) { uint status; CSN = 0; status = SPI_RW ( reg ); SPI_RW ( value ); CSN = 1; return ( status ); } /****************************************************************************************************/ /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数 /****************************************************************************************************/ uint SPI_Read_Buf ( uchar reg, uchar *pBuf, uchar uchars ) { uint status, uchar_ctr; CSN = 0; // Set CSN low, init SPI tranaction status = SPI_RW ( reg ); // Select register to write to and read status uchar for ( uchar_ctr = 0; uchar_ctr < uchars; uchar_ctr++ ) pBuf[uchar_ctr] = SPI_RW ( 0 ); // CSN = 1; return ( status ); // return nRF24L01 status uchar } /********************************************************************************************************* /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars) /*功能: 用于写数据:reg为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数 /*********************************************************************************************************/ uint SPI_Write_Buf ( uchar reg, uchar *pBuf, uchar uchars ) { uint status, uchar_ctr; CSN = 0; //SPI使能 status = SPI_RW ( reg ); for ( uchar_ctr = 0; uchar_ctr < uchars; uchar_ctr++ ) // SPI_RW ( *pBuf++ ); CSN = 1; //关闭SPI return ( status ); // } /****************************************************************************************************/ /*函数:void SetRX_Mode(void) /*功能:数据接收配置 /****************************************************************************************************/ void SetRX_Mode ( void ) { CE = 0; SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0f ); // IRQ收发完成中断响应,16位CRC ,主接收 CE = 1; inerDelay_us ( 130 ); } /******************************************************************************************************/ /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) /*功能:数据读取后放如rx_buf接收缓冲区中 /******************************************************************************************************/ uchar nRF24L01_RxPacket ( unsigned char* rx_buf ) { unsigned char revale = 0; sta = SPI_Read ( STATUS ); // 读取状态寄存其来判断数据接收状况 if ( RX_DR ) // 判断是否接收到数据 { CE = 0; //SPI使能 SPI_Read_Buf ( RD_RX_PLOAD, rx_buf, TX_PLOAD_WIDTH ); // read receive payload from RX_FIFO buffer revale = 1; //读取数据完成标志 } SPI_RW_Reg ( WRITE_REG + STATUS, sta ); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志 return revale; } /*********************************************************************************************************** /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf) /*功能:发送 tx_buf中数据 /**********************************************************************************************************/ void nRF24L01_TxPacket ( unsigned char * tx_buf ) { CE = 0; //StandBy I模式 SPI_Write_Buf ( WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH ); // 装载接收端地址 SPI_Write_Buf ( WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH ); // 装载数据 SPI_RW_Reg ( WRITE_REG + CONFIG, 0x0e ); // IRQ收发完成中断响应,16位CRC,主发送 SPI_RW_Reg ( WRITE_REG + STATUS, 0X7E ); // 清 除中断,以便开始发送数据 CE = 1; //置高CE,激发数据发送 inerDelay_us ( 10 ); } #endif