1、24L01+带数据包的ACK用于双向传输24L01+带数据包的ACK-用于双向传输D/*/#ifndef _NRF24L01_H_#define _NRF24L01_H_#define uchar unsigned char#define uint unsigned int/*1:GND;2:Vcc;3:CE;4CSN;5:SCK;6:MOSI;7:MISO;8:IRQ*/ sbit CE = P73; / Chip Enable pin signal (output)/ sbit CSN = P72; / Slave Select pin, (output to CSN, nRF24L01)
2、/ sbit SCK = P71; / Interrupt signal, from nRF24L01 (input)/ sbit MOSI = P70; / Master In, Slave Out pin (input)/ sbit MISO = P37; / Serial Clock pin, (output)/ sbit IRQ = P36; / Master Out, Slave In pin (output)sbit CE = P04; / Chip Enable pin signal (output)sbit CSN = P03; / Slave Select pin, (out
3、put to CSN, nRF24L01)sbit SCK = P02; / Interrupt signal, from nRF24L01 (input)sbit MOSI = P01; / Master In, Slave Out pin (input)sbit MISO = P00; / Serial Clock pin, (output)sbit IRQ = P46; / Master Out, Slave In pin (output)/ SPI(nRF24L01) commands#define READ_REG 0x00 /读寄存器指令#define WRITE_REG 0x20
4、 /写寄存器指令#define R_RX_PL_WID 0x60 /读接收到的数据长度#define RD_RX_PLOAD 0x61 /读接收数据指令#define WR_TX_PLOAD 0xA0 /写待发送数据指令#define W_ACK_PAYLOAD 0xA8 /写ACK数据指令,用于接收模式#define FLUSH_TX 0xE1 /冲洗发送FIFO指令#define FLUSH_RX 0xE2 /冲洗接收FIFO指令#define REUSE_TX_PL 0xE3 /重复装载数据指令#define NOP 0xFF /空指令,用于读出状态字/寄存器地址#define CONF
5、IG 0x00 /配置寄存器#define EN_AA 0x01 /自动应答,禁止自动应答后可以与2401通讯#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 /数
6、据通道0接收地址,最大长度5个字节,先写低字节,所有字节数量由SETUP_AW设定#define RX_ADDR_P1 0x0B /数据通道1接收地址,最大长度5个字节,先写低字节,所有字节数量由SETUP_AW设定#define RX_ADDR_P2 0x0C /数据通道2接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P139:8相等#define RX_ADDR_P3 0x0D /数据通道3接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P139:8相等#define RX_ADDR_P4 0x0E /数据通道4接收地址,最低字节可设定,高字节部分必须与RX_ADDR
7、_P139:8相等#define RX_ADDR_P5 0x0F /数据通道5接收地址,最低字节可设定,高字节部分必须与RX_ADDR_P139:8相等#define TX_ADDR 0x10 /发送地址#define RX_PW_P0 0x11 /通道0接收数据长度#define RX_PW_P1 0x12 /通道1接收数据长度#define RX_PW_P2 0x13 /通道2接收数据长度#define RX_PW_P3 0x14 /通道3接收数据长度#define RX_PW_P4 0x15 /通道4接收数据长度#define RX_PW_P5 0x16 /通道5接收数据长度#defin
8、e FIFO_STATUS 0x17 /FIFO状态寄存器#define DYNPD 0x1C#define FEATURE 0x1D#define Mode_RX1 1 /普通接收模式#define Mode_TX1 2 /普通发送模式#define Mode_RX2 3 /双向传输接收模式#define Mode_TX2 4 /双向传输发送模式#define TX_ADR_WIDTH 5 / 5字节宽度的发送地址#define RX_ADR_WIDTH 5 / 5字节宽度的接收地址#define TX_PLOAD_WIDTH 32 / 数据通道有效数据宽度#define RX_PLOAD_
9、WIDTH 32 / 数据通道有效数据宽度extern uchar code TX_ADDRESSTX_ADR_WIDTH;extern uchar code RX_ADDRESSRX_ADR_WIDTH;extern uchar RX_BUFTX_PLOAD_WIDTH; /接收缓存extern uchar TX_BUFTX_PLOAD_WIDTH; /发送缓存extern uchar RX_flag; /接收标志extern uchar Length; /数据长度void Init_24L01(Byte ModeDat,Byte ch); /初始化24L01void Delay12us()
10、;uchar SPI_RW(uchar byte); /SPI读写函数uchar SPI_Write_Reg(uchar reg, uchar value);uchar SPI_Read(uchar reg);uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes);uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes);void NRF_TX(uchar *pBuf, uchar Len); /发送数据包,用于发送模式2/4void NRF_TX_AP(uchar *pBuf,
11、 uchar Len); /发送数据包,接收模式2uchar Check_ACK(bit clear);void Read_24L01_data(void); #endif /*/以下是.c文件#include #include nrf24l01.h#include #include uart1.huchar bdata sta;sbit RX_DR = sta6;sbit TX_DS = sta5;sbit MAX_RT = sta4;uchar code TX_ADDRESSTX_ADR_WIDTH = 0x13,0x14,0x52,0x05,0x20; / 定义一个静态发送地址uchar
12、 code RX_ADDRESSRX_ADR_WIDTH = 0x13,0x14,0x52,0x05,0x20; / 定义一个静态发送地址uchar RX_BUFTX_PLOAD_WIDTH; /接收缓存uchar TX_BUFTX_PLOAD_WIDTH; /发送缓存uchar RX_flag; /接收标志uchar Length; /数据长度/*/*函数: init_io()描述: 初始化IO/*/void Init_24L01(Byte ModeDat,Byte ch) CE = 0; / 待机 CSN = 1; / SPI禁止 SCK = 0; / SPI时钟置低 IRQ = 1; /
13、 中断复位 Delay12us(); CE = 0; SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); / 写入发送地址 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); / 为了应答接收设备,接收通道0地址和发送地址相同 SPI_Write_Reg(WRITE_REG + EN_AA, 0x01); / 使能接收通道0自动应答 SPI_Write_Reg(WRITE_REG + EN_RXADDR, 0x01); / 使能接收通道0 SPI
14、_Write_Reg(WRITE_REG + SETUP_RETR, 0x1a); / 自动重发延时等待500us,自动重发10次 SPI_Write_Reg(WRITE_REG + RF_CH, ch); / 选择射频通道ch SPI_Write_Reg(WRITE_REG + RF_SETUP, 0x0f); / 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益 switch(ModeDat) case 1: SPI_Write_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); / 接收通道0选择和发送通道相同有效数据宽度 SPI_Write_R
15、eg(WRITE_REG + CONFIG, 0x0f); break; case 2: SPI_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); SPI_Write_Reg(WRITE_REG + CONFIG, 0x0e); break; case 3: SPI_Write_Reg(FLUSH_TX,0xff); SPI_Write_Reg(FLUSH_RX,0xff); SPI_Write_Reg(WRITE_REG + CONFIG, 0x0f); / IRQ收发完成中断开启,16位CRC,主接收 SPI_RW(0x50); SPI_RW(0x
16、73); SPI_Write_Reg(WRITE_REG+DYNPD,0x01); SPI_Write_Reg(WRITE_REG+FEATURE,0x06); break; case 4: SPI_Write_Reg(WRITE_REG + CONFIG, 0x0e); / IRQ收发完成中断开启,16位CRC,主发送 SPI_Write_Reg(FLUSH_TX,0xff); SPI_Write_Reg(FLUSH_RX,0xff); SPI_RW(0x50); SPI_RW(0x73); SPI_Write_Reg(WRITE_REG+DYNPD,0x01); SPI_Write_Reg
17、(WRITE_REG+FEATURE,0x06); break; default:break; CE = 1;/*/*函数:delay_ms()描述: 延迟x毫秒/*/void Delay12us() /18.432MHz unsigned char i; _nop_(); _nop_(); _nop_(); i = 52; while (-i);/*/*函数:SPI_RW()描述: 根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节/*/uchar SPI_RW(uchar byte) uchar i; for(i=0; i8; i+) / 循环8次 MOSI
18、 = (byte & 0x80); / byte最高位输出到MOSI byte = 1; / 低一位移位到最高位 SCK = 1; / 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据 byte |= MISO; / 读MISO到byte最低位 SCK = 0; / SCK置低 return(byte); / 返回读出的一字节/*/*函数:SPI_RW_Reg()描述: 写数据value到reg寄存器/*/uchar SPI_Write_Reg(uchar reg, uchar value) uchar status; CSN = 0; / CSN置低,开始传输数
19、据 status = SPI_RW(reg); / 选择寄存器,同时返回状态字 SPI_RW(value); / 然后写数据到该寄存器 CSN = 1; / CSN拉高,结束数据传输 return(status); / 返回状态寄存器/*/*函数:SPI_Read()描述: 从reg寄存器读一字节/*/uchar SPI_Read(uchar reg) uchar reg_val; CSN = 0; / CSN置低,开始传输数据 SPI_RW(reg); / 选择寄存器 reg_val = SPI_RW(0); / 然后从该寄存器读数据 CSN = 1; / CSN拉高,结束数据传输 retu
20、rn(reg_val); / 返回寄存器数据/*/*函数:SPI_Read_Buf()描述: 从reg寄存器读出bytes个字节,通常用来读取接收通道 数据或接收/发送地址/*/uchar SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes) uchar status, i; CSN = 0; / CSN置低,开始传输数据 status = SPI_RW(reg); / 选择寄存器,同时返回状态字 for(i=0; ibytes; i+) pBufi = SPI_RW(0); / 逐个字节从nRF24L01读出 CSN = 1; / CSN拉高,
21、结束数据传输 return(status); / 返回状态寄存器/*/*函数:SPI_Write_Buf()描述: 把pBuf缓存中的数据写入到nRF24L01,通常用来写入发 射通道数据或接收/发送地址/*/uchar SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes) uchar status, i; CSN = 0; / CSN置低,开始传输数据 status = SPI_RW(reg); / 选择寄存器,同时返回状态字 for(i=0; ibytes; i+) SPI_RW(pBufi); / 逐个字节写入nRF24L01 CSN =
22、 1; / CSN拉高,结束数据传输 return(status); / 返回状态寄存器/*/void NRF_TX(uchar *pBuf, uchar Len) /发送数据包,用于发送模式2/4 CE = 0; SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); / 装载接收端地址 SPI_Write_Buf(WR_TX_PLOAD, pBuf, Len); / 装载数据 CE = 1; Delay12us();void NRF_TX_AP(uchar *pBuf, uchar Len) /发送数据包,接收模式2
23、 CE = 0; SPI_Write_Buf(W_ACK_PAYLOAD, pBuf, Len); CE = 1;/判断寄存器状态是否有接收到数据或者发送完数据void Read_24L01_data(void)/ while(IRQ); sta = SPI_Read(READ_REG+STATUS); / 读状态寄存器 if(RX_DR) / 判断是否接受到数据 Length = SPI_Read(READ_REG+R_RX_PL_WID); if(Length33) SPI_Read_Buf(RD_RX_PLOAD, RX_BUF, Length); / 从RX FIFO读出数据 RX_f
24、lag = 1; /将标志位置1,表示接收到数据,好让主函数去处理接收到的数据 else SPI_Write_Reg(FLUSH_RX,0xff);/清空缓冲区 if(TX_DS) ; if(MAX_RT) if(sta & 0x01) /TX FIFO FULL SPI_Write_Reg(FLUSH_TX,0xff); SPI_Write_Reg(WRITE_REG + STATUS, sta); / 清除RX_DS中断标志以下是主函数,发送与接收模式用一样的.c.h文件,初始化为不同模式就行了/*/*/发送模式:#include #include #include uart1.h#include nrf24l01.hvoid Delayxms(Word xms) /18.432MHz Word j; for(;xms0;xms-) for(j=1110;j0;j-);Byte a; void main() Dela
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1