NRF24L01地发送与接收程序

合集下载

NRF24L01测试发送程序

NRF24L01测试发送程序

NRF24L01测试发送程序/*对该程序做一下几点说明一、该程序仅用于测试是否发送成功,所以有两处的设置做出了调整1、SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);//频道0自动ACK应答允许(此处禁止用于测试)2、SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00);//允许接收地址只有频道0(此处禁止用于测试)二、其中P3口连接的是无线模块的引脚,P2口连接的是LED 是为了显示发送数据后STA TUS的状态若使用的开发板不同,需将P2口连接到其他口观察状态寄存器的状态三、P3口一定不要接其他外部设备,如使用的开发板有其他外接设备一定要断掉。

或侧换成最小系统板进行试验四、若发送仍不成功,可以用示波器观察发送数据时的MISO口的波形判断是否为硬件问题*///***************************************************发送程序*********************************//#include#includetypedef unsigned char uchar;//****************************************NRF24L01 IO端口定义*********************************//sbit CE =P3^2;sbit CSN =P3^3;sbit SCK =P3^4;sbit M OSI =P3^5;sbit M ISO =P3^6;sbit IRQ =P3^7;//***********************************发送缓冲区***********************************************//uchar TxBuf[3]={1,2,3};//发送的数据用数字存储//*****************************NRF24L01的接收和发送地址***************************************//#define TX_ADR_WIDTH 5 // 5个字节的TX地址长度#define RX_ADR_WIDTH 5 // 5个字节的TX地址长度#define TX_PLOAD_WIDTH 3 // 20个字节的TX数据长度#define RX_PLOAD_WIDTH 3 // 20个字节的TX数据长度uchar const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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);uchar SPI_RW(uchar num);uchar SPI_Read(uchar reg);void SetRX_Mode(void);uchar SPI_RW_Reg(uchar reg, uchar value);uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************延时函数***************************************//void inerDelay_us(unsigned char n){for(;n>0;n--)_nop_();}//*****************************************长延时*****************************************//void Delay(unsigned int s){unsigned int i;for(i=0; i<="" p="">for(i=0; i<="" p="">}//****************************************状态标志****************************************//uchar bdata sta;sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;//********************************NRF24L01初始化******************************************//void init_NRF24L01(void){inerDelay_us(100);CE=0; // 片选使能CSN=1; // SPI使能SCK=0; // SPI时钟拉低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); //写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 频道0自动ACK 应答允许(此处禁止用于测试)SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x00); //允许接收地址只有频道0(此处禁止用于测试),如果需要多频道可以参考Page21 SPI_RW_Reg(WRITE_REG + RF_CH, 0); //设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送}/************************************************************** **************** **********************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/************************************************************** **************** **********************/uchar SPI_RW(uchar num){uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (num & 0x80); // output 'uchar', MSB to MOSInum = (num << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..num |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(num); // return read uchar}/************************************************************** **************** **********************函数:uchar SPI_Read(uchar reg)功能:NRF24L01的SPI时序*************************************************************** **************** *********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/************************************************************** **************** **********************//*功能:NRF24L01读写寄存器函数/************************************************************** **************** **********************/uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/************************************************************** **************** ***************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************** ************ ***************************/uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uchar status,uchar_ctr;CSN = 0; //SPI使能status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<="" bdsfid="224" p="" uchar_ctr++)="">SPI_RW(*pBuf++);CSN = 1; //关闭SPIreturn(status); //}/************************************************************** **************** *****************************/*函数: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); // 装载数据CE=1; //置高CE激发数据发送inerDelay_us(10);}/************************************主函数************************************************************/ void main(void){init_NRF24L01() ;Delay(6000);while(1){nRF24L01_TxPacket(TxBuf); // 发送Tx buffer的数据Delay(15000); //可变P2=SPI_Read(STA TUS);Delay(10000); //可变}}。

nrf24l01发送接收一体程序(以调通,解决了接收端只能接收一次的问题)

nrf24l01发送接收一体程序(以调通,解决了接收端只能接收一次的问题)

nrf24l01发送接收一体程序(以调通,解决了接收端只能接收一次的问题)/**************************************************基于单片机无线报警系统主机(机载设别)系统程序/**************************************************/#include#include#define uchar unsigned char/***************************************************/#define TX_ADR_WIDTH 5 // 5字节宽度的发送/接收地址#define TX_PLOAD_WIDTH 4 // 数据通道有效数据宽度uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址uchar RX_BUF[4]={0,0,0,0};uchar TX_BUF[4]={0x20,0x20,0x20,0x20};uchar flag; //无线模块接受数据标志uchar DATA = 0x01;uchar bdata sta;unsigned int a,k; //定时器延时参数uchar mark; //传感器响应标志位uchar mark1; // 延时标志位sbit RX_DR = sta^6; //接受数据成功标志位sbit TX_DS = sta^5; // 发送成功标志位sbit MAX_RT = sta^4; //最大重发上限标志位sbit HW=P2^0; //红外感应模块输入端sbit ZD=P1^7; //震动传感器输入端sbit LED=P2^1; //LED报警器输出端sbit SDA=P2^4; //语音模块数据控制端sbit ONN=P2^3; //语音芯片电源控制端口sbit FM =P2^5; //蜂鸣器/************************************************** 函数:delayus()描述:延迟x微秒/**************************************************/void delayus(unsigned int t){while(t--);}/************************************************** 函数:delayms()描述:延迟x毫秒/**************************************************/void delayms(unsigned int h){unsigned int j;while(h--)for(j=85;j>0;j--);}/************************************************** 函数:delays()描述:延迟x.xx秒/**************************************************/void delays( float h){unsigned int i,j;h*=100;while(h--){for(i=0;i<235;i++)for(j=0;j<3;j++);}}/************************************************** 函数:sendadd()描述:语音模块发送地址信号/**************************************************/ void sendadd(unsigned char addr){uchar i;delayms(5); /* 数据信号置于低电平5ms */for(i=0;i<8;i++){ SDA=1;if(addr & 1){delayus(60); /* 高电平比低电平为600us:200us,表示发送数据1 */SDA=0;delayus(20);}else{delayus(20);SDA=0; /* 高电平比低电平为200us:600us,表示发送数据0 */ delayus(60);}addr>>=1;}SDA=1;}/**************************************************函数:SPI_RW()描述:根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节/**************************************************/uchar SPI_RW(uchar byte){for(i=0; i<8; i++) // 循环8次{MOSI = (byte & 0x80); // byte最高位输出到MOSIbyte <<= 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_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN置低,开始传输数据status = SPI_RW(reg); // 选择寄存器,同时返回状态字SPI_RW(value); // 然后写数据到该寄存器CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/************************************************** 函数:clear()描述:清TX_FIFO寄存器/**************************************************/void clear(){CSN=0;SPI_RW(FLUSH_TX);CSN=1;}/************************************************** 函数: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拉高,结束数据传输return(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; ipBuf[i] = SPI_RW(0); // 逐个字节从nRF24L01读出CSN = 1; // CSN拉高,结束数据传输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; iSPI_RW(pBuf[i]); // 逐个字节写入nRF24L01CSN = 1; // CSN拉高,结束数据传输return(status); // 返回状态寄存器}/**************************************************函数:RX_Mode()描述:这个函数设置nRF24L01为接收模式,等待接收发送设备的数据包/**************************************************/void RX_Mode(void){CE = 0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F); // CRC使能,16位CRC校验,上电,接收模式CE = 1;delayus(200); // 拉高CE启动接收设备}/**************************************************函数:TX_Mode()描述:这个函数设置nRF24L01为发送模式,(CE=1持续至少10us),130us后启动发射,数据发送结束后,发送模块自动转入接收模式等待应答信号。

NRF24L01收发程序

NRF24L01收发程序

/******* ******** ******** ******** ******** ******** ******** ******** ******** ******* ******** ******** ******/ uchar SPI_Read (uchar reg) { uchar reg_val; CSN = 0; // CSN low, initiali ze SPI communic ation... SPI_RW(r eg); // Select register to read from.. reg_val = SPI_RW(0 ); // ..then read register value
/*NRF24L 01 初始 化 //****** ******** ******** ******** ******** ******** ******** ******** */ void init_NRF 24L01(vo id) { inerDela y_us(100 ); CE=0; // chip enable CSN=1; // Spi disable SCK=0; // SPI_Writ e_Buf(WR ITE_REG + TX_ADDR, TX_ADDRE SS, TX_ASCK high.. uchar |= MISO; // capture current MISO bit SCK = 0; // ..then set SCK low again } return(u char); // return read uchar } /******* ******** ******** ******** ******** ******** ******** ******** ******** ******* ******** ******** ****** /*函数: uchar SPI_Read (uchar reg) /*功能: NRF24L01 的SPI 时 序

nRF24L01的工作原理

nRF24L01的工作原理

nRF24L01的工作原理nRF24L01是一款低功耗、高性能的2.4GHz无线收发模块,广泛应用于物联网、无线传感器网络和远程控制等领域。

它采用射频(RF)技术,能够在不需要复杂的网络设置和配置的情况下,实现设备之间的无线通信。

nRF24L01的工作原理主要包括以下几个方面:1. 射频通信:nRF24L01采用2.4GHz频段的射频信号进行通信。

它支持GFSK调制方式,并提供多个可选的通信通道。

在发送端,数据通过SPI接口输入到nRF24L01的发送缓冲区,经过调制后,以射频信号的形式发送出去。

在接收端,nRF24L01接收到射频信号后,进行解调和解码,将数据恢复成原始的数字信号,并通过SPI接口输出。

2. 发送和接收模式:nRF24L01有两种工作模式,分别是发送模式和接收模式。

在发送模式下,nRF24L01将发送缓冲区中的数据通过射频信号发送出去。

在接收模式下,nRF24L01接收到射频信号后,将数据存储在接收缓冲区中,等待主机读取。

3. 网络配置:nRF24L01支持多个通信通道和多个地址管道,可以通过设置不同的通道和地址,实现多个设备之间的无线通信。

每个设备都有一个唯一的地址,用于区分不同的设备。

通过配置不同的通道和地址,可以避免设备之间的干扰。

4. 自动重传和自动确认:nRF24L01具有自动重传和自动确认功能。

在发送数据时,nRF24L01可以自动重传数据,以确保数据的可靠传输。

同时,接收端的nRF24L01可以发送确认信号给发送端,告知数据已经成功接收。

如果发送端没有收到确认信号,会自动重传数据,以提高数据传输的可靠性。

5. 低功耗设计:nRF24L01采用了低功耗设计,可以在不同的睡眠模式之间切换,以降低功耗。

在睡眠模式下,nRF24L01的功耗非常低,适用于电池供电的应用场景。

总结:nRF24L01是一款功能强大的2.4GHz无线收发模块,具有射频通信、发送和接收模式、网络配置、自动重传和自动确认、低功耗设计等特点。

nrf24l01发送接收点对点 汇编程序

nrf24l01发送接收点对点 汇编程序

;延时14s子程序
YANSHI1S MOV R7,#250
YANSHI1S1 MOV R6,#250
YANSHI1S2 NOP
NOP
DJNZ R6,YANSHI1S2
DJNZ R2,DUZT1
SETB P1.7 ;CSN变高,完成一次命令
RET
START MOV P1,#0AFH ;模块待机
DJNZ R6,DL0
DJNZ R7,DL1
RET
;将58开始的单或多字节(字节数在R3中)写入芯片
XIENB MOV R0,#58H
CLR P1.7 ;SCN变低
MOV 58H,#21H ;01寄存器
MOV 59H,#03H ;0,1通道允许自动应答
MOV R3,#02H
LCALL XIENB
MOV P1.5,C ;数据送上MOSI线
SETB P1.4 ;数据移入模块
CLR P1.4
SETB P1.6 ;启动发射
MOV R7,#5
DJNZ R7,$
CLR P1.6
MOV R3,#02H
LCALL XIENB
MOV 58H,#2AH ;0A寄存器(通道0)
MOV 59H,#02H ;配置地址
DJNZ R2,XIE1B1
RET
;读芯片状态字 将芯片状态字读到5FH
DUZT MOV R2,#8
SETB P1.5
MOV R0,#70H
XIEXUN LCALL XIE1B
INC R0
DJNZ R3,XIEXUN
SETB P1.7
MOV 58H,#31H ;11寄存器

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册

nRF24L01无线通信模块使用手册一、模块简介该射频模块集成了NORDIC公司生产的无线射频芯片nRF24L01:1.支持2.4GHz的全球开放ISM频段,最大发射功率为0dBm2.2Mbps,传输速率高3.功耗低,等待模式时电流消耗仅22uA4.多频点(125个),满足多点通信及跳频通信需求5.在空旷场地,有效通信距离:25m(外置天线)、10m(PCB天线)6.工作原理简介:发射数据时,首先将nRF24L01配置为发射模式,接着把地址TX_ADDR和数据TX_PLD 按照时序由SPI口写入nRF24L01缓存区,TX_PLD必须在CSN为低时连续写入,而TX_ADDR在发射时写入一次即可,然后CE置为高电平并保持至少10μs,延迟130μs后发射数据;若自动应答开启,那么nRF24L01在发射数据后立即进入接收模式,接收应答信号。

如果收到应答,则认为此次通信成功,TX_DS置高,同时TX_PLD从发送堆栈中清除;若未收到应答,则自动重新发射该数据(自动重发已开启),若重发次数(ARC_CNT)达到上限,MAX_RT置高,TX_PLD不会被清除;MAX_RT或TX_DS置高时,使IRQ变低,以便通知MCU。

最后发射成功时,若CE为低,则nRF24L01进入待机模式1;若发送堆栈中有数据且CE为高,则进入下一次发射;若发送堆栈中无数据且CE为高,则进入待机模式2。

接收数据时,首先将nRF24L01配置为接收模式,接着延迟130μs进入接收状态等待数据的到来。

当接收方检测到有效的地址和CRC时,就将数据包存储在接收堆栈中,同时中断标志位RX_DR置高,IRQ变低,以便通知MCU去取数据。

若此时自动应答开启,接收方则同时进入发射状态回传应答信号。

最后接收成功时,若CE变低,则nRF24L01进入空闲模式1。

三、模块引脚说明1 / 197 NC 空 8 CSN 芯片片选信号 I 9 CE 工作模式选择I 10+5V电源四、模块与AT89S52单片机接口电路注:上图为示意连接,可根据自己实际需求进行更改;使用AT89S52MCU 模块时,请将Nrf24L01通讯模块每个端口(MOSI 、SCK 、CSN 和CE )接4.7K 的排阻上拉到VCC 增强其驱动能力(如下图:)。

nrf24L01发送接收流程图

nrf24L01发送接收流程图

NRF24L01流程图、引脚定义
N Y
Y
N
N
开始
时钟IC 、LCD 液晶、温度传感器 初始化
nRF24L01配置模式
判断键盘是否有动数据采集 将采集到的数据装入发射寄启动发发射是否完成 按键处理子
是否处理

Y
开始上电
待机模
式I
CE
有数
据包在
发射处

发射模
式发送数据
自动
重发使能
NO_A
CK有效
置位
TX_DS
CE
有数
据包在
有数
据包
CE待机模
接收
模式
应答
是否接收


把ACK
加载到接收
置位
TX_DS 发射处

发射模式
重发上一次数
据包
置位
MAX_RT
接收模式
待机模
CE
CE
接收处理
开始上电
接收
FIFO满了
接收
到数据
自动
应答使能
是新
把数据包放入接收
FIFO并置位RX_DR
把数据包放入接收
FIFO并置位RX_DR
IRQ
开始
初始化
把数据装载到数据发送结
结束。

NRF24L01 MSP430发送接收程序(word文档良心出品)

NRF24L01 MSP430发送接收程序(word文档良心出品)

NRF24L01 MSP430发送接收程序作者:codebaby 文章来源:codebaby 点击数: 1351 更新时间:2011-8-18最近弄了几天的无线模块,玩的是NRF2L01,因为这款无线模块价格便宜,网上也就卖10多块钱!刚开始用51写,“百度一下”发现网上的程序真是百篇一律,你抄我,我抄你。

对比了几个程序之后,发现他们的程序注释也是自相矛盾,看了的唯一收获就是,结合技术资料,对NRF24L01的工作模式和通信过程有了个总体的把握。

用51调了几次没成功,改而用430板子来写。

在网上查了一些相关的程序,终于成功了。

现在发现其实要写对NRF24L01的基本通信程序并不难,当然要玩转它又是另外一回事了。

我也刚刚才玩会单通道接收发送这个工作模式,其他的工作模式还没玩!还是附上相应的程序供大家学习交流,当然程序可能难免还有疏漏和错误,还望比拼指出!这是NRF24L01的头文件配置程序:#include <msp430x14x.h>//=======================NRF24L01_CE 端口========================================= #define RF24L01_CE_0 P3OUT &=~BIT1#define RF24L01_CE_1 P3OUT |= BIT1//=============================RF24L01_CSN 端口================================== #define RF24L01_CSN_0 P3OUT &=~BIT3#define RF24L01_CSN_1 P3OUT |= BIT3//=============================RF24L01_SCK 端口====================================== #define RF24L01_SCK_0 P3OUT &=~BIT2#define RF24L01_SCK_1 P3OUT |= BIT2//=============================RF24L01_MISO 端口=========================================#define RF24L01_MISO_0 P3OUT &=~BIT0#define RF24L01_MISO_1 P3OUT |= BIT0//============================= RF24L01_MOSI 端口================================ #define RF24L01_MOSI_0 P2OUT &=~BIT6#define RF24L01_MOSI_1 P2OUT |= BIT6//==========================IRQ 状态============================================ #define RF24L01_IRQ_0 P2OUT &=~BIT7#define RF24L01_IRQ_1 P2OUT |= BIT7//==========================NRF24L01地址,接收发送数据长度=============================== =============#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 32 TX payload //这里可以更改你想要发送和接收的数据长度如果是发指令我喜欢越短越好#define RX_PLOAD_WIDTH 32 // 32 uints TX payload//=========================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 NOP1 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栈入栈出状态寄存器设置//=============================RF24l01状态=====================================char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址//我刚开始学的时候对这个发送和接收地址不是很明白,为什么他要设置成这样,后来才知道这个地址是用户自己定的,也就是说不是每个芯片只有唯一的地址,只要发送和接收端的地址一致就行char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址char sta;char TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; //这个程序要发送的数据void RF24L01_IO_set(void);void ms_delay(void);void InitSys();void Delay(int s);char SPI_RW(char data);char SPI_Read(char reg);char SPI_RW_Reg(char reg, char value);char SPI_Read_Buf(char reg, char *pBuf, char uchars);char SPI_Write_Buf(char reg, char *pBuf, char uchars);void SetRX_Mode(void);char nRF24L01_RxPacket(char* rx_buf);void nRF24L01_TxPacket(char * tx_buf);void init_NRF24L01(void);//===========================RF24L01端口设置========================================== void RF24L01_IO_set(void){P2DIR &= 0x7f; P2DIR |= 0x40; P2SEL&=0x3F; P2IE=P2IE&0x3f;P3DIR &= 0xFE; P3DIR |= 0x0E; P3SEL&=0xF0;}//******************************************************************************//系统初始化打开430XT2晶振//******************************************************************************void InitSys(){unsigned int iq0;_DINT();BCSCTL1 &=~XT2OFF;do{IFG1 &= ~OFIFG; // 清除振荡器失效标志for (iq0 = 0xFF; iq0 > 0; iq0--); // 延时,等待XT2起振}while ((IFG1 & OFIFG) != 0); // 判断XT2是否起振BCSCTL2 =SELM1+SELS; // MCLK,SMCLK时钟为XT2}//========================延时约5ms============================================= void ms_delay(void){unsigned int i=40000;while (i != 0){i--;}}//========================================长延时================================ void Delay(int s){unsigned int i,j;for(i=0; i<s; i++);for(j=0; j<s; j++);}//****************************************************************************************** //延时函数//****************************************************************************************** void inerDelay_us(char n){for(;n>0;n--);}//============================================================================== //函数:uint SPI_RW(uint uchar)//功能:NRF24L01的SPI写时序//******************************************************************************char SPI_RW(char data){char i,temp=0;for(i=0;i<8;i++) // output 8-bit{if((data & 0x80)==0x80){RF24L01_MOSI_1; // output 'uchar', MSB to MOSI}else{RF24L01_MOSI_0;}data = (data << 1); // shift next bit into MSB..temp<<=1;RF24L01_SCK_1; // Set SCK high..if((P3IN&0x01)==0x01)temp++; // capture current MISO bitRF24L01_SCK_0; // ..then set SCK low again}return(temp); // return read uchar}//*********************************************************************************************** *****//函数:uchar SPI_Read(uchar reg)//功能:NRF24L01的SPI时序//*********************************************************************************************** *****char SPI_Read(char reg){char reg_val;RF24L01_CSN_0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueRF24L01_CSN_1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}//*********************************************************************************************** *****///功能:NRF24L01读写寄存器函数//*********************************************************************************************** *****/char SPI_RW_Reg(char reg, char value){char status1;RF24L01_CSN_0; // CSN low, init SPI transactionstatus1 = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..RF24L01_CSN_1; // CSN high againreturn(status1); // return nRF24L01 status uchar}//*********************************************************************************************** *****///函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数//****************************************************************************************************/char SPI_Read_Buf(char reg, char *pBuf, char chars){char status2,uchar_ctr;RF24L01_CSN_0; // Set CSN low, init SPI tranactionstatus2 = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<chars;uchar_ctr++){pBuf[uchar_ctr] = SPI_RW(0);}RF24L01_CSN_1;return(status2); // return nRF24L01 status uchar}//*********************************************************************************************** **********//函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)//功能: 用于写数据reg:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数//*********************************************************************************************** **********/char SPI_Write_Buf(char reg, char *pBuf, char chars){char status1,uchar_ctr;RF24L01_CSN_0; //SPI使能status1 = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<chars; uchar_ctr++){SPI_RW(*pBuf++);}RF24L01_CSN_1; //关闭SPIreturn(status1);}//*********************************************************************************************** *****///函数:void SetRX_Mode(void)//功能:数据接收配置//*********************************************************************************************** *****/void SetRX_Mode(void){RF24L01_CE_0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收RF24L01_CE_1;inerDelay_us(130); //注意不能太小}//*********************************************************************************************** *******///函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)//功能:数据读取后放如rx_buf接收缓冲区中//*********************************************************************************************** *******/char nRF24L01_RxPacket(char* rx_buf){char revale=0;sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(sta&0x40) // 判断是否接收到数据{RF24L01_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(char * tx_buf)//功能:发送tx_buf中数据//*********************************************************************************************** ***********/void nRF24L01_TxPacket(char * tx_buf){RF24L01_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,主发送RF24L01_CE_1; //置高CE,激发数据发送inerDelay_us(10);}//****************************************************************************************//NRF24L01初始化//***************************************************************************************/void init_NRF24L01(void){inerDelay_us(100);RF24L01_CE_0 ; // chip enableRF24L01_CSN_1; // Spi disableRF24L01_SCK_0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Pa ge21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0E); // IRQ收发完成中断响应,16位CRC ,主接收}}//=============================================================================下面是发送主程序:#include <msp430x14x.h>#include "NRF24L01.h"void main(){WDTCTL = WDTPW + WDTHOLD; //禁止看门狗RF24L01_IO_set();InitSys();init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // 将要发送的数据转移到发送缓冲区while(1){nRF24L01_TxPacket(TxBuf);SPI_RW_Reg(WRITE_REG+STATUS,0XFF); //清状态寄存器ms_delay();ms_delay();LED1_1;ms_delay();ms_delay();LED1_0;}}下面是接收主程序:将接收到的数据发送到PC 可以通过串口助手来查看接收到数据是否正确#include <msp430x14x.h>#include "NRF24L01.h"char RxBuf[32]={0};//===============================串口初始化=====================================void init_uart0(void){//====================串口工作模式设置========================================U0CTL=0x00; // U0CTL包含串口0通信协议、通信模式、校验位等设置,允许UART0U0CTL +=CHAR; //(CHAR=0x10)当CHAR=0时位7位数据,当CHAR=1时为8位数据//不需要校验,数据位为8位,无反馈,异步UART通信,UART被允许//====================串口发送操作设置========================================U0TCTL=0x00; //U0TCTL包含串口0发送功能操作U0TCTL +=SSEL0; //波特率发生器选择ACLK//#define SSEL1 (0x20) #define SSEL0 (0x10)//====================串口拨特率设置9600====================================//===================拨特率计算公式:拨特率=BRCLK/(UBR+(M7+M6+。

NRF24L01的发送与接收程序

NRF24L01的发送与接收程序

#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义sbit MISO =P1^5;sbit MOSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//************************************按键sbit KEY1=P3^4;//************************************蜂明器sbit LED=P3^5;//**************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//*****************************************************************************uint 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; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收}/******************************************************************************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/******************************************************************************uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/******************************************************************************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/******************************************************************************uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*****************************************************************************//*功能:NRF24L01读写寄存器函数/*****************************************************************************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*****************************************************************************//*函数: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 tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(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)/*功能: 用于写数据:为寄存器地址,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; //关闭SPIreturn(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接收缓冲区中/*****************************************************************************/unsigned char 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 bufferrevale =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,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************串口初始化void StartUART( void ){ //波特率4800SCON = 0x50;TMOD = 0x20;TH1 = 0xFA;TL1 = 0xFA;PCON = 0x00;TR1 = 1;}//************************************通过串口将接收到数据发送给PC端void R_S_Byte(uchar R_Byte){SBUF = R_Byte;while( TI == 0 ); //查询法TI = 0;}//************************************主函数void main(void){uchar i,temp;uchar RxBuf[32];init_NRF24L01() ;StartUART();Delay(6000);while(1){SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)){LED=0;temp++;for(i=0;i<32;i++){R_S_Byte(RxBuf[i]);Delay(600);}}LED=1;Delay(600);}}#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义sbit MISO =P1^5;sbit MOSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//************************************按键sbit KEY1=P3^4;//************************************蜂明器sbit LED=P3^5;//***********************************发送缓冲区uchar TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; ////*********************************************NRF24L01*********************** #define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//*****************************************************************************uint 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; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送}/**************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/******************/uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSI uchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/********************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication... SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*******************//*功能:NRF24L01读写寄存器函数/*********************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*********************//*函数: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 tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(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)/*功能: 用于写数据:为寄存器地址,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; //关闭SPIreturn(status); //}/********************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/**********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收inerDelay_us(130); //延时不能太短}/**********************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/***********************/unsigned char 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 bufferrevale =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,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************主函数void main(void){uchar temp =0;init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataDelay(6000);P0=0xBF;{nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer data LED=0;Delay(10000); //可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}}。

NRF24L01的发送与接收程序

NRF24L01的发送与接收程序

#include <> #include <>typedef unsigned char uchar;typedef unsigned char uint;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1;SCK = 1;uchar |= MISO; then set SCK low again}return(uchar); .SPI_RW(reg);reg_val = SPI_RW(0); then read registervalueCSN = 1; and write value to it..CSN = 1; // CSN high again/* 函数: 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 return(status); }// return nRF24L01 status ucharstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(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)/* 功能: 用于写数据:为寄存器地址,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; // 关闭SPIreturn(status); ///********************//* 函数:void SetRX_Mode(void)/* 功能:数据接收配置/**********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); 接收CE = 1;inerDelay_us(130); // 延时不能太短}/**********************//* 函数: unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/* 功能:数据读取后放如 rx_buf 接收缓冲区中/***********************/unsigned char 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 frombuffer// IRQ 收发完成中断响应, 16 位 CRC,主 FIFOSPI_RW_Reg(WRITE_REG+STATUS,sta); // 接收到数据后RX_DR,TX_DS,MAX_P都置高为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, OxOe); // IRQ 收发完成中断响应,16 位CRC 主发送CE=1; //置高CE激发数据发送inerDelay_us(1O);}//************************************ void main(void){uchar temp =O;init_NRF24LO1() ;nRF24LO1_TxPacket(TxBuf);Delay(6OOO);PO=OxBF;主函数// Transmit Tx buffer datawhile(1)nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataLED=0;Delay(10000); // 可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}。

nrf24l01的收发信号资料

nrf24l01的收发信号资料

2014无线电电子设计大赛题目:NRF24L01的收发信号队号:三个烙铁匠队员:王晖曹恒万东胜摘要随着现代电子技术的飞速发展,通信技术也取得了长足的进步。

在无线通信领域,越来越多的通信产品大量涌现出来。

但设计无线数据传输产品往往需要相当的无线电专业知识和价格高昂的专业设备,因而影响了用户的使用和新产品的开发。

nRF24L01是一个为433MHz ISM频段设计的无线收发芯片,它为短距离无线数据传输应用提供了较好的解决办法, 使用nRF24L01降低了开发难度,缩短了开发周期,使产品能更快地推向市场。

本文提出了一种应用于无线数据收发系统的设计思路及实现方案,给出了基于无线射频芯片nRF24L01和STC89C52单片机的无线数据传输模块的设计方法,详细分析了各部分实现原理,并对系统的传输距离、传输数据的正确性进行了测试。

试验表明,该系统性能稳定,具有较强的抗干扰能力,有较强的实用价值。

关键词:无线通信;无线数据传输模块;单片机;射频AbstractWith the rapid development of modern electronic technology, communication technology has also made great progress. In the field of wireless communication, more and more communication products have sprung up in large quantities. But the design of wireless data transmission products often require considerable radio of the high price of professional knowledge and professional equipment, thus affecting the user's use and development of new products. NRF24L01 is a designed for 433 MHZ ISM band wireless transceiver chip, it for the short distance wireless data transmission application provides a better solution, using nRF24L01 reduces the development difficulty, shorten the development cycle, can make the product to market faster. This paper puts forward a kind of applied to wireless data transceiver system design idea and implementation scheme, and is given based on wireless rf chip nRF24L01 and STC89C52 single-chip wireless data transmission module, the design method of the realization principle of each part are analyzed in detail, and the transmission distance of the system, the correctness of the data transmission was tested. Tests show that the system performance is stable, stronganti-interference ability, a strong practical value.Keywords:Wireless communication;Wireless data transmission module;Single chip microcomputer;Radio frequency目录前言 (1)1系统设计 (1)1.1系统设计 (2)1.2实现过程 (2)2系统组成 (3)2.1 射频收发控制模块 (3)2.1.1 无线收发芯片nRF24L01介绍 (3)2.1.2 稳压部分 (5)2.2单片机控制部分 (5)2.2.1 STC89C52RC功能介绍 (6)2.2.2 内部结构 (6)2.2.3 串口通信 (8)2.3 显示部分 (9)3软件设计 (10)3.1 主程序流程图 (11)3.2 数据收发子程序流程图 (11)4测试结果及分析 (12)4.1 硬件电路测试 (13)4.2 系统测试 (13)4.2.1 测试方法 (13)4.2.2 功能测试及分析 (13)5结论 (14)6参考文献 (15)附录1:无线发射系统电路图 (16)附录 2:发送程序 (17)前言伴随着短距离、低功率无线数据传输技术的成熟,无线数据传输被越来越多地应用到新的领域。

nRF24L01的工作原理

nRF24L01的工作原理

nRF24L01的工作原理nRF24L01是一款低功耗的2.4GHz无线收发器,广泛应用于无线通信领域。

它采用射频芯片nRF24L01+和微控制器相结合的方式,可以实现无线数据传输和接收功能。

本文将详细介绍nRF24L01的工作原理及其相关技术参数。

一、nRF24L01的基本结构nRF24L01由射频芯片和微控制器组成,射频芯片负责无线通信的收发功能,而微控制器则负责控制和处理数据。

1. 射频芯片nRF24L01射频芯片是一款集成度高、性能稳定的射频收发器。

它支持2.4GHz 频段,采用GFSK调制方式,具有快速的数据传输速率和较低的功耗。

射频芯片包含了射频收发器、调制解调器、频率合成器等功能模块,能够实现无线通信的基本功能。

2. 微控制器nRF24L01通常与微控制器相结合使用,常见的微控制器有Arduino、STM32等。

微控制器负责控制射频芯片的工作模式、发送和接收数据的处理,以及与其他设备的交互等功能。

二、nRF24L01的工作模式nRF24L01具有多种工作模式,包括发送模式、接收模式和待机模式等。

下面将详细介绍每种工作模式的特点和工作原理。

1. 发送模式在发送模式下,nRF24L01将数据发送给接收端。

发送模式的工作原理如下:- 设置发送端的地址和通信频道。

- 将待发送的数据写入发送缓冲区。

- 发送端开始发送数据,nRF24L01将数据通过射频信号发送出去。

- 发送完毕后,发送端等待接收端的应答信号。

2. 接收模式在接收模式下,nRF24L01接收来自发送端的数据。

接收模式的工作原理如下:- 设置接收端的地址和通信频道。

- 接收端开始监听射频信号,并等待发送端发送数据。

- 当接收端接收到数据时,nRF24L01将数据写入接收缓冲区。

- 接收端可以通过读取接收缓冲区中的数据进行进一步处理。

3. 待机模式在待机模式下,nRF24L01处于低功耗状态,仅保持最基本的功能。

待机模式的工作原理如下:- nRF24L01关闭射频发送和接收功能,以降低功耗。

nRF24L01的工作原理

nRF24L01的工作原理

nRF24L01的工作原理nRF24L01是一款低功耗、高性能的2.4GHz无线收发器,广泛应用于无线通信领域。

它采用了射频(RF)技术,能够在无线环境中进行数据传输和通信。

工作频率:nRF24L01的工作频率为2.4GHz,采用ISM频段(工业、科学和医疗),这个频段是无线设备可以自由使用的频段之一。

它提供了多个可选的通信信道,以避免与其他无线设备的干扰。

工作模式:nRF24L01可以在两种不同的工作模式下进行操作:发射模式和接收模式。

1. 发射模式:在发射模式下,nRF24L01将待发送的数据加载到发送缓冲区,并通过射频信号将数据传输到接收端。

发送器会不断尝试发送数据,直到成功发送或者达到最大重试次数。

它还具有自动重传和自动应答功能,以确保数据的可靠传输。

2. 接收模式:在接收模式下,nRF24L01通过接收缓冲区接收从发送器发送过来的数据。

接收器会检查接收到的数据的完整性和准确性,并通过SPI接口将数据传输给主控制器进行进一步处理。

通信协议:nRF24L01使用了一种称为Enhanced ShockBurst™的协议,它是一种高效的无线通信协议。

该协议具有自动重传和自动应答的功能,能够在低功耗下实现可靠的数据传输。

它还支持多通道和多设备的通信,可以实现多个无线设备之间的互联。

射频特性:nRF24L01具有出色的射频特性,包括调制方式、发射功率和接收灵敏度等。

它支持GFSK调制方式,能够在不同的传输速率下进行数据传输。

发射功率可根据需求进行调整,以平衡传输距离和功耗。

接收灵敏度高,能够接收到较弱的信号。

硬件接口:nRF24L01通过SPI(串行外设接口)与主控制器进行通信。

SPI接口提供了数据传输、时钟同步和控制信号等功能。

此外,nRF24L01还提供了一些额外的引脚,用于配置和控制模块的工作模式和参数。

应用领域:nRF24L01广泛应用于无线通信领域,包括无线传感器网络、智能家居、远程控制、无线游戏手柄、无线键盘鼠标等。

NRF24L01无线模块收发程序(实测成功多图)

NRF24L01无线模块收发程序(实测成功多图)

NRF24L01无线模块收发程序(实测成功多图)本模块是NRF24L01无线传输模块,用于无线传输数据,距离不远,一般只是能够满足小距离的传输,目测是4-5m,价格一般是4元左右,可以方便的买到。

51最小系统学习板就可以,当时是用了两块学习板,一块用于发送,一块用于接收。

小车也是比较容易购到的,四个端口控制两个电机,两个控制一个电机,当两个端口高低电平不同时电机就会转动,即为赋值1和0是电机转动,赋值可以用单片机作用,当然这是小车启动部分,前进后退左转右转就是你赋值0和1的顺序问题了。

整体思路是用发射端的按键控制小车,即为按键按下就前进,再按其他按键实现其他功能,本次程序是在用NRF24L01发射数据在接收端用1602显示的基础上改变。

下面是程序源码(有好几个文件,分别创建)1.//////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////2.#include3.4.#include5.6.#include'1602.h'7.#include'delay.h'8.#include 'nrf24l01.h'9.#define uint unsigned int10.#define uchar unsigned char11.uint Weight_Shiwu=1234;12.unsigned char KeyScan(void);//键盘扫描13.// unsigned char KeyScan(void);//键盘扫描14.15.//#define KeyPort P016.sbit KEY1 = P0^0;17.sbit KEY2 = P0^1;18.sbit KEY3 = P0^2;19.sbit KEY4 = P0^3;20.sbit KEY5 = P0^4;21.void main()22.{23.// char TxDate[4];24.// LCD_Init(); //初始化液晶屏25.// LCD_Clear(); //清屏26.// NRF24L01Int(); //初始化LCD160227.// LCD_Write_String(4,0,'welcome');28.while(1)29.{30.KeyScan();31.32.}33.}34.35.36.37.38.unsigned char KeyScan(void)39.{40./******************************************************** /42.{43.if(!KEY1) //如果检测到低电平,说明按键按下44.{45.DelayMs(10); //延时去抖,一般10-20ms46.if(!KEY1) //再次确认按键是否按下,没有按下则退出47.{48.while(!KEY1);//如果确认按下按键等待按键释放,没有则退出49.{50.TxDate[0] = 1;//向左转51.TxDate[1] = 0;52.TxDate[2] = 1;53.TxDate[3] = 1;54.NRFSetTxMode(TxDate);//发送数据·55.while(CheckACK()); //检测是否发送完毕56.}57.}58.}59./******************************************************** /60.else if(!KEY2) //如果检测到低电平,说明按键按下61.{62.DelayMs(10); //延时去抖,一般10-20ms63.if(!KEY2) //再次确认按键是否按下,没有按下则退出64.{65.while(!KEY2);//如果确认按下按键等待按键释放,没有则退出66.{67.TxDate[0] = 1;//向右转69.TxDate[2] = 1;70.TxDate[3] = 0;71.NRFSetTxMode(TxDate);//发送数据72.while(CheckACK()); //检测是否发送完毕73.}74.}75.}76./******************************************************** /77.else if(!KEY3) //如果检测到低电平,说明按键按下78.{79.DelayMs(10); //延时去抖,一般10-20ms80.if(!KEY3) //再次确认按键是否按下,没有按下则退出81.{82.while(!KEY3);//如果确认按下按键等待按键释放,没有则退出83.{84.TxDate[0] = 1;//前进85.TxDate[1] = 0;86.TxDate[2] = 1;87.TxDate[3] = 0;88.NRFSetTxMode(TxDate);//发送数据89.while(CheckACK()); //检测是否发送完毕90.}91.}92.}93./******************************************************** /94.else if(!KEY4) //如果检测到低电平,说明按键按下96.DelayMs(10); //延时去抖,一般10-20ms97.if(!KEY4) //再次确认按键是否按下,没有按下则退出98.{99.while(!KEY4);//如果确认按下按键等待按键释放,没有则退出100.{101.TxDate[0] = 0;//后退102.TxDate[1] = 1;103.TxDate[2] = 0;104.TxDate[3] = 1;105.NRFSetTxMode(TxDate);//发送数据106.while(CheckACK()); //检测是否发送完毕107.}108.}109.}110.else if(!KEY5)111.{112.DelayMs(10);113.if(!KEY5)114.{115.while(!KEY5)116.{117.TxDate[0] = 1;118.TxDate[1] = 1;119.TxDate[2] = 1;120.TxDate[3] = 1;121.NRFSetTxMode(TxDate);122.while(CheckACK());123.}125.}126.}127.}1.//////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////2.#include3.4.#include5.6.#include'1602.h'7.#include'delay.h'8.#include 'nrf24l01.h'9.#define uint unsigned int10.#define uchar unsigned char11.uint Weight;12.sbit a = P2^0;13.sbit b = P2^1;14.sbit c = P2^2;15.sbit d = P2^3;16.void main()17.{18.LCD_Init(); //初始化液晶屏19.LCD_Clear(); //清屏20.*(RevTempDate+4)=*\0*;21.NRF24L01Int();22.while(1)23.{25.NRFSetRXMode();//设置为接收模式26.GetDate();//开始接受数;27.//Weight=RevTempDate[0]*1000+RevTempDate[1]*100+RevTemp Date[2]*10+RevTempDate[3];28.LCD_Write_Char(7,0,RevTempDate[0]+0x30);29.LCD_Write_Char(8,0,RevTempDate[1]+0x30);30.LCD_Write_Char(9,0,RevTempDate[2]+0x30);31.LCD_Write_Char(10,0,RevTempDate[3]+0x30);32. a = RevTempDate[0];//根据接受数据来设置高低电平(目测仅限传输1.0两种数值)33. b = RevTempDate[1];34. c = RevTempDate[2];35. d = RevTempDate[3];36.}37.}38.39.///////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////1.#include2.3.#include 'nrf24l01.h'4.#define uchar unsigned char5.#define uint unsigned int6.sbit IRQ =P1^2;//输入7.sbit MISO =P1^3; //输入8.sbit MOSI =P1^1;//输出9.sbit SCLK =P1^4;//输出10.sbit CE =P1^5;//输出11.sbit CSN =P1^0;//输出12.uchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址13./*****************状态标志*****************************************/14.uchar bdata sta; //状态标志15.sbit RX_DR=sta^6;16.sbit TX_DS=sta^5;17.sbit MAX_RT=sta^4;18./*****************SPI时序函数******************************************/19.uchar NRFSPI(uchar date)20.{21.uchar i;22.for(i=0;i<8;i++)>23.{24.if(date&0x80)25.MOSI=1;26.else27.MOSI=0; // byte最高位输出到MOSI28.date<=1;>29.SCLK=1;30.if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据31.date|=0x01; // 读MISO到byte最低位32.SCLK=0; // SCK置低33.}34.return(date); // 返回读出的一字节35.}36./**********************NRF24L01初始化函数*******************************/37.void NRF24L01Int()38.{39.DDelay(2);//让系统什么都不干40.CE=0; //待机模式141.CSN=1;42.SCLK=0;43.IRQ=1;44.}45./*****************SPI读寄存器一字节函数*********************************/46.uchar NRFReadReg(uchar RegAddr)47.{48.uchar BackDate;49.CSN=0;//启动时序50.NRFSPI(RegAddr);//写寄存器地址51.BackDate=NRFSPI(0x00);//写入读寄存器指令52.CSN=1;53.return(BackDate); //返回状态54.}55./*****************SPI写寄存器一字节函数*********************************/56.uchar NRFWriteReg(uchar RegAddr,uchar date)57.{58.uchar BackDate;59.CSN=0;//启动时序60.BackDate=NRFSPI(RegAddr);//写入地址61.NRFSPI(date);//写入值62.CSN=1;63.return(BackDate);64.}65./*****************SPI读取RXFIFO寄存器的值********************************/66.uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen)67.{ //寄存器地址//读取数据存放变量//读取数据长度//用于接收68.uchar BackDate,i;69.CSN=0;//启动时序70.BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址71.for(i=0;i72.{73.RxDate[i]=NRFSPI(0);74.}75.CSN=1;76.return(BackDate);77.}78./*****************SPI写入TXFIFO寄存器的值**********************************/79.uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen)80.{ //寄存器地址//写入数据存放变量//读取数据长度//用于发送81.uchar BackDate,i;82.CSN=0;83.BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址84.for(i=0;i85.{86.NRFSPI(*TxDate++);87.}88.CSN=1;89.return(BackDate);90.}91./*****************NRF设置为发送模式并发送数据******************************/92.void NRFSetTxMode(uchar *TxDate)93.{//发送模式94.CE=0;95.NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_A DDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度96.NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同97.NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WIT DH);//写入数据98./******下面有关寄存器配置**************/99.NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答100.NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0101.NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次102.NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40103.NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益104.NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电105.CE=1;106.DDelay(5);//保持10us秒以上107.}108./*****************NRF设置为接收模式并接收数据******************************/109.//主要接收模式110.void NRFSetRXMode()111.{112.CE=0;113.NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址114.NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答115.NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0116.NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40117.NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WIT DH); // 接收通道0选择和发送通道相同有效数据宽度118.NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益*/119.NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式120.CE = 1;121.DDelay(5);//保持10us秒以上122.}123./****************************检测应答信号******************************/124.uchar CheckACK()125.{ //用于发射126.sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器127.if(TX_DS||MAX_RT) //发送完毕中断128.{129.NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志130.CSN=0;131.NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!不然会出现意想不到的后果大家记住!!132.CSN=1;133.return(0);134.}135.else136.return(1);137.}138./******************判断是否接收收到数据,接到就从RX 取出*********************/139.//用于接收模式140.uchar NRFRevDate(uchar *RevDate)141.{142.uchar RevFlags=0;143.sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器144.if(RX_DR) // 判断是否接收到数据145.{146.CE=0; //SPI使能147.NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WI TDH);// 从RXFIFO读取数据148.RevFlags=1; //读取数据完成标志149.}150.NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标151.return(RevFlags);152.}153.void DDelay(uint t)154.{155.uint x,y;156.for(x=t;x>0;x--)157.for(y=110;y>0;y--);158.}159.///////////////////////////////////////////////////////////// ///////////////////////////////////////////1.#include 'delay.h'2./*------------------------------------------------延时函数,含有输入参数 unsigned char t,无返回值4.unsigned char 是定义无符号字符变量,其值的范围是5.0~255 这里使用晶振12M,精确延时请使用汇编,大致延时6.长度如下 T=tx2+5 uS7.------------------------------------------------*/8.void DelayUs2x(unsigned char t)9.{10.while(--t);11.}12./*------------------------------------------------13.mS延时函数,含有输入参数 unsigned char t,无返回值14.unsigned char 是定义无符号字符变量,其值的范围是15.0~255 这里使用晶振12M,精确延时请使用汇编16.------------------------------------------------*/17.void DelayMs(unsigned char t)18.{19.20.while(t--)21.{22.//大致延时1mS23.DelayUs2x(245);24.DelayUs2x(245);25.26.}27.}28.///////////////////////////////////////////////////////////// //////////////////////////////1.下面是接收的NRF24L01的程序。

nRF24L01的工作原理

nRF24L01的工作原理

nRF24L01的工作原理引言概述:nRF24L01是一种低功耗、高性能的2.4GHz无线收发器,广泛应用于无线通信领域。

本文将详细介绍nRF24L01的工作原理,包括射频通信、调制解调、数据包传输、频道选择和功耗控制等方面。

一、射频通信1.1 发射端工作原理nRF24L01的发射端通过内置的射频发射器将数据转换为无线信号进行传输。

工作时,发射端将待发送的数据通过SPI接口发送给nRF24L01,然后nRF24L01将数据进行编码和调制处理,并将其转换为射频信号发送出去。

1.2 接收端工作原理nRF24L01的接收端通过内置的射频接收器接收从发射端发送过来的无线信号,并将其转换为可供处理的数据。

接收端将接收到的信号进行解调和解码处理,然后通过SPI接口将数据发送给主控制器进行进一步处理。

1.3 射频通信特点nRF24L01采用2.4GHz的ISM频段进行通信,具有抗干扰能力强、传输距离远、传输速率高等特点。

同时,nRF24L01支持多频道选择,可以实现多设备同时工作而互不干扰。

二、调制解调2.1 调制原理nRF24L01采用GFSK调制方式,即高斯频移键控调制。

在调制过程中,nRF24L01将数字信号转换为模拟信号,并通过改变信号的频率来表示不同的数据。

2.2 解调原理nRF24L01的接收端通过解调将接收到的模拟信号转换为数字信号,以便后续处理。

解调过程中,nRF24L01通过检测信号的频率变化来还原原始的数字信号。

2.3 调制解调性能nRF24L01的调制解调性能优良,能够实现高效的数据传输。

其采用的GFSK 调制方式具有抗干扰能力强、传输速率高等优点,能够在复杂的无线环境中稳定传输数据。

三、数据包传输3.1 数据包格式nRF24L01的数据包由多个字节组成,包括数据长度、地址、校验和等信息。

数据包格式的设计使得nRF24L01能够实现可靠的数据传输和错误检测。

3.2 传输协议nRF24L01支持多种传输协议,包括主从模式、广播模式和自动应答模式等。

51单片机控制nRF24L01收发数据程序

51单片机控制nRF24L01收发数据程序

51单片机控制nRF24L01收发数据程序#include#includetypedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义***************************************sbit M ISO =P1^3;sbit M OSI =P1^4;sbit SCK =P1^2;sbit CE =P1^1;sbit CSN =P3^2;sbit IRQ =P3^3;//************************************按键***************************************************sbit KEY1=P3^6;sbit KEY2=P3^7;//************************************数码管位选*********************************************sbit led0=P2^0;sbit led1=P2^1;sbit led2=P2^2;sbit led3=P2^3;//***********************************数码管0-9编码*******************************************//自己uchar seg[10]={0xC0,0xCF,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0~~9编码//*********************************************NRF24L01************************ *************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 20 // 20 uints TX payload#define RX_PLOAD_WIDTH 20 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接受地址//***************************************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 // 冲洗接受虵IFO指令#define REUSE_TX_PL 0xE3 // 定义重装载数据指令#define NOP 0xFF // 保留//*************************************SPI(nRF24L01)寄存器地址****************************************************#define CONFIG 0x00#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#define RX_ADDR_P1 0x0B#define RX_ADDR_P2 0x0C#define RX_ADDR_P3 0x0D#define RX_ADDR_P4 0x0E#define RX_ADDR_P5 0x0F#define TX_ADDR 0x10#define RX_PW_P0 0x11#define RX_PW_P1 0x12#define RX_PW_P2 0x13#define RX_PW_P3 0x14#define RX_PW_P4 0x15#define RX_PW_P5 0x16#define FIFO_STATUS 0x17//************************************************************* **************** *********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);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时*****************************************void Delay(unsigned int s){unsigned int i;for(i=0; i<="" p="">for(i=0; i<="" p="">}//************************************************************* **************** *************uint 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; // chip enableCSN=1; // Spi disableSCK=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);SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);SPI_RW_Reg(WRITE_REG + RF_CH, 0);SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);}/************************************************************** **************** **********************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序序/************************************************************** **************************************/uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/************************************************************** **************** **********************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/************************************************************** **************** **********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/************************************************************** **************** **********************//*功能:NRF24L01读写寄存器函数/************************************************************** **************** **********************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/************************************************************** **************** **********************//*函数: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 tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)<bdsfid="230" p=""></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)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************** ************ ***************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,uchar_ctr;CSN = 0;status = SPI_RW(reg);for(uchar_ctr=0; uchar_ctr<="">SPI_RW(*pBuf++);CSN = 1;return(status);}/************************************************************** **************** **********************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/************************************************************** **************** **********************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);CE = 1;inerDelay_us(130);}/************************************************************** **************** ************************//*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)/*功能:数据读取后如rx_buf接受缓冲区中/************************************************************** **************** ************************/unsigned char nRF24L01_RxPacket(unsigned char* rx_buf) {unsigned char revale=0;sta=SPI_Read(STATUS);if(RX_DR){CE = 0;SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);revale =1;}SPI_RW_Reg(WRITE_REG+STATUS,sta);return revale;}/************************************************************** **************** *****************************/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送tx_buf中数据/************************************************************** **************** ****************************/void nRF24L01_TxPacket(unsigned char * tx_buf){CE=0;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);CE=1;inerDelay_us(10);}//************************************主函数*********************************************************** void main(void){unsigned char tf =0;unsigned char TxBuf[20]={0};unsigned char RxBuf[20]={0};init_NRF24L01() ;led2=0;led3=0;led0=0;led1=0;// P0=0x00;TxBuf[1] = 1 ;TxBuf[2] = 1 ;nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer data Delay(6000);// P0=0xBF;while(1){if(KEY1 ==0 ){led2=1;//自己P0=seg[1];TxBuf[1] = 1 ;tf = 1 ;}if(KEY2 ==0 ){//自己P0=seg[2];led3=1;TxBuf[2] =1 ;tf = 1 ;if (tf==1){nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataTxBuf[1] = 0x00;TxBuf[2] = 0x00;tf=0;Delay(1000);}//************************************************************* **************** ******************SetRX_Mode();nRF24L01_RxPacket(RxBuf);if(RxBuf[1]|RxBuf[2]){if( RxBuf[1]==1){led0=1;//ziji P0=seg[3];}if( RxBuf[2]==1){led1=1;//ziji P0=seg[4];}Delay(1000);}RxBuf[1] = 0x00;RxBuf[2] = 0x00;}。

NRF24L01接收程序

NRF24L01接收程序

/*************************************************头文件:NRF24L01.h**文件名: NRF24L01.c**创建人: 动车组**日期: 2012-8-21**功能描述:用NRF24L01发送一定字节数的数据或者接收数据**占用资源:四位控制SPI总线的IO线和1位NRF24L01模式控制引脚** 占用一个中段***********************************************/#include"nrf24l01.h"uchar code TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uchar code RX_ADDRESS_0[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//为了应答接收设备,接收通道0地址和发送地址相同//uchar code RX_ADDRESS_1[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道1地址//通道1-5最有最低字节不一样//uchar code RX_ADDRESS_2[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道2地址//且写地址的时候是低字节先写//uchar code RX_ADDRESS_3[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道3地址//uchar code RX_ADDRESS_4[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道4地址//uchar code RX_ADDRESS_5[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01};//接收通道5地址bit RX_OK = 0; //接收数据完成标志,在中断中置位bit TX_OK = 1; //数据发送完毕标志,在中断置位由于第一次要可以发送所以初值为1bit MAX_RT_OK=0; //发送次数超过设置的次数的标志在中断置位uchar bdata sta = 0x00; //状态标志sbit RX_DR =sta^6;sbit TX_DS =sta^5;sbit MAX_RT =sta^4;/************************************以下是SPI的读写函数*********************************************//****************************************************************************** **********************/*函数:uchar SPI_RW(uchar date)/*功能:SPI一个字节写时序/****************************************************************************** **********************/uchar SPI_RW(uchar byte){SCK = 0;for(i=0; i<8; i++) // 循环8次{MOSI = (byte & 0x80); // byte最高位输出到MOSIbyte <<= 1; // 低一位移位到最高位SCK = 1; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据byte |= MISO; // 读MISO到byte最低位SCK = 0; // SCK置低}return(byte); // 返回读出的一字节}/****************************************************************************** **********************/*函数:uchar SPI_Read(uchar reg)/*功能:SPI 从reg中读出一个字节时序/****************************************************************************** **********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器reg_val = SPI_RW(0); // 然后从该寄存器读数据CSN = 1; // CSN拉高,结束数据传输return(reg_val); // 返回寄存器数据}/****************************************************************************** **********************//*功能:SPI 在reg中写入数据value函数/****************************************************************************** **********************/void SPI_RW_Reg(uchar reg, uchar value){CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器,同时返回状态字SPI_RW(value); // 然后写数据到该寄存器CSN = 1; // CSN拉高,结束数据传输}/****************************************************************************** **********************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于SPI连读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出/****************************************************************************** **********************/void SPI_Read_Buf(uchar reg, uchar * pBuf, uchar bytes){uchar i;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; i<bytes; i++)pBuf[i] = SPI_RW(0); // 逐个字节从nRF24L01读出CSN = 1; // CSN拉高,结束数据传输}/****************************************************************************** ***************************/*函数:uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于SPI连写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数/****************************************************************************** ***************************/void SPI_Write_Buf(uchar reg, uchar * pBuf, uchar bytes){uchar i;CSN = 0; // CSN置低,开始传输数据SPI_RW(reg); // 选择寄存器,同时返回状态字for(i=0; i<bytes; i++)SPI_RW(pBuf[i]); // 逐个字节写入nRF24L01CSN = 1; // CSN拉高,结束数据传输}/*************************以下是nrf24l01的应用层函数*******************************************/void nrf_delay(){uint a=130*10;while(a--);}/*************************************************************************** NRF24L01初始化/**************************************************************************/ void init_NRF24L01(void){CE=0; // 待机// SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // 配置寄存器设置为接收模式SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 通道0自动ACK应答允许0x01SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有通道0,如果需要多频道可以参考Page21 0x01// SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03); // 收发地址宽度设置为5个字节SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x0a); // 等待250+86us 重发10次SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS_0, RX_ADR_WIDTH); // 为了应答接收设备,接收通道0地址和发送地址相同SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地发送地址SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节EX1=1; //开外部中断1IT1=1; //下降沿触发EA=1; //开总中断}/***************************************************************************/*设置模式:b为0时是发送模式为1时是接收模式*//**************************************************************************/ void Set_Mode(char b){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e+b); // IRQ收发完成中断响应,16位CRC ,主接收CE = 1; // 模式转换要等待130Usnrf_delay();}/****************************************************************************** *****************************/*函数:bit nRF24L01_TxPacket(unsigned char * tx_buf)/*功能:发送tx_buf中数据返回1数据发送/****************************************************************************** ****************************/bit nRF24L01_TxPacket(uchar * tx_buf){bit val=0;if(TX_OK){TX_OK=0;CE=0; //StandBy I模式SPI_RW_Reg(WRITE_REG+STATUS,sta); //发送完数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志// CSN = 0; // CSN置低,开始传输数据// SPI_RW(FLUSH_TX);//数据成功发送到了接收端,此时状态寄存器的TX_DS位置高并把数据从TX FIFO中清除掉//所以这里就不要再清除TX FIFO了// CSN = 1; // CSN置低,开始传输数据SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送CE=1; //置高CE,激发数据发送val = 1;}else if(MAX_RT_OK){MAX_RT_OK=0;SPI_RW_Reg(WRITE_REG+STATUS,sta); //发送完数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志CSN = 0; // CSN置低,开始传输数据SPI_RW(FLUSH_TX); //MAX_RT位置高,不清除TX FIFO 中的数据所以这里要清除TX FIFOCSN = 1;TX_OK=1;}return val;}/****************************************************************************** ************************//*函数:bit nRF24L01_RxPacket(uchar* rx_buf)/*功能:数据读取后放如rx_buf接收缓冲区中/****************************************************************************** ************************/bit nRF24L01_RxPacket(uchar* rx_buf){bit revale=0;if(RX_OK) // 判断是否接收到数据{RX_OK=0; //接收数据标志清零CE = 0; //SPI使能SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO bufferSPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志CSN = 0; // CSN置低,开始传输数据SPI_RW(FLUSH_RX); //用于清空FIFO !!CSN = 1; // CSN置低,开始传输数据revale =1; //读取数据完成标志Set_Mode(1); //重新设置为接收模式}return revale;}/*NRF24L01 IRQ引脚产生的中断函数*/void Int_1() interrupt 2{sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况if(RX_DR) //接收到数据了RX_OK=1;if(TX_DS) //数据发送完毕TX_OK=1;if(MAX_RT)MAX_RT_OK=1;}/**************************************************//*************************************************文件名: NRF24L01.h**创建人: 动车组**日期: 2012-8-21**功能描述:用NRF24L01发送一定字节数的数据或者接收数据**占用资源:四位控制SPI总线的IO线和1位NRF24L01模式控制引脚** 占用一个中段***********************************************/#ifndef __NRF24L01_H__#define __NRF24L01_H__#include <REG52.H>#define uint unsigned int#define uchar unsigned char//********************SPI 引脚号********************************sbit M ISO=P1^6; // 7 主入从出sbit SCK =P1^7; // 5 SPI 时钟由主机产生sbit CSN =P3^7; // 4 SPI使能为1时SPI禁止sbit MOSI=P1^5; // 6 主出从入//********************NRF24L01引脚*********************sbit CE =P3^6;sbit IRQ =P3^3; //中断引脚#define TX_PLOAD_WIDTH 32 // 发送字节数在这里设置发送和接收要一样#define RX_PLOAD_WIDTH 32 // 接收字节数在这里设置void init_NRF24L01(void); //NRF24L01初始化已经中断初始化了void Set_Mode(char b);///*设置模式:b为0时是发送模式为1时是接收模式*/bit nRF24L01_TxPacket(uchar * tx_buf);//发送tx_buf中数据返回1数据发送bit nRF24L01_RxPacket(uchar* rx_buf) ;//返回1时数据读取后放如rx_buf接收缓冲区中否则没有数据#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width//***************************************NRF24L01寄存器指令**********************************#define READ_REG 0x00 // 读寄存器指令/**************************************************000A AAAA 读配置寄存器;AAAAA 指出读操作的寄存器地址**************************************************/#define WRITE_REG 0x20 // 写寄存器指令/****************************************************************************** **************001A AAAA 写配置寄存器;AAAAA 指出写操作的寄存器地址只有在掉电模式和待机模式下可操作******************************************************************************* **************/#define RD_RX_PLOAD 0x61 // 读取接收数据指令/****************************************************************************** **************0110 0001 读RX有效数据;1-32字节,读操作全部从字节0开始,当读RX有效数据完成后FIFO寄存器中有效数据被清除;应用于接收模式下******************************************************************************* **************/#define WR_TX_PLOAD 0xA0 // 写待发数据指令/****************************************************************************** ***************1010 0000 写TX有效数据,1-32字节写操作,从字节0开始;应用于发射模式下/****************************************************************************** ***************/#define FLUSH_TX 0xE1 // 冲洗发送FIFO指令/****************************************************************************** ***************1110 0001 清除TX FIFO 寄存器,应用于发射模式下*********************************************************************************************/#define FLUSH_RX 0xE2 // 冲洗接收FIFO指令/****************************************************************************** ***************1110 0010 清除RX FIFO 寄存器;应用于接收模式下.在传输应答信号过程中不应执行此指令,也就是说若传输应答信号过程中执行此指令的话,将使得应答信号不能被完整的传输******************************************************************************* **************/#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令/****************************************************************************** ***************1110 0011 重新使用上一包有效数据,当CE为高过程中数据包被不断的重新发射在发射数据包过程中必须禁止数据包重利用功能******************************************************************************* **************/#define NOP 0xFF // 保留/****************************************************************************** ***************1111 1111 空操作,可以用来读状态寄存器******************************************************************************* **************///*************************************SPI(nRF24L01)寄存器地址*******************************#define CONFIG 0x00 // 配置收发状态,CRC校验模式以及收发状态响应方式/****************************************************************************** ***************寄存器位复位值类型描述reserved 7 0 R/W 默认为0MASK_RX_DR 6 0 R/W 可屏蔽中断RX_RD,1:IRQ引脚不显示RX_RD中断;0:RX_RD中断产生时IRQ引脚电平为低MASK_TX_DS 5 0 R/W 可屏蔽中断TX_DS,1:IRQ引脚不显示TX_DS中断;0:TX_DS中断产生时IRQ引脚电平为低MASK_MAX_RT 4 0 R/W 可屏蔽中断MAX_RT,1:IRQ引脚不显示TX_DS 中断;0:MAX_RT中断产生时IRQ引脚电平为低EN_CRC 3 1 R/W CRC使能.如果EN_AA中任意一位为高,则EN_CRC强迫为高CRCO 2 0 R/W CRC 模式:‘0’-8 位CRC 校验;‘1’-16 位CRC 校验PWR_UP 1 0 R/W 1:上电;0:掉电PRIM_RX 0 0 R/W 1:接收模式0:发射模式******************************************************************************* **************/#define EN_AA 0x01 // 自动应答功能设置此功能禁止后可与nRF2401 通讯/****************************************************************************** ***************位7:6保留(00) 位5:0(11 1111):数据通道5-0自动应答允许******************************************************************************* **************/#define EN_RXADDR 0x02 // 可用信道设置接收地址允许/****************************************************************************** ***************位7:6保留(00) 位5:0(00 0011):接收数据通道5-0允许******************************************************************************* **************/#define SETUP_AW 0x03 // 收发地址宽度设置/****************************************************************************** ***************位7:2保留(0000 00) 位1:0(11):接收/发射地址宽度00:无效;01:三字节;10:四字节;11:五字节******************************************************************************* **************/#define SETUP_RETR 0x04 // 自动重发功能设置/****************************************************************************** ***************位7:4(0000) 自动重发延时= ((位7:4)+1)*250+86us延时时间是指一包数据发送完成到下一包数据开始发射之间的时间间隔位3:0(0011):自动重发计数自动重发(位3:0)次例如复位值是自动重发3次******************************************************************************* **************/#define RF_CH 0x05 // 工作频率设置/****************************************************************************** ***************位7保留(0) 位6:0(000 0010):设置nRF24L01 工作通道频率******************************************************************************* **************/#define RF_SETUP 0x06 // 射频寄存器/****************************************************************************** ***************位7:5保留(000) 位4(0):PLL_LOCK 允许;仅应用于测试模式位3(1): 数据传输率:‘0’–1Mbps ‘1’2 Mbps位2:1保留(11) 发射功率:00-18dBm 01-12dBm 10-6dBm 11 0dBm 位0(1) 低噪声放大器增益******************************************************************************* **************/#define STATUS 0x07 // 状态寄存器/****************************************************************************** ***************寄存器位复位值类型描述Reserved 7 0 R/W 默认为0RX_DR 6 0 R/W 接收数据中断,当接收到有效数据后置一,写‘1’清除中断TX_DS 5 0 R/W 数据发送完成中断,当数据发送完成后产生中断.如果工作在自动应答模式下,只有当接收到应答信号后此位置一,写‘1’清除中断MAX_RT 4 0 R/W 达到最多次重发中断,写‘1’清除中断如果MAX_RT中断产生,则必须清除后系统才能进行通讯RX_P_NO 3:1 111 R 接收数据通道号000-101:数据通道号110:未使用111:RX FIFO 寄存器为空TX_FULL 0 0 R TX_FIFO寄存器满标志1:TX FIFO 寄存器满0: TX FIFO 寄存器未满,有可用空间******************************************************************************* **************/#define OBSERVE_TX 0x08 // 发送监测功能/****************************************************************************** ***************寄存器位复位值类型描述PLOS_CNT 7:4 0000 R 数据包丢失计数器,当写RF_CH 寄存器时此寄存器复位,当丢失15个数据包后此寄存器重启ARC_CNT 3:0 0000 R 重发计数器,发送新数据包时此寄存器复位******************************************************************************* **************/#define CD 0x09 // 地址检测载波检测/****************************************************************************** ***************寄存器位复位值类型描述Reserved 7:1 000000 RCD 0 0 R 载波检测******************************************************************************* **************/#define RX_ADDR_P0 0x0A // 频道0接收数据地址/****************************************************************************** ***************寄存器位复位值类型描述RX_ADDR_P0 39:0 0xE7E7E7E7E7 R/W 数据通道0接收地址最大长度5个字节先写低字节所写字节数量由SETUP_AW设定******************************************************************************* **************/#define RX_ADDR_P1 0x0B // 频道1接收数据地址 (0xC2C2C2C2C2)#define RX_ADDR_P2 0x0C // 频道2接收数据地址 (0xC2C2C2C2C3)#define RX_ADDR_P3 0x0D // 频道3接收数据地址 (0xC2C2C2C2C4)#define RX_ADDR_P4 0x0E // 频道4接收数据地址 (0xC2C2C2C2C5)#define RX_ADDR_P5 0x0F // 频道5接收数据地址(0xC2C2C2C2C6)#define TX_ADDR 0x10 // 发送地址寄存器先写低字节,在增强型ShockBurstTM模式下RX_ADDR_P0与此地址相等#define RX_PW_P0 0x11 // 接收频道0接收数据长度位7:6保留(00);(位5:0)个字节有效数据宽度(00 0000)#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接收数据长度同上#define FIFO_STATUS 0x17 // FIFO栈入栈出状态寄存器设置/****************************************************************************** ***************寄存器位复位值类型描述Reserved 7 0 R/W 默认为0TX_REUSE 6 0 R 若TX_REUSE=1,则当CE位高电平状态时,不断发送上一数据包TX_REUSE 通过SPI 指令REUSE_TX_PL 设置通过W_TX_PALOAD或FLUSH_TX 复位TX_FULL 5 0 R TX FIFO 寄存器满标志1:TX FIFO 寄存器满0: TX FIFO 寄存器未满有可用空间TX_EMPTY 4 1 R TX FIFO 寄存器空标志1:TX FIFO 寄存器空0: TX FIFO 寄存器非空Reserved 3:2 00 R/W 墨认为00RX_FULL 1 0 R RX FIFO 寄存器满标志1:RX FIFO 寄存器满0: RX FIFO 寄存器未满有可用空间RX_EMPTY 0 1 R RX FIFO 寄存器空标志1:RX FIFO 寄存器空0: RX FIFO 寄存器非空******************************************************************************* **************/#endif/****************************/#include <REG52.H>#include"C_Ko.h"#include"nrf24l01.h"#define uchar unsigned char#define uint unsigned intvoid main(){uchar tab[32];uchar i;UATR_Init(); //串口初始化init_NRF24L01(); //NRF24L01初始化已经中断初始化了Set_Mode(1); //为1时是接收模式*/while(1){if(nRF24L01_RxPacket(tab)){for(i=0;i<32;i++){Uatr_Print_Char(tab[i]);Uatr_Prints("\t\n");}}}}/***********串口程序在这里!/view/5282ded1195f312b3169a5a0.html?st=1 ***************/。

nRF24L01接收和发送的问题

nRF24L01接收和发送的问题

24L01是收发双方都需要编程的器件,这就对调试方法产生了一定的要求,如果两块一起调,那么通讯不成功,根本不知道是发的问题还是收的问题,不隐晦的说,我当时也是没理清调试思路才浪费了大半天时间看着模块干瞪眼。

正确的方法应该是先调试发送方,能保证发送正确,再去调接收,这样就可以有针对性的解决问题。

至于怎么去调发送方,先说下发送方的工作流程:•配置寄存器使芯片工作于发送模式后拉高CE端至少10us•读状态寄存器ST ATUS•判断是否是发送完成标志位置位•清标志•清数据缓冲网上的程序我也看过,大多都是成品,发送方发送-等应答-(自动重发)-触发中断。

可是这样的流程就已经把接收方给牵涉进来了,就是说一定要接收方正确收到数据并且回送应答信号之后发送方才能触发中断,结束一次完整的发送。

可是这跟我们的初衷不相符,我们想单独调试发送,完全抛开接收,这样就要去配置一些参数来取消自动应答,取消自动重发,让发送方达到发出数据就算成功的目的。

SPI_RW_Reg(WRITE_REG + EN_AA, 0x00); // 失能通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RX ADDR, 0x00); // 失能接收通道0SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00); // 失能自动重发(注:以下贴出的寄存器描述由于中文资料上有一个错误,故贴出原版英文资料)有了以上这三个配置,发送方的流程就变成了发送-触发中断。

这样就抛开了接收方,可以专心去调试发送,可是怎么样才知道发送是否成功呢,要用到另外两个寄存器,ST ATUS和FIFO_ST AT US。

这样就很清晰了,我们可以通过读取ST ATUS的值来判断是哪个事件触发了中断,寄存器4、5、6位分别对应自动重发完成中断,数据发送完成中断,数据接收完成中断。

也就是说,在之前的配置下,如果数据成功发送,那么ST ATUS的值应该为0x2e。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义sbit MISO =P1^5;sbit MOSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//************************************按键sbit KEY1=P3^4;//************************************蜂明器sbit LED=P3^5;//**************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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栈入栈出状态寄存器设置//*****************************************************************************voidDelay(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);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//*****************************************************************************uint 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; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC ,主接收}/******************************************************************************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/******************************************************************************uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/******************************************************************************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/******************************************************************************uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*****************************************************************************//*功能:NRF24L01读写寄存器函数/*****************************************************************************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*****************************************************************************//*函数: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 tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(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)/*功能: 用于写数据:为寄存器地址,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; //关闭SPIreturn(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接收缓冲区中/*****************************************************************************/unsigned char 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 bufferrevale =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,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************串口初始化void StartUART( void ){ //波特率4800SCON = 0x50;TMOD = 0x20;TH1 = 0xFA;TL1 = 0xFA;PCON = 0x00;TR1 = 1;}//************************************通过串口将接收到数据发送给PC端void R_S_Byte(uchar R_Byte){SBUF = R_Byte;while( TI == 0 ); //查询法TI = 0;}//************************************主函数void main(void){uchar i,temp;uchar RxBuf[32];init_NRF24L01() ;StartUART();Delay(6000);while(1){SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)){LED=0;temp++;for(i=0;i<32;i++){R_S_Byte(RxBuf[i]);Delay(600);}}LED=1;Delay(600);}}#include <reg52.h>#include <intrins.h>typedef unsigned char uchar;typedef unsigned char uint;//****************************************NRF24L01端口定义sbit MISO =P1^5;sbit MOSI =P1^1;sbit SCK =P1^6;sbit CE =P1^7;sbit CSN =P1^2;sbit IRQ =P1^0;//************************************按键sbit KEY1=P3^4;//************************************蜂明器sbit LED=P3^5;//***********************************发送缓冲区uchar TxBuf[32]={0x01,0x02,0x03,0x4,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x30,0x31,0x32,}; ////*********************************************NRF24L01***********************#define TX_ADR_WIDTH 5 // 5 uints TX address width#define RX_ADR_WIDTH 5 // 5 uints RX address width#define TX_PLOAD_WIDTH 32 // 20 uints TX payload#define RX_PLOAD_WIDTH 32 // 20 uints TX payloaduint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址//***************************************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);unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);void nRF24L01_TxPacket(unsigned char * tx_buf);//*****************************************长延时void Delay(unsigned int s){unsigned int i;for(i=0; i<s; i++);for(i=0; i<s; i++);}//*****************************************************************************uint 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; // chip enableCSN=1; // Spi disableSCK=0; // Spi clock line init highSPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // 写本地地址SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // 频道0自动ACK应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 允许接收地址只有频道0,如果需要多频道可以参考Page21SPI_RW_Reg(WRITE_REG + RF_CH, 0); // 设置信道工作为2.4GHZ,收发必须一致SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //设置发射速率为1MHZ,发射功率为最大值0dBSPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送}/**************/*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01的SPI写时序/******************/uint SPI_RW(uint uchar){uint bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit{MOSI = (uchar & 0x80); // output 'uchar', MSB to MOSIuchar = (uchar << 1); // shift next bit into MSB..SCK = 1; // Set SCK high..uchar |= MISO; // capture current MISO bitSCK = 0; // ..then set SCK low again}return(uchar); // return read uchar}/********************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01的SPI时序/********************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; // CSN low, initialize SPI communication...SPI_RW(reg); // Select register to read from..reg_val = SPI_RW(0); // ..then read registervalueCSN = 1; // CSN high, terminate SPI communicationreturn(reg_val); // return register value}/*******************//*功能:NRF24L01读写寄存器函数/*********************/uint SPI_RW_Reg(uchar reg, uchar value){uint status;CSN = 0; // CSN low, init SPI transactionstatus = SPI_RW(reg); // select registerSPI_RW(value); // ..and write value to it..CSN = 1; // CSN high againreturn(status); // return nRF24L01 status uchar}/*********************//*函数: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 tranactionstatus = SPI_RW(reg); // Select register to write to and read status ucharfor(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)/*功能: 用于写数据:为寄存器地址,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; //关闭SPIreturn(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接收缓冲区中/***********************/unsigned char 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 bufferrevale =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,主发送CE=1; //置高CE,激发数据发送inerDelay_us(10);}//************************************主函数void main(void){uchar temp =0;init_NRF24L01() ;nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataDelay(6000);P0=0xBF;while(1){nRF24L01_TxPacket(TxBuf); // Transmit Tx buffer dataLED=0;Delay(10000); //可变SPI_RW_Reg(WRITE_REG+STATUS,0XFF);LED=1;Delay(8000);}}。

相关文档
最新文档