NRF24L01无线模块收发程序例程

合集下载

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。

三、模块引脚说明四、模块与AT89S52单片机接口电路注:上图为示意连接,可根据自己实际需求进行更改;使用AT89S52MCU模块时,请将Nrf24L01通讯模块每个端口(MOSI、SCK、CSN和CE)接4.7K的排阻上拉到VCC增强其驱动能力(如下图:)。

nRF24L01无线模块6个接收通道_发送nRF24L01

nRF24L01无线模块6个接收通道_发送nRF24L01

nRF24L01无线模块6个接收通道_发送nRF24L01#include"nRF24L01.h"//uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x34,0x43,0x10,0x10,0x01}; // 定义一个静态发送地址uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0xb2,0xb2,0xb3,0xb4,0x01};//uchar code TX_ADDRESS[TX_ADR_WIDTH] = {0x02,0xb4,0xb3,0xb2,0xb1};uchar RX_BUF[TX_PLOAD_WIDTH];uchar TX_BUF[TX_PLOAD_WIDTH]={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,};uchar flag,status;uchar DATA = 0x01;uchar bdata sta;sbit RX_DR = sta^6;sbit TX_DS = sta^5;sbit MAX_RT = sta^4;/**************************************************//**************************************************函数: init_io()描述:初始化IO/**************************************************/ void init_io(void){CE = 0; // 待机CSN = 1; // SPI禁止SCK = 0; // SPI时钟置低IRQ = 1; // 中断复位LED = 0x00; // 关闭指示灯}/**************************************************//************************************************** 函数:delay_ms()描述:延迟x毫秒/**************************************************/ void delay_ms(uchar x){uchar i, j;i = 0;for(i=0; i{j = 250;while(--j);j = 250;while(--j);}}/**************************************************//**************************************************函数:SPI_RW()描述:根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节/**************************************************/uchar SPI_RW(uchar byte){uchar i;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); // 返回状态寄存器}/**************************************************//************************************************** 函数: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_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 接收设备接收通道0使用和发送设备相同的发送地址// SPI_Write_Buf(WRITE_REG + RX_ADDR_P1, RX_ADDRESS1, TX_ADR_WIDTH);// SPI_Write_Buf(WRITE_REG + RX_ADDR_P2, RX_ADDRESS2, TX_ADR_WIDTH);// SPI_RW_Reg(WRITE_REG + RX_PW_P1, TX_PLOAD_WIDTH);SPI_RW_Reg(WRITE_REG + EN_AA, 0x3f); // 使能接收通道0自动应答SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x3f); // 使能接收通道0SPI_RW_Reg(WRITE_REG + RF_CH, 40); // 选择射频通道0x40 SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // 接收通道0选择和发送通道相同有效数据宽度SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // CRC使能,16位CRC校验,上电,接收模式CE = 1; // 拉高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基于C51单片机双向通讯C语言程序(中文详解)

无线模块NRF24L01基于C51单片机双向通讯C语言程序(中文详解)

#include <reg52.h>#include <intrins.h>/********************************************************** *****************************//* NRF24L01 地管脚定义,以及在本程序中地应用,VCC接3.3V 电源,可以通过5V用电压转换芯片/*得到,NC 管脚可以接可以不接,暂时没用途.本程序应用于51或者52单片机,是两个模块进行通讯/*成功地简单指示,现象是:模块1地 KEY1 对应模块1地LED1 和模块2地LED3 ,模块1地 KEY2 对应模/*块1地LED2 和模块2地LED4,发过来也对应./********************************************************** *****************************/typedef unsigned char uchar;typedef unsigned char uint;/************************************NRF24L01端口定义***********************************/sbit NC =P2^0; //没用,不接也可sbit MISO =P2^5; //数字输出(从 SPI 数据输出脚)sbit MOSI =P2^4; //数字输入(从 SPI 数据输入脚)sbit SCK =P1^7; //数字输入(SPI 时钟)sbit CE =P2^1; //数字输入(RX 或 TX 模式选择)sbit CSN =P2^2; //数字输入(SPI片选信号)sbit IRQ =P2^6; //数字输入(可屏蔽中断)/************************************按键***********************************************/sbit KEY1=P3^3;//按键S1sbit KEY2=P3^2;//按键S2/************************************数码管位选******************************************/sbit led1=P1^0; //LED0sbit led2=P1^1; //LED1sbit led3 =P1^2; //LED2sbit led4 =P1^3; //LED3sbit led5 =P1^4; //LED4/*********************************************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 // 冲洗接收 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); //NRF24L01 初始化uint SPI_RW(uint dat); //根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01读出一字节uchar SPI_Read(uchar reg); //从reg寄存器读一字节void SetRX_Mode(void); //数据接收配置uint SPI_RW_Reg(uchar reg, uchar value); //写数据value到reg寄存器uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); //从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); //把pBuf缓存中地数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);//数据读取后放入rx_buf接收缓冲区中void nRF24L01_TxPacket(unsigned char * tx_buf);//发送 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; //RX_DR 为 sta 地第六位sbit TX_DS =sta^5; //TX_DS 为 sta 地第五位sbit MAX_RT =sta^4; //MAX_RT 为 sta 地第四位/********************************************************** ********************************//*延时函数/********************************************************** ********************************/void inerDelay_us(unsigned char n) //延时,us 级{for(;n>0;n--)_nop_();}/********************************************************** ******************************//*NRF24L01初始化/********************************************************** *****************************/void init_NRF24L01(void){inerDelay_us(100);CE=0; // 芯片使能CSN=1; // 禁止 SPISCK=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, 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,发射功率为最大值0dB}/********************************************************** ******************************************//*函数:uint SPI_RW(uint uchar)/*功能:NRF24L01地SPI写时序-----根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节/********************************************************** ******************************************/uint SPI_RW(uint dat){uint i;for(i=0;i<8;i++) // 循环8次{MOSI = (dat & 0x80); // dat地最高位输出到MOSI MSB to MOSIdat = (dat << 1); // 从右向左进一位shift next bit into MSB..SCK = 1; // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据Set SCK high..dat |= MISO; //读MISO到 dat 最低位 capture current MISO bitSCK = 0; // SCK置低..then set SCK low again}return(dat); //返回读出地一字节 return read dat}/********************************************************** ******************************************/*函数:uchar SPI_Read(uchar reg)/*功能:NRF24L01地SPI时序-----------从reg寄存器读一字节/********************************************************** ******************************************/uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0; //CSN置低,开始传输数据CSN low, initialize SPI communication...SPI_RW(reg); //选择寄存器 Select register to read from..reg_val = SPI_RW(0); //然后从该寄存器读数据 ..then read registervalueCSN = 1; //CSN拉高,结束数据传输CSN high, terminate SPI communicationreturn(reg_val); //返回寄存器数据 return register value}/********************************************************** ******************************************//*功能:NRF24L01读写寄存器函数/*描述:写数据value到reg寄存器/********************************************************** ******************************************/uint SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0; // CSN置低,开始传输数据CSN low, init SPI transactionstatus = SPI_RW(reg); // 选择寄存器,同时返回状态字select registerSPI_RW(value); // 然后写数据到该寄存器 ..and write value to it..CSN = 1; // CSN拉高,结束数据传输CSN high againreturn(status); // 返回状态寄存器 return nRF24L01 status uchar}/********************************************************** ******************************************//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars) /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据地个数/*描述: 从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址/********************************************************** ******************************************/uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,i;CSN = 0; //CSN置低,开始传输数据 Set CSN low, init SPI tranactionstatus = SPI_RW(reg); //选择寄存器,同时返回状态字Select register to write to and read status uchar for(i=0;i<uchars;i++)pBuf[i] = SPI_RW(0); //逐个字节从nRF24L01读出CSN = 1; //CSN拉高,结束数据传输return(status); //返回状态寄存器return nRF24L01 status uchar}/********************************************************** ***********************************************/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据地个数/*描述:把pBuf缓存中地数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址/********************************************************** ***********************************************/uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars){uint status,i;CSN = 0; //CSN置低,开始传输数据status = SPI_RW(reg); //选择寄存器,同时返回状态字inerDelay_us(10);for(i=0; i<uchars; i++)SPI_RW(*pBuf++); //逐个字节写入nRF24L01CSN = 1; //CSN拉高,结束数据传输return(status); //返回状态寄存器}/********************************************************** ******************************************//*函数:void SetRX_Mode(void)/*功能:数据接收配置/********************************************************** ******************************************/void SetRX_Mode(void){CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);//CRC使能,16位CRC 校验,上电,接收模式CE = 1; // 拉高CE启动接收设备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,激发数据发送}/************************************主函数*********************************************************** */void main(void){unsigned char tf =0;unsigned char TxBuf[20]={0}; // 要发送地数组unsigned char RxBuf[20]={0}; // 接收地数据数组init_NRF24L01() ; //模块初始化led1=1;led2=1;led3 =1;led4 =1; //led 灯关闭Delay(1000);while(1){if(KEY1 ==0 ) //按键 1 按下{TxBuf[1] = 1 ; //赋值tf = 1 ;led1=0; //本地led 灯闪烁led1=1;Delay(200);}if(KEY2 ==0 ) //按键 2 按下{TxBuf[2] =1 ; //赋值tf = 1 ;led2=0; //本地led 灯闪烁Delay(200);led2=1;Delay(200);}if (tf==1) //有键按下{nRF24L01_TxPacket(TxBuf); //发送数据 Transmit Tx buffer dataTxBuf[1] = 0x00; //清零TxBuf[2] = 0x00;tf=0;Delay(1000);}SetRX_Mode(); //设置成接受模式RxBuf[1] = 0x00; //接收地数组相应位清零RxBuf[2] = 0x00;Delay(1000);nRF24L01_RxPacket(RxBuf); //接收数据if(RxBuf[1]|RxBuf[2]){if( RxBuf[1]==1){led3=RxBuf[0];}if( RxBuf[2]==1){led4=RxBuf[4];}Delay(3000); //old is '1000'}RxBuf[1] = 0x00; //清零RxBuf[2] = 0x00;led3=1; //关灯led4=1;}}本程序存在地问题:反应不够灵敏,当在按键1和按键2之间切换地时候,对方地灯闪烁会有一定地延时,另外本程序没有消除按键地抖动.对部分函数地解释:uint SPI_RW(uint dat)最基本地函数,完成 GPIO模拟 SPI 地功能.将输出字节(MOSI)从 MSB 循环输出,同时将输入字节(MISO)从 LSB 循环移入.上升沿读入,下降沿输出. (从 SCK被初始化为低电平可以判断出)uchar SPI_Read(uchar reg); //从reg寄存器读一字节读取寄存器值地函数:基本思路就是通过 READ_REG命令(也就是 0x00+寄存器地址) ,把寄存器中地值读出来.对于函数来说也就是把 reg 寄存器地值读到reg_val 中去.uint SPI_RW_Reg(uchar reg, uchar value); //写数据value到reg寄存器寄存器访问函数:用来设置 24L01 地寄存器地值.基本思路就是通过 WRITE_REG命令(也就是 0x20+寄存器地址)把要设定地值写到相应地寄存器地址里面去,并读取返回值.对于函数来说也就是把 value值写到 reg 寄存器中.需要注意地是,访问 NRF24L01 之前首先要 enable 芯片(CSN=0;) ,访问完了以后再 disable芯片(CSN=1;).uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars); //从reg寄存器读出bytes个字节,通常用来//读取接收通道数据或接收/发送地址接收缓冲区访问函数:主要用来在接收时读取 FIFO 缓冲区中地值.基本思路就是通过READ_REG命令把数据从接收 FIFO(RD_RX_PLOAD)中读出并存到数组里面去.uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars); //把pBuf缓存中地数据写入到nRF24L01,通常//用来写入发发射缓冲区访问函数:主要用来把数组里地数放到发射 FIFO缓冲区中.基本思路就是通过WRITE_REG命令把数据存到发射 FIFO(WR_TX_PLOAD)中去.Tx 模式初始化过程1)写 Tx 节点地地址 TX_ADDR2)写 Rx 节点地地址(主要是为了使能 Auto Ack) RX_ADDR_P0 3)使能 AUTO ACK EN_AA4)使能 PIPE 0 EN_RXADDR5)配置自动重发次数 SETUP_RETR6)选择通信频率 RF_CH7)配置发射参数(低噪放大器增益.发射功率.无线速率) RF_SETUP 8 ) 选择通道0 有效数据宽度 Rx_Pw_P09)配置 24L01 地基本参数以及切换工作模式 CONFIG.Rx 模式初始化过程:初始化步骤 24L01 相关寄存器1)写 Rx 节点地地址 RX_ADDR_P02)使能 AUTO ACK EN_AA3)使能 PIPE 0 EN_RXADDR4)选择通信频率 RF_CH5) 选择通道0 有效数据宽度 Rx_Pw_P06)配置发射参数(低噪放大器增益.发射功率.无线速率) RF_SETUP 7)配置 24L01 地基本参数以及切换工作模式 CONFIG.。

nRF24L01射频模块驱动程序设计

nRF24L01射频模块驱动程序设计
YAN L i n - x i a n g, Z HANG Ho n g - y u
( S c h o o l o fE l e c t r o n i c E n g i n e e r i n g , U n w e n i t y o fE l e c t r o n i c S c i e n c e a n d T e c h n o l o g y f o C h i n a , C h e n g d u 6 1 1 7 3 1 ,C h i n a )
序 。最 终 实现 了 n R F 2 4 L 0 1 射 频 模 块 之 间 的通 信 。 该 射 频模 块在 2 . 4 5 G无 线通 信 领 域 中有 着 广 泛 的应 用前 景 。 关键词 : 驱动程序 : n R F 2 4 L 0 1 射频模块 ; 嵌入 式 L i n u x ; 2 . 4 5 G 无 线通 信
严林 祥 . 张 红 雨
( 电子 科 技 大 学 电子
摘 要 :文 中基 于微 处理 器 ¥ 3 C 2 4 4 0和 嵌 入 式 L i n u x操 作 系统 .介 绍 了 一种 利 用 S P I 控 制 器控 制 n R F 2 4 L 0 1 射 频模 块 的驱动程序设计。讨论 了n R F 2 4 L 0 1 射 频 模 块 的硬 件 电路 。 采 用 字符 设 备 驱 动 的 开发 流程 设 计 了射 频模 块 的 驱 动 程
且 有 统 一 的 协 议 标 准 的 应 用 领 域 有 :微 波 炉 、无 绳 电 话 、
段 的超 低 功耗 单 片 无 线 收 发 器 芯 片 。芯 片 内置 频 率 发 生 器 、 功率放大器 、 晶体 振 荡 器 、 调制器和解调器等功 能模块 , 外 围 扩展少量 的器件就可 以利用全 双工的 S P I 串行 接 口与 MC U 实 现 通信 。芯 片 有 1 2 5个频 点 , 能够实现点对点 、 点 对 多 点 的

nRF24L01的工作原理

nRF24L01的工作原理

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

它采用射频收发器芯片nRF24L01+,支持2Mbps的高速数据传输速率,具有优秀的抗干扰能力和稳定的信号传输性能。

本文将详细介绍nRF24L01的工作原理,包括硬件结构和通信协议。

1. 硬件结构nRF24L01模块主要由射频收发器芯片、天线、晶振、电源管理电路和外部接口组成。

射频收发器芯片:nRF24L01+芯片是模块的核心部件,它集成为了射频收发器、基带处理器和嵌入式协议栈等功能。

该芯片采用2.4GHz的ISM频段,支持多通道选择,能够与其他nRF24L01模块进行无线通信。

天线:nRF24L01模块通常配备了PCB天线,用于接收和发送无线信号。

天线的设计和布局对模块的通信距离和稳定性有一定影响。

晶振:nRF24L01模块使用晶振提供时钟信号,以保证模块的正常运行。

常见的晶振频率为16MHz。

电源管理电路:nRF24L01模块需要3.3V的电源供电,电源管理电路用于稳定和管理电源输入。

外部接口:nRF24L01模块通常具有SPI接口,用于与主控芯片进行通信。

SPI接口包括四根信号线:SCK、MISO、MOSI和CSN。

2. 通信协议nRF24L01模块使用一种称为Enhanced ShockBurst的协议进行数据传输。

该协议基于射频通信技术,具有高效的数据传输和强大的抗干扰能力。

Enhanced ShockBurst协议采用了一对多的通信方式,即一个发送器可以同时向多个接收器发送数据。

协议中定义了一些重要的概念和参数,如地址、通道、数据包、数据速率等。

地址:nRF24L01模块使用6字节的地址进行通信,发送器和接收器必须使用相同的地址才干进行通信。

地址由发送器设定,并在数据包中包含。

通道:nRF24L01模块支持多达125个通道,发送器和接收器必须使用相同的通道才干进行通信。

通道的选择可以用于避免不同模块之间的干扰。

nRF24L01的工作原理

nRF24L01的工作原理

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

它采用射频(RF)技术,能够在2.4GHz频段进行无线通信,并具备较高的数据传输速率和较低的功耗。

nRF24L01工作原理主要包括无线信号传输、数据编码和解码、频率选择和信号调制等关键步骤。

下面将详细介绍nRF24L01的工作原理。

1. 无线信号传输nRF24L01通过天线接收或者发送无线信号。

在发送端,待发送的数据通过SPI(串行外设接口)与nRF24L01进行通信,nRF24L01将数据转换为无线信号并通过天线发送出去。

在接收端,nRF24L01通过天线接收到的无线信号,将其转换为数字信号,并通过SPI与微控制器进行通信,将接收到的数据传输给用户。

2. 数据编码和解码nRF24L01使用一种称为Enhanced ShockBurst™的编码技术,用于提高数据传输的可靠性和抗干扰能力。

发送端将待发送的数据分为多个数据包,并对每一个数据包进行编码和校验,以确保数据的完整性和准确性。

接收端对接收到的数据包进行解码和校验,以还原原始数据。

3. 频率选择nRF24L01可以在2.4GHz频段的多个不重叠的信道中进行通信。

通过选择不同的信道,可以避免与其他无线设备的干扰。

nRF24L01支持2.4GHz频段的125个信道,其中2.4GHz到2.525GHz范围内有16个信道,每一个信道之间的频率间隔为1MHz。

4. 信号调制nRF24L01使用高级调制技术,将数字信号转换为摹拟信号进行无线传输。

它采用高级调制方式,如GFSK(高斯频移键控)调制,以提高数据传输的可靠性和抗干扰能力。

GFSK调制技术通过改变载波频率的相位,将数字信号转换为摹拟信号,并通过天线进行传输。

5. 功耗控制nRF24L01具有低功耗特性,能够在不同的功耗模式之间进行切换,以满足不同应用场景的需求。

它支持多种低功耗模式,如睡眠模式、待机模式和接收模式等。

nrf24l01无线通信模块与51单片机工作原理

nrf24l01无线通信模块与51单片机工作原理

nrf24l01无线通信模块与51单片机工作原理
nRF24L01是一款低功耗的2.4GHz无线通信模块,适用于微
控制器和嵌入式系统之间的短距离数据传输。

它可以与51单
片机进行配合使用。

nRF24L01模块包括一个射频发射芯片和一个射频接收芯片。

模块通过SPI接口与51单片机连接。

其工作原理如下:
1. 初始化:首先,51单片机通过SPI接口向nRF24L01模块发送配置命令,包括设置通信频率、通信通道、发射功率等参数。

2. 发送数据:当需要发送数据时,51单片机将待发送的数据
通过SPI接口发送给nRF24L01模块的发送芯片。

发送芯片将
数据转换为无线信号,并通过天线发射出去。

3. 接收数据:当有数据被接收时,nRF24L01模块的接收芯片
会把接收到的数据通过SPI接口传递给51单片机。

单片机再
根据需要对接收到的数据进行处理。

4. 确认和重传:发送芯片在发送数据后会等待接收芯片的确认信号。

如果收到确认信号,发送芯片会继续发送下一个数据包。

如果未收到确认信号,发送芯片会进行多次重传,以确保数据的可靠传输。

5. 通信协议:nRF24L01模块支持多种通信协议,如无线串口、SPI、I2C等。

可以根据需要选择合适的通信协议进行数据传输。

通过上述工作原理,nRF24L01模块可以实现低功耗、短距离的无线数据传输,并与51单片机进行可靠的通信。

它被广泛应用于无线遥控、传感器网络、智能家居等领域。

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

//下面是接收的NRF24L01的程序。

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include<reg52.h>#include "nrf24l01.h"#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit IRQ =P1^2;//输入sbit MISO =P1^3; //输入sbit MOSI =P1^1;//输出sbit SCLK =P1^4;//输出sbit CE =P1^5;//输出sbit CSN =P1^0;//输出uchar RevTempDate[5];//最后一位用来存放结束标志uchar code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址/*****************状态标志*****************************************/uchar bdata sta; //状态标志sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;/*****************SPI时序函数******************************************/ uchar NRFSPI(uchar date){uchar i;for(i=0;i<8;i++) // 循环8次{if(date&0x80)MOSI=1;elseMOSI=0; // byte最高位输出到MOSIdate<<=1; // 低一位移位到最高位SCLK=1;if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据date|=0x01; // 读MISO到byte最低位SCLK=0; // SCK置低}return(date); // 返回读出的一字节}/**********************NRF24L01初始化函数*******************************/ void NRF24L01Int(){NRFDelay(2);//让系统什么都不干CE=0;CSN=1;SCLK=0;IRQ=1;}/*****************SPI读寄存器一字节函数*********************************/ uchar NRFReadReg(uchar RegAddr){uchar BackDate;CSN=0;//启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令CSN=1;return(BackDate); //返回状态}/*****************SPI写寄存器一字节函数*********************************/ uchar NRFWriteReg(uchar RegAddr,uchar date){uchar BackDate;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值CSN=1;return(BackDate);}/*****************SPI读取RXFIFO寄存器的值********************************/ uchar NRFReadRxDate(uchar RegAddr,uchar *RxDate,uchar DateLen){ //寄存器地址//读取数据存放变量//读取数据长度//用于接收uchar BackDate,i;CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i<DateLen;i++) //读取数据{RxDate[i]=NRFSPI(0);}CSN=1;return(BackDate);}/*****************SPI写入TXFIFO寄存器的值**********************************/ uchar NRFWriteTxDate(uchar RegAddr,uchar *TxDate,uchar DateLen){ //寄存器地址//写入数据存放变量//读取数据长度//用于发送uchar BackDate,i;CSN=0;BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址for(i=0;i<DateLen;i++)//写入数据{NRFSPI(*TxDate++);}CSN=1;return(BackDate);}/*****************NRF设置为发送模式并发送数据******************************/ void NRFSetTxMode(uchar *TxDate){ //发送模式CE=0;NRFWriteTxDate(W_REGISTER+TX_ADDR,TxAddr,TX_ADDR_WITDH);//写寄存器指令+P0地址使能指令+发送地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DA TA_WITDH);//写入数据/******下面有关寄存器配置**************/NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等待250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC使能,16位CRC校验,上电CE=1;NRFDelay(5);//保持10us秒以上}/*****************NRF设置为接收模式并接收数据******************************/ //接收模式void NRFSetRXMode(){CE=0;NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH); // 接收设备接收通道0使用和发送设备相同的发送地址NRFWriteReg(W_REGISTER+EN_AA,0x01); // 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0NRFWriteReg(W_REGISTER+RF_CH,0x40); // 选择射频通道0x40NRFWriteReg(W_REGISTER+RX_PW_P0,TX_DATA_WITDH); // 接收通道0选择和发送通道相同有效数据宽度NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放大器增益NRFWriteReg(W_REGISTER+CONFIG,0x0f); // CRC使能,16位CRC校验,上电,接收模式CE = 1;NRFDelay(5);}/****************************检测是否有接收到数据******************************/void CheckACK(){ //用于发射模式接收应答信号sta=NRFReadReg(R_REGISTER+STATUS); // 返回状态寄存器if(TX_DS)NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标志}/*************************接收数据*********************************************/void GetDate(){sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器if(RX_DR) // 判断是否接收到数据{CE=0;//待机NRFReadRxDate(R_RX_PAYLOAD,RevTempDate,RX_DATA_WITDH);// 从RXFIFO读取数据接收4位即可,后一位位结束位NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标CSN=0;NRFSPI(FLUSH_RX);//用于清空FIFO !!关键!!不然会出现意想不到的后果!!!大家记住!!CSN=1;}//NRFWriteReg(W_REGISTER+STA TUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标}void NRFDelay(uint t){uint x,y;for(x=t;x>0;x--)for(y=110;y>0;y--);}。

相关文档
最新文档