关于NRF24L01的C51单片机双向通讯C程序(中文详解)
51单片机的串口通信程序(C语言)
51单片机的串口通信程序(C语言) 51单片机的串口通信程序(C语言)在嵌入式系统中,串口通信是一种常见的数据传输方式,也是单片机与外部设备进行通信的重要手段之一。
本文将介绍使用C语言编写51单片机的串口通信程序。
1. 硬件准备在开始编写串口通信程序之前,需要准备好相应的硬件设备。
首先,我们需要一块51单片机开发板,内置了串口通信功能。
另外,我们还需要连接一个与单片机通信的外部设备,例如计算机或其他单片机。
2. 引入头文件在C语言中,我们需要引入相应的头文件来使用串口通信相关的函数。
在51单片机中,我们需要引入reg51.h头文件,以便使用单片机的寄存器操作相关函数。
同时,我们还需要引入头文件来定义串口通信的相关寄存器。
3. 配置串口参数在使用串口通信之前,我们需要配置串口的参数,例如波特率、数据位、停止位等。
这些参数的配置需要根据实际需要进行调整。
在51单片机中,我们可以通过写入相应的寄存器来配置串口参数。
4. 初始化串口在配置完串口参数之后,我们需要初始化串口,以便开始进行数据的发送和接收。
初始化串口的过程包括打开串口、设置中断等。
5. 数据发送在串口通信中,数据的发送通常分为两种方式:阻塞发送和非阻塞发送。
阻塞发送是指程序在发送完数据之后才会继续执行下面的代码,而非阻塞发送是指程序在发送数据的同时可以继续执行其他代码。
6. 数据接收数据的接收与数据的发送类似,同样有阻塞接收和非阻塞接收两种方式。
在接收数据时,需要不断地检测是否有数据到达,并及时进行处理。
7. 中断处理在串口通信中,中断是一种常见的处理方式。
通过使用中断,可以及时地响应串口数据的到达或者发送完成等事件,提高程序的处理效率。
8. 串口通信实例下面是一个简单的串口通信实例,用于在51单片机与计算机之间进行数据的传输。
```c#include <reg51.h>#include <stdio.h>#define BAUDRATE 9600#define FOSC 11059200void UART_init(){TMOD = 0x20; // 设置定时器1为模式2SCON = 0x50; // 设置串口为模式1,允许接收TH1 = 256 - FOSC / 12 / 32 / BAUDRATE; // 计算波特率定时器重载值TR1 = 1; // 启动定时器1EA = 1; // 允许中断ES = 1; // 允许串口中断}void UART_send_byte(unsigned char byte){SBUF = byte;while (!TI); // 等待发送完成TI = 0; // 清除发送完成标志位}unsigned char UART_receive_byte(){while (!RI); // 等待接收完成RI = 0; // 清除接收完成标志位return SBUF;}void UART_send_string(char *s){while (*s){UART_send_byte(*s);s++;}}void main(){UART_init();UART_send_string("Hello, World!"); while (1){unsigned char data = UART_receive_byte();// 对接收到的数据进行处理}}```总结:通过以上步骤,我们可以编写出简单的51单片机串口通信程序。
51单片机应用之无线通讯模块NRF24L01+
30、51单片机应用之............无线通讯模块NRF24L01+(一)基础知识篇
今天刚调试好,先看图吧!这张是AT89C2051控制NRF24L01+做发射调试。
看看NRF24L01细节吧!
这是LCD屏显示:
AT89S52做接收测试:
正在接收时的显示:
接收到数据后显示32个数据值:
无线模块NRF24L01+应用上篇结束,敬请期待NRF24L01+下篇的调试部分。
31、51单片机应用之............无线通讯模块NRF24L01+(二)模块调试篇
32、51单片机应用之............无线通讯模块NRF24L01+(三)发送与接收模块的联调
33、51单片机应用之............无线通讯模块NRF24L01+(四)举例应用
34、补充NRF24L01+之————LED调试篇
写了前面四篇关于NRF24L01通讯调试的文章,看来大家还是很喜欢,有帮助的。
有很多大学生朋友问我说,我们没有两个LCD来显示调试状态,连一个也没有,能不能用几个LED来显示调试状态呢?因此我就写这篇补充调试的文章,就用P0口的8个LED来显示调试NRF24L01到成功进行数据通讯。
先把51单片机的最小系统准备好,还有8个LED的小电路板,如果你的LED就在系统板上那省了这一步。
8个LED的小板子电路很简单,但你焊接要可靠,不然电路本身都不稳定,后面对判断故障会产生很大影响。
NRF24L01+模块电路还是前面说过的那样:
相同的两个模块的板子。
nRF24L01中文手册
在 ShockBurstTM 发送模式下,nRF24L01 自动生成前导码及 CRC 校验,参见表格 12。数据发送完毕 后 IRQ 通知 MCU。减少了 MCU 的查询时间,也就意味着减少了 MCU 的工作量同时减少了软件的开发 时间。nRF24L01 内部有三个不同的 RX FIFO 寄存器(6 个通道共享此寄存器)和三个不同的 TX FIFO 寄 存器。在掉电模式下、待机模式下和数据传输的过程中 MCU 可以随时访问 FIFO 寄存器。这就允许 SPI 接口可以以低速进行数据传送,并且可以应用于 MCU 硬件上没有 SPI 接口的情况下。
小心:静电敏感器件。操作时遵守防护规则。
COPYRIGHT ©2007 迅通科技 TEL 北京:+86 10 64390486 深圳:+86 755 26675941
6
术语表
迅通科技
术语
描述
ACK
确认信号(应答信号)
ART
自动重发
CE
芯片使能
CLK
迅 ShockBurstTM 模式: ShockBurst 模式下 nRF24L01 可以与成本较低的低速 MCU 相连。高速信号处理是由芯片内部的射频 协议处理的,nRF24L01 提供 SPI 接口,数据率取决于单片机本身接口速度。ShockBurst 模式通过允许与 单片机低速通信而无线部分高速通信,减小了通信的平均消耗电流。
工业传感器 玩具
技
低工作电压:1.9~3.6V
概述:
科
nRF24L01 是一款工作在 2.4~2.5GHz 世界通用 ISM 频段的单片无线收发器芯片。无线收发器包括:频
无线模块2401调试方法(C51)
//*************************************SPI(nRF24L01)寄存器地址**************************************************** #define CONFIG #define EN_AA #define EN_RXADDR #define SETUP_AW #define SETUP_RETR #define RF_CH #define RF_SETUP #define STATUS #define OBSERVE_TX #define CD #define RX_ADDR_P0 #define RX_ADDR_P1 #define RX_ADDR_P2 #define RX_ADDR_P3 #define RX_ADDR_P4 #define RX_ADDR_P5 #define TX_ADDR #define RX_PW_P0 #define RX_PW_P1 #define RX_PW_P2 #define RX_PW_P3 #define RX_PW_P4 #define RX_PW_P5 #define FIFO_STATUS 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17 // 配置收发状态,CRC 校验模式以及收发状态响应方式 // 自动应答功能设置 // 可用信道设置 // 收发地址宽度设置 // 自动重发功能设置 // 工作频率设置 // 发射速率、功耗功能设置 // 状态寄存器 // 发送监测功能 // 地址检测 // 频道 0 接收数据地址 // 频道 1 接收数据地址 // 频道 2 接收数据地址 // 频道 3 接收数据地址 // 频道 4 接收数据地址 // 频道 5 接收数据地址 // 发送地址寄存器 // 接收频道 0 接收数据长度 // 接收频道 0 接收数据长度 // 接收频道 0 接收数据长度 // 接收频道 0 接收数据长度 // 接收频道 0 接收数据长度 // 接收频道 0 接收数据长度 // FIFO 栈入栈出状态寄存器设置
无线模块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.。
如何让SPI nRF24L01无线在两个单片机里实现通信
66 delay_ms(300}
69 }
2401.h
1 #ifndef __NRF24L01_H__
2 #define __NRF24L01_H__
3 #include
4 #define uchar unsigned char
5 #define uint unsigned int
45 delay_ms(5);//消抖动
46 if(KEY8==0)
47 {
48 while(!KEY8);
49 TX_Mode(); //发送模式
50 nRF24L01_TxPacket(Tx_Buf1); //发送命令数据
51 LED6=0;
52 delay_ms(300);
53 LED6=1;
6
7 sbit CE =P1
18 {
19 unsigned int i;
20 while(x--)
21 for(i=125;i》0;i--);
22 }
23 void main()
24 {
25 uchar Tx_Buf1[]={1};//发送的信息1
26 uchar Rx_Buf[32]; //接收到的数据暂存器,最多32字节数据
39 {
40 RX_Mode();//接收模式
41 while(!nRF24L01_RxPacket(Rx_Buf))//等待接收数据,返回1则接收到数据,在等待接收数据期间,可以随时变成发送模式
42 {
43 if(KEY8==0)//按了按键8则变成发送模式,发送对应数据,发送完后变成接收模式
44 {
如何让SPI nRF24L01无线在两个单片机里实现通信
nrf24l01无线通信模块与51单片机工作原理
nrf24l01无线通信模块与51单片机工作原理无线通信技术在现代社会中扮演着重要的角色,其中nrf24l01无线通信模块与51单片机也成为了无线通信的重要组成部分。
本文将探讨nrf24l01无线通信模块与51单片机的工作原理,以及它们之间的配合关系。
一、nrf24l01无线通信模块nrf24l01无线通信模块是一种低功耗的2.4GHz无线收发模块,广泛应用于物联网、无线传感器网络等领域。
其工作原理基于射频通信技术,通过无线信道进行数据的传输。
nrf24l01模块由无线收发器和嵌入式射频微控制器组成,具备高速率、长距离传输和多通道选择等特性。
1. 发射端工作原理nrf24l01发射端主要由收发器、天线和控制电路组成。
当51单片机通过SPI总线与nrf24l01通信时,可将要发送的数据通过控制电路和收发器转换成射频信号,并通过天线发送出去。
发送端的工作原理可简述为以下几个步骤:a. 初始化设置:通过配置寄存器进行初始化设置,包括工作频率、数据传输速率、天线增益等参数。
b. 数据准备与发送:将待发送的数据加载到发送缓冲区中,并通过发送指令启动数据的发送。
c. 发送前导码:在发送数据之前,发射端会先发送一段前导码作为同步信号,以确保接收端正确接收数据。
d. 数据传输与重发机制:发送端将数据以数据包的形式传输,接收端在接收到数据后会进行确认应答,发送端根据应答情况决定是否进行重发。
2. 接收端工作原理nrf24l01接收端与发送端相似,主要由收发器、天线和控制电路组成。
当发送端通过射频信号将数据发送过来时,接收端的工作原理如下:a. 初始化设置:与发送端类似,接收端也需要通过配置寄存器进行初始化设置,以匹配发送端的参数。
b. 接收与解码:接收端在接收到射频信号后,对信号进行解码,并将解码后的数据加载到接收缓冲区。
c. 数据处理与应答:通过与51单片机的交互,将接收到的数据进行处理,并向发送端发送确认应答,确保数据的可靠性。
NRF24L01无线模块C语言程序
NRF24L01无线模块C语言法式之巴公井开创作24MHz晶振#include#include#include#include#include#include#define U8 unsigned char#define U16 unsigned int#define TX_ADDR_WITDH 5 //发送地址宽度设置为5个字节#define RX_ADDR_WITDH 5 //接收地址宽度设置为5个字节#define TX_DATA_WITDH 1//发送数据宽度1个字节#define RX_DATA_WITDH 1//接收数据宽度1个字节#define R_REGISTER 0x00//读取配置寄存器#define W_REGISTER 0x20//写配置寄存器#define R_RX_PAYLOAD 0x61//读取RX有效数据#define W_TX_PAYLOAD 0xa0//写TX有效数据#define FLUSH_TX 0xe1//清除TXFIFO寄存器#define FLUSH_RX 0xe2//清除RXFIFO寄存器#define REUSE_TX_PL 0xe3//重新使用上一包有效数据#define NOP 0xff//空把持#define CONFIG 0x00//配置寄存器#define EN_AA 0x01//使能自动应答#define EN_RXADDR 0x02//接收通道使能0-5个通道#define SETUP_AW 0x03//设置数据通道地址宽度3-5#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//P0通道数据宽度设置#define RX_PW_P1 0x12//P1通道数据宽度设置#define RX_PW_P2 0x13//P2通道数据宽度设置#define RX_PW_P3 0x14//P3通道数据宽度设置#define RX_PW_P4 0x15//P4通道数据宽度设置#define RX_PW_P5 0x16//P5通道数据宽度设置#define FIFO_STATUS 0x17//FIFO状态寄存器//NRF24L01U8 NRFACK();U8 NRFSPI(U8 date);U8 NRFReadReg(U8 RegAddr);U8 NRFWriteReg(U8 RegAddr,U8 date);U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen);U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen);U8 NRFRevDate(U8 *RevDate);void NRFSetTxMode(U8 *TxDate);void NRF24L01Int();void NRFSetRXMode();U8 CheckACK();void Delay(U16 t);U8 bdata sta;//mainvoid Delay_10ms(U16 del);bit CE=P1^4; //RX/TX模式选择端sbit IRQ=P1^1; //可屏蔽中断端sbit CSN=P1^6; //SPI片选端//就是SSsbit MOSI=P1^0; //SPI主机输出从机输入端1sbit MISO=P1^2; //SPI主机输入从机输出端sbit SCLK=P1^3; //SPI时钟端U8 code TxAddr[]={0x34,0x43,0x10,0x10,0x01};//发送地址U8 bdata sta; //状态标识表记标帜sbit RX_DR=sta^6;sbit TX_DS=sta^5;sbit MAX_RT=sta^4;void Delay(U16 t){ U16 x,y; for(x=t;x>0;x--) for(y=110;y>0;y--);}U8 NRFSPI(U8 date){U8 i; for(i=0;i<8;i++) // 循环8次{ if(date&0x80) MOSI=1; else MOSI=0; // byte最高位输出到MOSI date<<=1; // 低一位移位到最高位 SCLK=1; if(MISO) // 拉高SCK,nRF24L01从MOSI读入1位数据, 同时从MISO输出1位数据 date|=0x01; // 读MISO 到byte最低位 SCLK=0; // SCK置低} return(date); // 返回读出的一字节}void NRF24L01Int(){ Delay(2);//让系统什么都不干CE=0; //待机模式1 CSN=1; SCLK=0; IRQ=1; }U8 NRFReadReg(U8 RegAddr){ U8 BackDate; CSN=0;//启动时序NRFSPI(RegAddr);//写寄存器地址BackDate=NRFSPI(0x00);//写入读寄存器指令CSN=1; return(BackDate); //返回状态}U8NRFWriteReg(U8 RegAddr,U8 date){ U8 BackDate; CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入地址NRFSPI(date);//写入值CSN=1; return(BackDate);}U8 NRFReadRxDate(U8 RegAddr,U8 *RxDate,U8 DateLen){ //寄存器地址//读取数据寄存变量//读取数据长度//用于接收U8 BackDate,i; CSN=0;//启动时序BackDate=NRFSPI(RegAddr);//写入要读取的寄存器地址for(i=0;i { RxDate[i]=NRFSPI(0); } CSN=1; return(BackDate);}U8 NRFWriteTxDate(U8 RegAddr,U8 *TxDate,U8 DateLen){ //寄存器地址//写入数据寄存变量//读取数据长度//用于发送U8 BackDate,i; CSN=0; BackDate=NRFSPI(RegAddr);//写入要写入寄存器的地址 for(i=0;i { NRFSPI(*TxDate++); }CSN=1; return(BackDate);}void NRFSetTxMode(U8 *TxDate){//发送模式 CE=0; NRFWriteTxDate(W_REGISTER+TX_ADDR,Tx Addr,TX_ADDR_WITDH);//写寄存器指令+接收地址使能指令+接收地址+地址宽度NRFWriteTxDate(W_REGISTER+RX_ADDR_P0,TxAddr,TX_ADDR_WITDH);//为了应答接收设备,接收通道0地址和发送地址相同NRFWriteTxDate(W_TX_PAYLOAD,TxDate,TX_DATA_WITDH);//写入数据NRFWriteReg(W_REGISTER+EN_AA,0x01);// 使能接收通道0自动应答NRFWriteReg(W_REGISTER+EN_RXADDR,0x01); // 使能接收通道0 NRFWriteReg(W_REGISTER+SETUP_RETR,0x0a); // 自动重发延时等候250us+86us,自动重发10次NRFWriteReg(W_REGISTER+RF_CH,0x40);// 选择射频通道0x40 NRFWriteReg(W_REGISTER+RF_SETUP,0x07); // 数据传输率1Mbps,发射功率0dBm,低噪声放年夜器增益NRFWriteReg(W_REGISTER+CONFIG,0x0e); // CRC 使能,16位CRC校验,上电CE=1; Delay(5);//坚持10us秒以上}//主要接收模式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);// 使能接收通道0 NRFWriteReg(W_REGISTER+RF_CH,0x40);// 选择射频通道0x40 NRFWriteReg(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; Delay(5);//坚持10us秒以上}U8 CheckACK(){ //用于发射sta=NRFReadReg(R_REGISTER+STATUS);// 返回状态寄存器if(TX_DS||MAX_RT) //发送完毕中断{ NRFWriteReg(W_REGISTER+STATUS,0xff); // 清除TX_DS或MAX_RT中断标识表记标帜CSN=0; NRFSPI(FLUSH_TX);//用于清空FIFO !!关键!!否则会呈现意想不到的后果!!!年夜家记住!! CSN=1; return(0); } else return(1);}//用于接收模式U8 NRFRevDate(U8 *RevDate){ U8RevFlags=0; sta=NRFReadReg(R_REGISTER+STATUS);//发送数据后读取状态寄存器 if(RX_DR) // 判断是否接收到数据{ CE=0; //SPI使能NRFReadRxDate(R_RX_PAYLOAD,RevDate,RX_DATA_WITDH);/ / 从RXFIFO读取数据RevFlags=1; //读取数据完成标识表记标帜} NRFWriteReg(W_REGISTER+STATUS,0xff); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标 return(RevFlags);}void Delay_10ms(U16 del){ U16 i,j; for(i=0; i<del; i++) for(j=0; j<1827; j++) //这个是通过软件仿真得出的数;}// 做发射main(){ U8 TxDate[1]={0}; NRF24L01Int(); Delay(6000); while(1) { if(KEY==0) { if(KEY==0) { Delay_1 0ms(2); TxDate[0]=0x08;//发射按键标识值NRFSetTxMode(TxDate); while(CheckACK());TxDate[0]=0; } } }}//// 做接收:一直处于接受模式查询所获得的值是不是0x08main(){ U8 x; U8 RxBuf[1]={0}; NRF24L01Int(); Delay(6000);while(1) { NRFSetRXMode(); NRFRevDate(RxBuf); x=RxBuf[0]; if(x==0x08)//0x08为发射部份所发送的按键标识{ // //加入所要执行的功能函数 //固然了这里用到单片机io口的时候需要在之前界说//还有就是发送法式中的KEY也需要之前界说好 RxBuf[0]=0; } }}。
单片机双机通信(C51程序)
单片机双机通信(C51程序)/*发送程序连线:两个单片机用3 根线连起来,要共地,rxd,txd 要交叉连接程序效果:通过主机发送,从机接收在主机中通过记下按键按下的次数,主机中显示最后按下的六个数值,并发送给从机,从机也显示这六个数值*/#includereg52.h //头文件#includeintrins.h //循环移位文件#define uchar unsigned char//宏定义#define uint unsigned intsbit key1=P3 ; //位声明uchar code table[] ={0X00,0x3f,0x06,0x5b,//数码管显示的数值0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uchar table_tr[6];//暂存最后按下的六个数值uchar count,cnt;//延时子函数,用于数码管显示void delay(uchar i){ uchar x,y; for(x=i;x0;x--) for(y=110;y0;y--);}//初始化子函数void init(){ TMOD=0x20;//T1 工作在方式2 TH1=0XF4;//波特率为4.8kbit/s TL1=0XF4; TR1=1;//启动定时器1 SCON=0X50;//串口工作在方式1,允许接收}//显示子函数void display(){ uchar i,j;//定义局部变量j=0x7f; //赋初值for(i=0;i6;i++) { P2=j; //点亮最右边的数码管P0=table[table_tr[i]]; //显示该数值delay(10); //延时,便于眼睛看清j=_cror_(j,1);//循环右移一位}}//按键扫描子函数void key_scan(){ if(key1==0) //判断是否有按键按下{ while(!key1) //等待按键松手{ display();//防止掉显} cnt++; //加1,用于显示SBUF=cnt;//送给缓冲区,发送while(!TI); //等待发送完TI=0; //发送完了,标志位清零for(count=0;count5;count++) //用于保存最后按下的六个按键数值{ table_tr[count] =table_tr[count+1]; } table_tr[5]=cnt; //把最后按下的按键数值赋给table_tr【5】if(cnt==10) //按键按下的次数有没有等于10 cnt=0;//等于,则清零}}void main() { init(); //调用初始化子函数P0=0x00; while(1) { key_scan(); //调用键盘扫描子函数display();//调用显示子函数} }tips:感谢大家的阅读,本文由我司收集整编。
NRF24L01无线串口开发板程序详解
1.源程序开发环境建立1.1程序编译软件编译软件用keil C51,打开安装文件,一路点击下一步即可完成。
1.2程序下载软件使用STC ISP下载软件。
2.源程序文件整体结构工程中,只有一个main.c文件,所有程序都写在这个文件里面。
Reg51.h是包含的头文件。
是不是非常简单!3.源程序执行流程无线数据处理程序:串口数据处理程序:4.串口配置函数void serial_open(void){SCON = 0X50;AUXR |= 0X04;TL2 = 0Xc0; // 9600TH2 = 0Xfd;AUXR|=0X10;}此串口配置函数,利用单片机内部的定时器2作为波特率发生器。
共用到4个寄存器:SCON AUXR TL2 TH2SM0和SM1的位决定串口工作的4种方式:程序中,SCON=0X50,即SM0=0 SM1=1,即串口工作在“方式1”;REN=1,允许串口接收数据。
TL2和TH2是定时器2的高位和低位寄存器。
程序中,首先AUXR|=0X40,最后AUXR|=0X10。
即首先把T2x12置1,然后把T2R置1。
即首先把定时器2设置为1T模式,然后把定时器打开。
5.串口发送数据函数void senddata(uchar data_buf){SBUF = data_buf;while(!TI);TI = 0;}用到了寄存器SBUF和寄存器SCON中的TI位。
SBUF寄存器是串口收发数据缓存寄存器,放到这个寄存器中的数据,会通过串口发送出去,接收到的串口数据,也会放到这个寄存器中。
也就是串口接收和发送都是使用这个寄存器。
程序中,SBUF=data_buf,就是把data_buf给了SBUF,单片机自动把SBUF里面的数据发送到串口。
TI是串口发送数据完成标志位,当串口发送完一个数据,此位置1,置位后,需要通过软件清0。
所以通过while(!TI),来检测TI位,达到检测串口是否发送完数据的目的。
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单片机进行可靠的通信。
它被广泛应用于无线遥控、传感器网络、智能家居等领域。
nrf24l01无线通信模块与51单片机工作原理 -回复
nrf24l01无线通信模块与51单片机工作原理-回复nRF24L01无线通信模块与51单片机工作原理引言:随着物联网的快速发展,无线通信技术在各个领域中的应用越来越广泛。
而在无线通信领域中,nRF24L01无线通信模块和51单片机成为了常见的组合。
本文将详细介绍nRF24L01和51单片机的工作原理及其之间的通信过程。
第一部分:nRF24L01无线通信模块的工作原理nRF24L01是一款低功耗的单片机无线通信模块,广泛应用于无线传感器网络、智能家居等领域。
其工作原理可以分为硬件和软件两个方面。
硬件方面,nRF24L01模块由射频前端及基带部分两个主要部分组成。
射频前端部分包括射频收发器和RF增益模块,用于接收和发送射频信号。
基带部分包含SPI接口、调制解调器和数据缓存区,用于控制数据的传输及处理。
软件方面,nRF24L01模块的工作需要通过使用专用的库函数进行驱动。
这些库函数可以在编程环境中调用,以实现nRF24L01模块的相应功能。
软件通过SPI接口与模块进行通信,并通过设置寄存器、发送命令和接收状态等方式控制模块的工作。
第二部分:51单片机的工作原理51单片机,全称为AT89C51,是一种典型的8051架构的单片机。
在无线通信系统中,51单片机通常作为主控芯片,通过与nRF24L01模块进行交互,实现与其他设备的无线通信。
51单片机的工作原理主要包括四个方面:时钟与计时、IO口控制、中断系统和串行通信。
时钟与计时:51单片机内部由一个双字节的定时器/计数器组成,用于提供计时和延时功能。
通过设置计时器的时钟源和分频系数,可以实现不同频率和精度的计时与延时。
IO口控制:51单片机的IO口主要用于与其他设备进行数据交互。
通过设置相应的寄存器,可以控制IO口的输入输出、上拉电阻和工作模式等。
中断系统:51单片机内部集成了中断控制器,可以通过设置中断优先级和中断源等参数,实现对不同事件的响应。
在无线通信系统中,可以通过中断来处理接收数据、发送完成等事件。
nrf24L01中文资料
单片2.4G 无线射频收发芯片nRF24L01===================================================特性● 真正的GFSK● 内置链路层● 增强型ShockBurst TM● 自动应答及自动重发功能 ● 地址及CRC 检验功能● 数据传输率1或2Mbps ● SPI 接口数据速率0~8Mbps ● 125个可选工作频道● 很短的频道切换时间可用于跳频 ● 与nRF 24XX 系列完全兼容 ● 可接受5V 电平的输入 ● 20脚QFN 44mm 封装 ● 极低的晶振要求60ppm ● 低成本电感和双面PCB 板 ● 工作电压 1.9~3.6V 应用● 无线鼠标键盘游戏机操纵杆 ● 无线门禁● 无线数据通讯 ● 安防系统 ● 遥控装置 ● 遥感勘测● 智能运动设备 ● 工业传感器 ● 玩具 概述:nRF24L01是一款工作在2.4~2.5GHz 世界通用ISM 频段的单片无线收发器芯片无线收发器包括:频率发生器增强型SchockBurst TM 模式控制器功率放大器晶体振荡器调制器解调器输出功率频道选择和协议的设置可以通过SPI 接口进行设置极低的电流消耗当工作在发射模式下发射功率为-6dBm 时电流消耗为9.0mA 接收模式时为12.3mA掉电模式和待机模式下电流消耗更低 快速参考数据参数 数值 单位最低供电电压 1.9 V最大发射功率 0 dBm最大数据传输率 2000 kbps发射模式下电流消耗0dBm 11.3 mA接收模式下电流消耗2000kbps 12.3 mA温度范围 -40~ +85数据传输率为1000kbps 下的灵敏度 -85 dBm掉电模式下电流消耗 900 nA 表1 nRF24L01快速参考数据很短的时间???hehe,,有想法,,,是Mbps,,,,要利用好,,,这是在此功耗下,,,大的功耗消耗更大丠丠dBm=10*lg(P/1mW)为0.9uA 1mW W分类信息型号描述版本nRF24L01 IC 裸片 DnRF24L01 20脚QFN 4*4mm,RoHS&SS-00259compliant DnRF24L01-EVKIT 评估套件 1.0表2nRF24L01 分类信息结构方框图:图1 nRF24L01 及外部接口引脚及其功能引脚名称引脚功能描述1 CE 数字输入 RX或TX模式选择2 CSN 数字输入 SPI片选信号3 SCK 数字输入 SPI时钟4 MOSI 数字输入从SPI数据输入脚5 MISO 数字输出从SPI数据输出脚6 IRQ 数字输出可屏蔽中断脚7 VDD 电源电源+3V8 VSS 电源接地0V9 XC2 模拟输出晶体震荡器2脚10 XC1 模拟输入晶体震荡器1脚/外部时钟输入脚11 VDD_PA 电源输出给RF的功率放大器提供的+1.8V电源12 ANT1 天线天线接口113 ANT2 天线天线接口214 VSS 电源接地0V15 VDD 电源电源+3V16 IREF 模拟输入参考电流17 VSS 电源接地0V18 VDD 电源电源+3V19 DVDD 电源输出去耦电路电源正极端20 VSS 电源接地0V表3nRF24L01引脚功能图2 引脚封装电气特性参数+27 +85 高电平输出电压=-0.5mA 高电平输出电压=0.5mA 160 320R GFSK >0 1800 2000 单通道工作电流单通道工作电流0.1%BRE(@2000kbps)图3nRF24L01外形封装尺寸极限范围供电电压VDD…………………………….-0.3V~+3.6VVSS (0V)输入电压V I………………………………-0.3V~5.25V输出电压V O……………………………. VSS~VDD总功耗=85……………………… 60mWPD T温度工作温度……………………-40~+85存储器温度…………………-40~+125注意:若超出上述极限值可能对元器件有损害静电敏感元件术语表术语描述ACK 确认信号应答信号ART 自动重发CE 芯片使能CLK 时钟信号CRC 循环冗余校验CSN 片选非ESB 增强型ShockBrust TMGFSK 高斯键控频移IRQ 中断请求ISM 工业科学医学LNA 低噪声放大LSB 最低有效位LSByte 最低有效字节Mbps 兆位/秒MCU 微控制器MISO 主机输入从机输出MOSI 主机输出从机输入MSB 最高有效位MSByte 最高有效字节PCB 印刷电路板PER 数据包误码率PID 数据包识别位PLD 载波PRX 接收源PTX 发射源PWR_DWN 掉电PWR_UP 上电RX 接收RX_DR 接收数据准备就绪SPI 串行可编程接口TX 发送TX_DS 已发送数据表5术语表功能描述工作模式nRF24L01可以设置为以下几种主要的模式模式PWR_UP PRIM_RX CE FIFO寄存器状态-接收模式 1 1 1数据在TX FIFO寄存器中发送模式 1 0 1发送模式 1 0 10 停留在发送模式直至数据发送完TX FIFO为空待机模式II 1 0 1待机模式I 1 - 0无数据传输-掉电模式0 - -表6 nRF24L01主要工作模式关于nRF24L01 I/O脚更详细的描述请参见下面的表7nRF24L01在不同模式下的引脚功能引脚名称 方向 发送模式接收模式 待机模式 掉电模式CE 输入 高电平>10us 高电平低电平-CSN 输入 SPI 片选使能低电平使能SCK 输入 SPI 时钟 MOSI输入 SPI 串行输入 MISO 三态输出 SPI 串行输出 IRQ输出 中断低电平使能表7nRF24L01引脚功能待机模式待机模式I在保证快速启动的同时减少系统平均消耗电流在待机模式I 下晶振正常工作在待机模式II 下部分时钟缓冲器处在工作模式当发送端TX FIFO 寄存器为空并且CE 为高电平时进入待机模式II 在待机模式期间寄存器配置字内容保持不变掉电模式在掉电模式下,nRF24L01各功能关闭保持电流消耗最小进入掉电模式后nRF24L01停止工作但寄存器内容保持不变启动时间见表格13掉电模式由寄存器中PWR_UP 位来控制数据包处理方式nRF24L01有如下几种数据包处理方式ShockBurst TM 与nRF2401nRF24E1nRF2402nRF24E2数据传输率为1Mbps 时相同 增强型ShockBurst TM 模式ShockBurst TM 模式ShockBurst 模式下nRF24L01可以与成本较低的低速MCU 相连高速信号处理是由芯片内部的射频协议处理的nRF24L01提供SPI 接口数据率取决于单片机本身接口速度ShockBurst 模式通过允许与单片机低速通信而无线部分高速通信减小了通信的平均消耗电流在ShockBurst TM 接收模式下当接收到有效的地址和数据时IRQ 通知MCU 随后MCU 可将接收到的数据从RX FIFO 寄存器中读出 在ShockBurst TM发送模式下nRF24L01自动生成前导码及CRC 校验参见表格12数据发送完毕后IRQ 通知MCU 减少了MCU 的查询时间也就意味着减少了MCU 的工作量同时减少了软件的开发时间nRF24L01内部有三个不同的RX FIFO 寄存器6个通道共享此寄存器和三个不同的TX FIFO 寄存器在掉电模式下待机模式下和数据传输的过程中MCU 可以随时访问FIFO 寄存器这就允许SPI 接口可以以低速进行数据传送并且可以应用于MCU 硬件上没有SPI 接口的情况下增强型的ShockBurst TM 模式增强型ShockBurst TM 模式可以使得双向链接协议执行起来更为容易有效典型的双向链接为发送方要求终端设备在接收到数据后有应答信号以便于发送方检测有无数据丢失一旦数据丢失则通过重新发送功能将丢失的数据恢复增强型的ShockBurst TM 模式可以同时控制应答及重发功能而无需增加MCU 工作量确实,,由硬件完成,,减小了量,,,图4 nRF24L01在星形网络中的结构图nRF24L01在接收模式下可以接收6路不同通道的数据见图4每一个数据通道使用不同的地址但是共用相同的频道也就是说6个不同的nRF24L01设置为发送模式后可以与同一个设置为接收模式的nRF24L01进行通讯而设置为接收模式的nRF24L01可以对这6个发射端进行识别数据通道0是唯一的一个可以配置为40位自身地址的数据通道1~5数据通道都为8位自身地址和32位公用地址所有的数据通道都可以设置为增强型ShockBurst 模式nRF24L01在确认收到数据后记录地址并以此地址为目标地址发送应答信号在发送端数据通道0被用做接收应答信号因此数据通道0的接收地址要与发送端地址相等以确保接收到正确的应答信号见图5 选择地址举例图5应答地址确定举例nRF24L01配置为增强型的ShockBurst TM发送模式下时只要MCU 有数据要发送nRF24L01就会启动ShockBurst TM 模式来发送数据在发送完数据后nRF24L01转到接收模式并等待终端的应答信号如果没有收到应答信号nRF24L01将重发相同的数据包直到收到应答信号或重发次数超过SETUP_RETR_ARC 寄存器中设置的值为止如果重发次数超过了设定值则产生MAX_RT 中断只要收到确认信号nRF24L01就认为最后一包数据已经发送成功接收方已经收到数据把TX FIFO 中的数据清除掉并产生TX_DS 中断IRQ 引脚置高在发射器中,,通道0要接收应答回来的信号,,所以应该与发送通道地址,,,相同,,在增强型ShockBurst模式下nRF24L01有如下的特征当工作在应答模式时快速的空中传输及启动时间极大的降低了电流消耗低成本nRF24L01集成了所有高速链路层操作比如重发丢失数据包和产生应答信号无需单片机硬件上一定有SPI口与其相连SPI 接口可以利用单片机通用I/O口进行模拟 由于空中传输时间很短极大的降低了无线传输中的碰撞现象由于链路层完全集成在芯片上非常便于软硬件的开发增强型ShockBurstTM发送模式1配置寄存器位PRIM_RX为低2当MCU有数据要发送时接收节点地址TX_ADDR和有效数据(TX_PLD)通过SPI接口写入nRF24L01发送数据的长度以字节计数从MCU写入TX FIFO当CSN为低时数据被不断的写入发送端发送完数据后将通道0设置为接收模式来接收应答信号其接收地址(RX_ADDR_P0)与接收端地址(TX_ADDR)相同例在图5中数据通道5的发送端(TX5)及接收端(RX)地址设置如下TX5TX_ADDR=0xB3B4B5B605TX5RX_ADDR_P0=0xB3B4B5B605RX RX_ADDR_P5=0xB3B4B5B6053设置CE为高启动发射CE高电平持续时间最小为10 us4nRF24L01 ShockBurst TM模式无线系统上电启动内部16MHz时钟无线发送数据打包见数据包描述高速发送数据由MCU设定为1Mbps或2Mbps5如果启动了自动应答模式自动重发计数器不等于0ENAA_P0=1无线芯片立即进入接收模式如果在有效应答时间范围内收到应答信号则认为数据成功发送到了接收端此时状态寄存器的TX_DS位置高并把数据从TX FIFO中清除掉如果在设定时间范围内没有接收到应答信号则重新发送数据如果自动重发计数器ARC_CNT溢出超过了编程设定的值则状态寄存器的MAX_RT位置高不清除TX FIFO中的数据当MAX_RT或TX_DS为高电平时IRQ引脚产生中断IRQ中断通过写状态寄存器来复位见中断章节如果重发次数在达到设定的最大重发次数时还没有收到应答信号的话在MAX_RX中断清除之前不会重发数据包数据包丢失计数器(PLOS_CNT)在每次产生MAX_RT中断后加一也就是说重发计数器ARC_CNT计算重发数据包次数PLOS_CNT计算在达到最大允许重发次数时仍没有发送成功的数据包个数6如果CE置低则系统进入待机模式I如果不设置CE为低则系统会发送TX FIFO寄存器中下一包数据如果TX FIFO寄存器为空并且CE为高则系统进入待机模式II.7如果系统在待机模式II当CE置低后系统立即进入待机模式I.增强型ShockBurst TM接收模式1 ShockBurst TM接收模式是通过设置寄存器中PRIM_RX位为高来选择的准备接收数据的通道必须被使能EN_RXADDR寄存器所有工作在增强型ShockBurst TM模式下的数据通道的自动应答功能是由(EN_AA寄存器)来使能的有效数据宽度是由RX_PW_Px寄存器来设置的地址的建立过程见增强型ShockBurst TM发送章节23 130us后4接收到有效的数据包后地址匹配CRC检验正确数据存储在RX_FIFO中同时RX_DR位置高并产生中断状态寄存器中RX_P_NO位显示数据是由哪个通道接收到的5如果使能自动确认信号则发送确认信号6 MCU设置CE脚为低进入待机模式I低功耗模式7 MCU将数据以合适的速率通过SPI口将数据读出8芯片准备好进入发送模式接收模式或掉电模式两种数据双方向的通讯方式如果想要数据在双方向上通讯寄存器必须紧随芯片工作模式的变化而变化处理器必须保证PTX和PRX端的同步性在RX_FIFO和TX_FIFO寄存器中可能同时存有数据CE=1是开始启动的标志,,,这个以前没有注意,,,!!!要接收几点的地址,,,看看要求,,,我的天那,,,认真看吧,,自动应答时,,接收方和发送方的EN_AA都要打开,,,接收方也要设置有效位,,跟发送的应该一致,,,自动应答RX自动应答功能减少了外部MCU 的工作量并且在鼠标/键盘等应用中也可以不要求硬件一定有SPI 接口因此降低成本减少电流消耗自动重应答功能可以通过SPI 口对不同的数据通道分别进行配置在自动应答模式使能的情况下收到有效的数据包后系统将进入发送模式并发送确认信号发送完确认信号后系统进入正常工作模式工作模式由PRIM_RX 位和CE 引脚决定自动重发功能ART (TX)自动重发功能是针对自动应答系统的发送方启动重发数据的时间长度在每次发送结束后系统都会进入接收模式并在设定的时间范围内等待应答信号接收到应答信号后系统转入正常发送模式如果TX FIFO 中没有待发送的数据且CE 脚电平为低则系统将进入待机模式I 如果没有收到确认信号则系统返回到发送模式并重发数据直到收到确认信号或重发次数超过设定值达到最大的重发次数有新的数据发送或PRIM_RX 寄存器配置改变时丢包计数器复位 数据包识别和CRC 校验应用于增强型ShockBurst TM模式下每一包数据都包括两位的PID 数据包识别来识别接收的数据是新数据包还是重发的数据包PID 识别可以防止接收端同一数据包多次送入MCU 在发送方每从MCU 取得一包新数据后PID 值加一PID 和CRC 校验应用在接收方识别接收的数据是重发的数据包还是新数据包如果在链接中有一些数据丢失了则PID 值与上一包数据的PID 值相同如果一包数据拥有与上一包数据相同的PID 值nRF24L01将对两包数据的CRC 值进行比较如果CRC 值也相同的话就认为后面一包是前一包的重发数据包而被舍弃1接收方接收方对新接收数据包的PID 值与上一包进行比较如果PID 值不同则认为接收的数据包是新数据包如果PID 值与上一包相同则新接收的数据包有可能与前一包相同接收方必须确认CRC 值是否相等如果CRC 值与前一包数据的CRC 值相等则认为是同一包数据并将其舍弃 2发送方每发送一包新的数据则发送方的PID 值加一图6PID 值生成和检测CRC 校验的长度是通过SPI 接口进行配置的一定要注意CRC 计算范围包括整个数据包地址PID确实,,减小了编程量,,,额,,,高四位设置,,额,,,两个CNT 就复位了,,,和有效数据等若CRC 校验错误则不会接收数据包这一点是接收数据包的附加要求在上图没有说明载波检测CD当接收端检测到射频范围内的信号时将CD 置高否则CD 为低内部的CD 信号在写入寄存器之前是经过滤波的内部CD 高电平状态至少保持128us 以上在增强型ShockBurst TM 模式中只有当发送模块没有成功发送数据时推荐使用CD 检测功能如果发送端PLOS_CNT 显示数据包丢失率太高时可将其设置位接收模式检测CD 值如果CD 为高说明通道出现了拥挤现象需要更改通信频道如果CD 为低电平状态距离超出通信范围可保持原有通信频道但需作其它调整数据通道nRF24L01配置为接收模式时可以接收6路不同地址相同频率的数据每个数据通道拥有自己的地址并且可以通过寄存器来进行分别配置数据通道是通过寄存器EN_RXADDR 来设置的默认状态下只有数据通道0和数据通道1是开启状态的 每一个数据通道的地址是通过寄存器RX_ADDR_Px 来配置的通常情况下不允许不同的数据通道设置完全相同的地址数据通道0有40位可配置地址数据通道1~5的地址为32位共用地址+各自的地址最低字节图7所示的是数据通道1~5的地址设置方法举例所有数据通道可以设置为多达40位但是1~5数据通道的最低位必须不同图7 通道0~5的地址设置当从一个数据通道中接收到数据并且此数据通道设置为应答方式的话则nRF24L01在收到数据后产生应答信号此应答信号的目标地址为接收通道地址 寄存器配置有些是针对所有数据通道的有些则是针对个别的如下设置举例是针对所有数据通道的 CRC 使能/禁止 CRC 计算 接收地址宽度 频道设置无线数据通信速率 LNA 增益 射频输出功率寄存器配置,,,注意了丗不同地址丆相同频率,,,不允许配置相同的地址的,,,额,,,这的目标地址为其接受到的地址,,,这么多是相同的,,,nRF24L01所有配置都在配置寄存器中所有寄存器都是通过SPI 口进行配置的 SPI 接口SPI 接口是标准的SPI 接口其最大的数据传输率为10Mbps 大多数寄存器是可读的 SPI 指令设置SPI 接口可能用到的指令在下面有所说明CSN 为低后SPI 接口等待执行指令每一条指令的执行都必须通过一次CSN 由高到低的变化 SPI 指令格式<命令字由高位到低位每字节>AAAAA AAAAA 1-32读操作全部从字节当读有效数据完成后寄存器中有效数据被清除应用于接收模式下1-32开始应用于发射模式下应用于发射模式下寄存器应用于接收模式下在传输应答信号过程中不应执行此指令信号过程中执行此指令的话将使得应答信号不能被完整的传输重新使用上一包有效数据当数据包被不断的重新发射空操作寄存器可能操作单字节或多字节寄存器当访问多字节寄存器时首先要读/写的是最低字节的高位在所有多字节寄存器被写完之前可以结束写SPI 操作在这种情况下没有写完的高字节保持原有内容不变例如RX_ADDR_P0寄存器的最低字节可以通过写一个字节给寄存器RX_ADDR_P0来改变在CSN 状态由高变低后可以通过MISO 来读取状态寄存器的内容 中断nRF24L01的中断引脚IRQ 为低电平触发当状态寄存器中TX_DS RX_DR 或MAX_RT 为高时触发中断当MCU 给中断源写1时中断引脚被禁止可屏蔽中断可以被IRQ 中断屏蔽通过设置可屏蔽中断位为高则中断响应被禁止默认状态下所有的中断源是被禁止的SPI 时序图8910和表910给出了SPI 操作及时序在写寄存器之前一定要进入待机模式或掉电模式在图8至图10中用到了下面的符号Cn-SPI 指令位 Sn-状态寄存器位Dn-数据位备注由低字节到高字节每个字节中高位在前图8SPI 读操作不会出现无线命令的配置,,,即:设置MASK 为高,,所以说写之前要把CSN 拉低,,,,图9SPI写操作图10SPI NOP 操作时序图表9SPI参考时间C load=5pF表10SPI参考时间C load=10pF寄存器地址所有未定义位可以被读出其值为0’地址 参数 位 复位值类型 描述 00 寄存器配置寄存器 reserved 7 0 R/W 默认为0 MASK_RX_DR 6R/W 可屏蔽中断RX_RD1IRQ 引脚不显示RX_RD 中断0RX_RD 中断产生时IRQ 引脚电平为低MASK_TX_DS 5 0 R/W 可屏蔽中断TX_DS1IRQ 引脚不显示TX_DS 中断0TX_DS 中断产生时IRQ 引脚电平为低MASK_MAX_RT 4 0 R/W 可屏蔽中断MAX_RT1IRQ 引脚不显示TX_DS 中断0MAX_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:发射模式01 EN_AA Enhanced ShockBurst TM 使能自动应答功能此功能禁止后可与nRF2401通讯 Reserved 7:6 00 R/W 默认为0 ENAA_P5 5 1 R/W 数据通道5自动应答允许 ENAA_P4 4 1 R/W 数据通道4自动应答允许 ENAA_P3 3 1 R/W 数据通道3自动应答允许 ENAA_P2 2 1 R/W 数据通道2自动应答允许 ENAA_P1 1 1 R/W 数据通道1自动应答允许 ENAA_P0 0 1 R/W 数据通道0自动应答允许 02 EN_RXADDR 接收地址允许 Reserved 7:6 00 R/W 默认为00 ERX_P5 5 0 R/W 接收数据通道5允许 ERX_P4 4 0 R/W 接收数据通道4允许 ERX_P3 3 0 R/W 接收数据通道3允许 ERX_P2 2 0 R/W 接收数据通道2允许 ERX_P1 1 1 R/W 接收数据通道1允许 ERX_P0 0 1 R/W 接收数据通道0允许 03 SETUP_AW 设置地址宽度所有数据通道 Reserved 7:2 00000 R/W 默认为00000 AW 1:0 11 R/W 接收/发射地址宽度‘00’-无效‘01’-3字节宽度 ‘10’-4字节宽度 ‘11’-5字节宽度04 SETUP_RETR 建立自动重发允许–1Mbps ‘1’-18dBm当接收到有效数据后置一接收数据通道号数据通道号寄存器满标志寄存器满当写存器复位当丢失15个数据包后此寄存器重启 ARC_CNT 3:0 0 R 重发计数器发送新数据包时此寄存器复位09 CDReserved 7:1 000000 RCD 0 0 R 载波检测0A RX_ADDR_P0 39:0 0xE7E7E7E7E7 R/W 数据通道0接收地址最大长度:5个字节先写低字节所写字节数量由SETUP_AW设定0B RX_ADDR_P1 39:0 0xC2C2C2C2C2 R/W 数据通道1接收地址最大长度:5个字节先写低字节所写字节数量由SETUP_AW设定0C RX_ADDR_P2 7:0 0xC3 R/W数据通道2接收地址最低字节可设置高字节部分必须与RX_ADDR_P1[39:8]相等0D RX_ADDR_P3 7:0 0xC4 R/W数据通道3接收地址最低字节可设置高字节部分必须与RX_ADDR_P1[39:8]相等0E RX_ADDR_P4 7:0 0xC5 R/W数据通道4接收地址最低字节可设置高字节部分必须与RX_ADDR_P1[39:8]相等0F RX_ADDR_P5 7:0 0xC6 R/W数据通道5接收地址最低字节可设置高字节部分必须与RX_ADDR_P1[39:8]相等10 TX_ADDR 39:0 0xE7E7E7E7E7 R/W 发送地址先写低字节在增强型ShockBurst TM模式下RX_ADDR_P0与此地址相等11 RX_PW_P0Reserved 7:6 00 R/W 默认为00RX_PW_P0 5:0 0 R/W 接收数据通道0有效数据宽度(1到32字节)0: 设置不合法1: 1字节有效数据宽度……32: 32字节有效数据宽度12 RX_PW_P1Reserved 7:6 00 R/W 默认为00RX_PW_P1 5:0 0 R/W 接收数据通道1有效数据宽度(1到32字节)0: 设置不合法1: 1字节有效数据宽度……32: 32字节有效数据宽度13 RX_PW_P2Reserved 7:6 00 R/W 默认为00RX_PW_P2 5:0 0 R/W 接收数据通道2有效数据宽度(1到32字节)0: 设置不合法1: 1字节有效数据宽度……32: 32字节有效数据宽度14 RX_PW_P3Reserved 7:6 00 R/W 默认为00RX_PW_P3 5:0 0 R/W 接收数据通道3有效数据宽度(1到32字节)0 设置不合法1: 1字节有效数据宽度……32: 32字节有效数据宽度15 RX_PW_P4Reserved 7:6 00 R/W 默认为00RX_PW_P4 5:0 0 R/W 接收数据通道4有效数据宽度(1到32字节)0: 设置不合法1: 1字节有效数据宽度……32: 32字节有效数据宽度16 RX_PW_P5Reserved 7:6 00 R/W 默认为00RX_PW_P5 5:0 0 R/W 接收数据通道5有效数据宽度(1到32字节)0: 设置不合法1: 1字节有效数据宽度……32: 32字节有效数据宽度17 FIFO_STATUS 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寄存器非空N/A TX_PLD 255:0 WN/A RX_PLD 255:0 R表11nRF24L01寄存器地址与nRF24XX兼容的寄存器配置如何建立nRF24L01从nRF2401/ nRF2402/ nRF24E1/ nRF24E2接收数据使用与nRF2401/ nRF2402/ nRF24E1/ nRF24E2相同的CRC配置设置PRIM_RX位为1相应通道禁止自动应答功能与发射模块使用相同的地址宽度与发射模块使用相同的频道在nRF24L01和nRF2401/ nRF2402/ nRF24E1/ nRF24E2两端都选择1Mbit/s的数据传输率设置正确的数据宽度设置PWR_UP和CE为高即频率相同,,,如何建立nRF24L01发射nRF2401/ nRF2402/ nRF24E1/ nRF24E2接收数据使用与nRF2401/ nRF2402/ nRF24E1/ nRF24E2相同的CRC 配置 设置PRIM_RX 位为0设置自动重发计数器为0禁止自动重发功能与nRF2401/ nRF2402/ nRF24E1/ nRF24E2使用相同的地址宽度 与nRF2401/ nRF2402/ nRF24E1/ nRF24E2使用相同的频道在nRF24L01和nRF2401/ nRF2402/ nRF24E1/ nRF24E2两端都选择1Mbit/s 的数据传输率 设置PWR_UP 为高发送与nRF2401/ nRF2402/ nRF24E1/ nRF24E2寄存器配置数据宽度相同的数据长度 设置CE 为高启动发射打包描述增强型ShockBurst TM 模式下的数据包形式前导码 地址35字节 9位标志位 数据132字节 CRC 校验 0/1/2字节ShockBurst TM 模式下与nRF2401/ nRF2402/ nRF24E1/ nRF24E2相兼容的数据包形式前导码 地址35字节 数据132字节 CRC 校验0/1/2字节1在发送模式下加入前导码从接收的数据包中自动去除地址PID 其中两位七位保留用作将来与其它产品相兼容nRF24L01 校验的多项式是校验的多项式是12重要的时序数据下面是nRF24L01部分工作时序数据nRF24L01时序信息nRF24L01时序最大值 最小值 参数名 掉电模式待机模式1.5ms T pd2stby 待机模式发送/接收模式 130usT stby2aCE 高电平保持时间10us Thce CSN 为低电平CE 上升沿的延迟时间4us T pece2csn表13nRF24L01工作时序nRF24L01在掉电模式下转入发射模式或接收模式前必须经过1.5ms 的待机模式注意当关掉电源VDD 后寄存器配置内容丢失模块上电后需重新进行配置最好禁止自动重发功能,,,增强型ShockBurst模式时序图11增强型ShockBurst TM模式发送一包数据时序2Mbps图11所示是发送一包数据并收到应答信号的示意图数据送入发送模块部分没有在图中显示接收模块转入接收模式CE=1发射模块配置为发射模式CE=1持续至少10us 130us 后启动发射再过37us 后发送一字节数据发送结束后发送模块自动转入接收模式等待应答信号发送模块在收到应答信号后产生中断通知MCU IRQ (TX_DS)=>TX-data sent(数据发送完)接收模块接收到数据包后产生中断通知MCU IRQ (RX_DR)=>RX-data ready(数据接收完毕)外围RF 信息 天线输出ANT1和ANT2输出脚给天线提供稳定的RF 输出这两个脚必须连接到VDD 的直流通路或者通过RF 扼流圈或者通过天线双极的中心点在输出功率最大时0dBm 推荐使用负载阻抗为15+j88通过简单的网络匹配可以获得较低的阻抗例如50Ω输出功率调节RF_PWR 输出功率 电流消耗11 0 dBm 11.3mA 10 -6 dBm 9.0 mA 01 -12 dBm 7.5 mA 00 -18 dBm 7.0 mA 工作条件VDD=3.0V ,VSS=0V ,T A =27,负载=15+j88表14nRF24L01输出功率设置接收完应答信号后才产生中断,,,。
(完整word版)NRF24L01详细教程
先来看接口电路,使用的IO 口不是唯一的哦,可随意定义接口,当然是在使用IO 口模拟SPI 且IRQ 中断引脚不使用的使用查询方法判断接收状态的情况下了。
作为初探我们就是用简单的IO 模拟SPI 的方法了,中断使用查询的方式。
那么该教程讲解的接口与单片机的连接如下:首先您需要了解NRF24L01,请参阅“NRF24L01 芯片中文资料”或者“NRF24L01 芯片英文资料”。
我们的教程是以一个简单的小项目为大家展示NRF24L01 的使用方法与乐趣。
我们所写教程均是以这种方式的呢,让您在学习的时候明白它能做什么,使您学起来不至于枯燥无味。
作为简易的教程,我们只需要知道它是怎么使用的就够了,我们本教程的目的是用NRF24L01 发送数据和接收数据,且接收方会对比发送的数据与接收的数据,若完全相同则控制LED 闪烁一次,并且把接收到的数据通过串口发送到PC 端,通过串口工具查看接收到的数据。
具体的要求如下:1、具备发送和接收的能力。
2、发送32 个字节的数据,接收方接收到正确数据之后给予提示,通过LED 闪烁灯形式。
3、把接收到的数据传送到PC 进行查看。
4、发送端每隔大约1.5 秒发送一次数据,永久循环。
以上是程序的要求,若您想自行设计出硬件接口,您也是可以添加一条呢:使用DIY 方式设计NRF24L01 的接口板,且包含含单片机平台,使用PCB 方式或者万用板方式均可。
如果您想让自己学的很扎实,那么推荐您自行做出接口板子呢。
当然若您的能力不足,那么我们不推荐自行做板呢,因为这样会增加您学习的难度,反而起到了反效果呢。
我们知道NRF24L01 的供电电压是1.9V~3.6V 不能超过这个范围,低了不工作,高了可能烧毁NRF24L01 芯片。
我们常用的STC89C52 的单片机的供电电压是5V,我们不能直接给24L01 这个模块供电,我们需要使用AMS1117-3.3V 稳压芯片把5V 转成3.3V 的电压为24L01 模块供电。
nrf24l01模块与单片机通信方式
nrf24l01模块与单片机通信方式一、nRF24L01模块与单片机的通信方式1.基于SPI通信协议的数据交换nRF24L01模块与单片机基于SPI通信协议进行数据交换。
SPI是一种同步串行通信协议,它通过四个信号线进行通信:MOSI、MISO、SCK和CSN。
在这四个信号线中,MOSI用于发送数据,MISO用于接收数据,SCK用于同步时钟信号,而CSN用于片选信号。
这种通信方式具有传输速度快、数据稳定性高、抗干扰能力强等优点。
2.控制引脚与SPI通信引脚的配置nRF24L01模块的控制引脚包括CE、CSN、IRQ,这些引脚可用于控制模块的开启、关闭以及接收中断等功能。
SPI通信引脚包括MOSI、MISO、SCK,这些引脚可用于实现与单片机之间的数据传输。
值得注意的是,这些引脚可以直接接普通的IO口,而不必特意选择SPI外设对应的引脚。
二、nRF24L01模块的应用场景1. 一对多通信当有两个以上的nRF无线模块且代码中未设置SPI片选信号时,可以实现一对多通信(即一个发多个收到该信息)。
这种通信方式在需要多个接收方的情况下非常实用,可以有效提高通信效率,降低系统成本。
2.多种通信模式的选择nRF24L01模块支持多种通信模式,如广播模式、多路复用模式等。
用户可以根据实际需求选择合适的通信模式,以满足不同场景下的应用要求。
3.远程控制与监测nRF24L01模块可应用于远程控制与监测领域,如智能家居、工业自动化、智能交通等。
通过无线通信,可以实现远程控制设备的开关、调节参数以及实时监测设备状态等功能。
4.数据传输与存储nRF24L01模块还可应用于数据传输与存储领域,如物联网、传感器网络等。
在这些场景下,nRF24L01模块可以实现传感器数据的实时采集、传输和存储,为用户提供便捷的数据处理方案。
nRF24L01模块与单片机的通信方式在实际应用中具有广泛的应用价值,可以为各类工程项目提供可靠的无线通信解决方案。
RF24L01中文详细资料 datasheet
待机模式 低电平
掉电模式 -
待机模式 待机模式 I 在保证快速启动的同时减少系统平均消耗电流 在待机模式 I 下 晶振正常工作 在待机
模式 II 下部分时钟缓冲器处在工作模式 当发送端 TX FIFO 寄存器为空并且 CE 为高电平时进入待机模式 II 在待机模式期间 寄存器配置字内容保持不变
掉电模式 在掉电模式下,nRF24L01 各功能关闭 保持电流消耗最小 进入掉电模式后 nRF24L01 停止工作
描述 确认信号 应答信号 自动重发 芯片使能 时钟信号 循环冗余校验 片选非 增强型 ShockBrustTM 高斯键控频移 中断请求 工业 科学 医学 低噪声放大 最低有效位 最低有效字节 兆位/秒 微控制器 主机输入从机输出 主机输出从机输入 最高有效位 最高有效字节 印刷电路板 数据包误码率 数据包识别位 载波 接收源 发射源 掉电 上电 接收 接收数据准备就绪 串行可编程接口 发送 已发送数据
引脚及其功能
引脚 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
名称 CE CSN SCK MOSI MISO IRQ VDD VSS XC2 XC1 VDD_PA ANT1 ANT2 VSS VDD IREF VSS VDD DVDD VSS
掉电模式和待机模式下电流消耗更低
快速参考数据
参数
数值
最低供电电压
1.9
最大发射功率
0
最大数据传输率
2000
发射模式下 电流消耗 0dBm
11.3
接收模式下电流消耗 2000kbps
12.3
温度范围
-40~ +85
数据传输率为 1000kbps 下的灵敏度
nrf24l01中文资料
nrf24l01中⽂资料NRF24L01⼀、初步认识⼀下NRF24L01是Nordic公司研发的⼀款2.4G通信芯⽚。
它不是zigbee、不是蓝⽛、不是wifi,它拥有的是⾃⼰的⼀套协议。
既然是通信芯⽚,⽽且有⾃⼰的协议,那说明这个芯⽚只能是⽤在NRF24L01与NRF24L01或者Nordic公司此系列的芯⽚通信,⼀般情况下,⽤在2个NRF24L01之间的通信,任何⼀个模块都可以设置为接收或者发送模式,⽽且可由主控单⽚机随时根据需要设置为发送或者接收模式。
⼆、深⼊认识⼀下NRF24L01是⼀个长着20个引脚的数字射频芯⽚,内部有若⼲寄存器,外部留有spi接⼝,外部单⽚机通过spi接⼝配置此芯⽚内部的寄存器。
内部寄存器⼤概分为控制寄存器和数据寄存器。
我们可以利⽤⽤单⽚机把它配置为接收模式或发送模式,还可以配置频道、地址、每次发送的字节数、是否带CRC校验、功率等。
配置成发送模式以后,⽤单⽚机把要发送的数据写进去,它就会⾃动把数据发出去;配置成接收模式以后,单⽚机通过观察它的IRQ引脚,就可以知道是否接收到了数据,IRQ为低电平,说明接收到了数据,单⽚机可以通过SPI⼝把接收到数据取出来。
三、通信条件两个nrf24l01通信,需要满⾜3个条件相同:1.频道相同(设置频道寄存器RF_CH)2.地址相同(设置TX_ADDR和RX_ADDR_P0相同)3.每次发送接收的字节数相同(如果设置了通道的有效数据宽度为n,那么每次发送的字节数也必须为n,当然,n<=32)四、是否可以⼀对多相互通信?答:可以。
nrf24l01最多⼀对⼏个呢?答案是⽆数个!官⽅⼿册上说,nrf24l01可以⼀对六,指的是⾃⾝的通道有6个,⽽且这种模式只能是1收6发,不能1发6收。
所以我们⼀般不⽤这种⽅式。
我们⼀般只⽤nrf24l01的通道0,通过改变频道和地址来实现1对多的互发。
它属于2.4G芯⽚,但实际上,可以在2.4G到2.5G之间的频道上通信,⼀共有125个频道,它的地址是5字节的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#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 registervalue CSN = 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 register SPI_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 ucharfor(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, 0x0e);//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,激发数据发送inerDelay_us(10);}/************************************主函数************************************************************/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 灯闪烁Delay(200);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之间切换的时候,对方的灯闪烁会有一定的延时,另外本程序没有消除按键的抖动。