nRF24L01基于arduino UNO板的收发程序(无bug)

helldealer2015 2015-07-06 09:41:52
楼主处女贴,贴出最近写的基于arduino UNO板的nRF24L01接收与发射程序,实现功能:发送方每隔1.5s发送16字节数据包给接收方。程序无BUG,但是也有一些问题:比如我程序中发射过程中CE一直是高,没有做到低功耗。贴出来供大家交流,共同进步
...全文
2042 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zkk12345 2015-08-28
  • 打赏
  • 举报
回复
您好,此贴非常有用。请问可以放出接受程序和注释学习一下吗?
helldealer2015 2015-07-06
  • 打赏
  • 举报
回复
上面的连起来是发送程序,程序的详细中文注解在下面的接收程序里
helldealer2015 2015-07-06
  • 打赏
  • 举报
回复
/*-------------------------------- Function: clearTXFIFO() Description: Clear TXFIFO geg. */ void clearTXFIFO(void){ digitalWrite(CSN,LOW); SPI.transfer(FLUSH_TX); delayMicroseconds(10); digitalWrite(CSN,HIGH); } /*-------------------------------- Function send_data() Description: This function initializes one nRF24L01 chip to TX Mode, AND send data. */ unsigned char send_data(unsigned char *buf) { unsigned int uiNum; byte sta; power_off(); digitalWrite(CE,LOW); RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0 RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans... RW_Reg(WRITE_REG + RF_CH, 0); // Select RF channel 40 RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, 0x05); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, 0x05); // RX_Addr0 same as TX_Adr for Auto.Ack RW_Reg(FLUSH_TX,0x00); SPI_Write_Buf(WR_TX_PLOAD, buf, TX_PLOAD_WIDTH); // Writes data to TX payload //Serial.println(SPI_Read(TX_ADDR),HEX); RW_Reg(WRITE_REG + CONFIG, 0x0e); // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:TX. MAX_RT & TX_DS enabled.. digitalWrite(IRQ,HIGH); digitalWrite(CE,HIGH); delayMicroseconds(200); //digitalWrite(CE,LOW); //Serial.println("sendhalf"); uiNum = 0; while(digitalRead(IRQ) == 1) { if (uiNum > 20000) { uiNum = 0; ifnnrf_CLEAR_ALL(); // Serial.print("IRQ == 1"); //delay(1000); return 0; } else { uiNum++; delayMicroseconds(10); } } /* if(digitalRead(IRQ)==0) { Serial.print("IRQ == 0!!!"); } sta = SPI_Read(STATUS); Serial.print(sta,HEX); sta = SPI_Read(FIFO_STATUS); Serial.println(sta,HEX); */ if (SPI_Read(STATUS) & STA_MARK_TX) { RW_Reg(WRITE_REG+STATUS,0xFF); // 清除所有中断标志 clearTXFIFO(); // Serial.print("STA1"); return 1; } else { RW_Reg(WRITE_REG+STATUS,0xFF); // 清除所有中断标志 clearTXFIFO(); //Serial.print("STA0"); } return 0; } /*------------------------- Function: receive_data() Description: Receive data from the sender. */ unsigned char receive_data(unsigned char *buf){ unsigned char RXflag = 0; if(digitalRead(IRQ) == 0){ if (SPI_Read(STATUS) & STA_MARK_RX) { SPI_Read_Buf(RD_RX_PLOAD,buf,TX_PLOAD_WIDTH); RXflag = 1; RW_Reg(WRITE_REG+STATUS,0xff); // 清除所有中断标志 } else { ifnnrf_CLEAR_ALL(); RXflag = 0; } } digitalWrite(IRQ,HIGH); return RXflag; } /*------------------------- */ void SPI_CLR_Reg(byte R_T){ digitalWrite(CSN,LOW); if(R_T == 1) SPI.transfer(FLUSH_TX); else SPI.transfer(FLUSH_RX); digitalWrite(CSN,HIGH); } /*-------------------------- */ void ifnnrf_CLEAR_ALL(){ SPI_CLR_Reg(0); SPI_CLR_Reg(1); RW_Reg(WRITE_REG+STATUS,0xff); pinMode (IRQ, INPUT); digitalWrite(IRQ,HIGH); }
helldealer2015 2015-07-06
  • 打赏
  • 举报
回复
#include <SPI.h> #define TX_ADR_WIDTH 5 // 5 unsigned chars TX(RX) address width #define TX_PLOAD_WIDTH 16 // 32 unsigned chars TX payload byte READ_REG = 0x00; // Define read command to register byte WRITE_REG = 0x20; // Define write command to register byte RD_RX_PLOAD = 0x61; // Define RX payload register address byte WR_TX_PLOAD = 0xA0; // Define TX payload register address byte FLUSH_TX = 0xE1; // Define flush TX register command byte FLUSH_RX = 0xE2; // Define flush RX register command #define REUSE_TX_PL 0xE3 // Define reuse TX payload register command #define NOP 0xFF // Define No Operation, might be used to read status register //***************************************************// // SPI(nRF24L01) registers(addresses) #define CONFIG 0x00 // 'Config' register address #define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address #define EN_RXADDR 0x02 // 'Enabled RX addresses' register address #define SETUP_AW 0x03 // 'Setup address width' register address #define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address #define RF_CH 0x05 // 'RF channel' register address #define RF_SETUP 0x06 // 'RF setup' register address #define STATUS 0x07 // 'Status' register address #define OBSERVE_TX 0x08 // 'Observe TX' register address #define CD 0x09 // 'Carrier Detect' register address #define RX_ADDR_P0 0x0A // 'RX address pipe0' register address #define RX_ADDR_P1 0x0B // 'RX address pipe1' register address #define RX_ADDR_P2 0x0C // 'RX address pipe2' register address #define RX_ADDR_P3 0x0D // 'RX address pipe3' register address #define RX_ADDR_P4 0x0E // 'RX address pipe4' register address #define RX_ADDR_P5 0x0F // 'RX address pipe5' register address #define TX_ADDR 0x10 // 'TX address' register address #define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address #define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address #define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address #define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address #define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address #define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address #define FIFO_STATUS 0x17 // 'FIFO Status Register' register address #define STA_MARK_RX 0X40 #define STA_MARK_TX 0X20 #define STA_MARK_MX 0X10 byte TX_ADDRESS[TX_ADR_WIDTH] = { 0x34,0x43,0x10,0x10,0x01}; // Define a static TX address byte const RX_ADDRESS[TX_ADR_WIDTH] = { 0x34,0x43,0x10,0x10,0x01}; //***************************************************************// // FUNCTION's PROTOTYPES // //**************************************************************** void RF_init(); // Init HW or SW SPI byte SPI_Read(byte reg); // Read one unsigned char from nRF24L01 unsigned char RW_Reg(byte reg, byte value); // Write one unsigned char to register 'reg' unsigned char SPI_Write_Buf(byte reg, byte *pBuf, byte bytes); // Writes multiply unsigned chars to one register unsigned char SPI_Read_Buf(byte reg, byte *pBuf, byte bytes); // Read multiply unsigned chars from one register void RX_Mode(void); void clearTXFIFO(void); unsigned char send_data(unsigned char *buf); unsigned char receive_data(unsigned char *buf); void ifnnrf_CLEAR_ALL(); void SPI_CLR_Reg(byte R_T); int IRQ = 8; int CE = 9; int CSN = 10; unsigned char txData[32]={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; unsigned char rxData[32]={ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}; void setup() { pinMode (CSN, OUTPUT); pinMode (CE, OUTPUT); pinMode (IRQ, INPUT); digitalWrite(IRQ,HIGH); SPI.begin(); Serial.begin(9600); RF_init(); delay(10); Serial.print("System initialization compeleted!"); void RX_Mode(); } void loop() { if(send_data(txData)==1) { Serial.println("send success"); delay(1500); }else { Serial.println("send fail"); delay(1500); } } //--------------------------------------------------------------------- //NRF24l01 function /*----------------------- Function: init(); Description: initialize the NRF24L01 chip. */ void RF_init(){ digitalWrite(CE,LOW); //chip enable digitalWrite(CSN,HIGH); //Spi disable } /*------------------------ Function: RW_Reg(); Description: Writes value 'value' to register 'reg' */ unsigned char RW_Reg(byte reg,byte value){ unsigned char sta = 0; digitalWrite(CSN,LOW); sta = SPI.transfer(reg); SPI.transfer(value); digitalWrite(CSN,HIGH); return(sta); } /*-------------------------- */ byte SPI_Read(byte reg) { byte reg_val; digitalWrite(CSN,LOW); // CSN low, initialize SPI communication... SPI.transfer(reg); // Select register to read from.. reg_val = SPI.transfer(0); // ..then read registervalue digitalWrite(CSN,HIGH); // CSN high, terminate SPI communication return(reg_val); // return register value } /*--------------------------- Function:SPI_Read_Buf(); Description: Reads 'unsigned chars' of unsigned chars from regester 'reg' Typically used to read RX payload,RX/TX address */ unsigned char SPI_Read_Buf(byte reg,byte *pBuf,byte bytes){ unsigned char sta,byte_ctr; digitalWrite(CSN,LOW); sta = SPI.transfer(reg); for(byte_ctr=0;byte_ctr<bytes;byte_ctr++) pBuf[byte_ctr] = SPI.transfer(0); digitalWrite(CSN,HIGH); return(sta); } /*------------------------------ Function:SPI_Write_Buf() Description: Writes contents of buffer '*pBuf' to nRF24L01 Typically used to write TX payload,Rx/Tx address */ unsigned char SPI_Write_Buf(byte reg,byte *pBuf,byte bytes){ unsigned char sta,byte_ctr; digitalWrite(CSN,LOW); sta = SPI.transfer(reg); for(byte_ctr=0;byte_ctr<bytes;byte_ctr++) SPI.transfer(*pBuf++); digitalWrite(CSN,HIGH); return(sta); } /*------------------------------- Function power_off() Description: This function initializes one nRF24L01 device to Power off Mode. */ void power_off(){ digitalWrite(CE,LOW); RW_Reg(WRITE_REG+CONFIG,0x0D); digitalWrite(CE,HIGH); delay(160); } /*------------------------------- Function RX_Mode() Description: This function initializes one nRF24L01 device to RX Mode Set RX address,writes RX payload width,select RF channel, datarate & LNA HCURR. After init,CE is TOGGLED to high, which means that this device is now ready to receave a datapacket. */ void RX_Mode(){ power_off(); digitalWrite(CE,LOW); SPI_Write_Buf(WRITE_REG+TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH); // Writes TX_Address to nRF24L01 SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH); RW_Reg(WRITE_REG+EN_AA,0x00); RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0 RW_Reg(WRITE_REG + RF_CH, 0); // Select RF channel 40 RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width RW_Reg(WRITE_REG + RF_SETUP, 0x07); // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(2 unsigned chars) & Prim:RX. RX_DR enabled.. RW_Reg(WRITE_REG+STATUS,0xff); // 清除所有中断标志 digitalWrite(CE,HIGH); // Set CE pin high to enable RX device delay(1); }
一、5G技术的发展简介2018年6月,5G NR独立组网标准冻结,标志着5G时代的来临。5G仅仅是比4G的网速更快吗?绝非如此。5G不仅提供了极高的网速,而且将网络时延、可靠性、容量等性能大幅提升,使得5G成为一个万物互联的平台,从而可以极大地推动大量相关产业的发展。中国信息通信研究院在其研究报告中称:“第五代移动通信技术(5G)正在阔步前行,它将以全新的网络架构,提供至少十倍于4G 的峰值速率、毫秒级的传输时延和千亿级的连接能力,开启万物广泛互联、人机深度交互的新时代。”中国电信在其《5G技术白皮书》中也写道:“5G将是引领科技创新、实现产业升级、发展新经济的基础性平台”。  由此可以看到,5G技术的应用,将不再局限于用户间的通信联系以及个人用户的信息获取,而是渗透到了诸多行业,满足各种行业应用的通信需求,从而推动整个社会的智能化进程,这将是一场广泛而深刻的通信变革。二、本课程的特色这门课程,是我花费了大量的时间,在阅读了大量的资料的基础上,精心编写、录制而成的。这门课程的目标人群是那些已经有了一定的移动通信知识,但对5g网络尚未有系统了解和掌握的朋友们。在编写课件的过程中,我力争做到深入浅出,既能把技术问题探讨到一定的深度,不流于肤浅,又能易于理解,避免晦涩难懂。从内容的选择上,我力争做到全面而系统,对于5G的组网策略、核心网、接入网、承载网、网络切片技术、大规模MIMO和移动边缘计算等内容都纳入了课程内容。如果各位认真地学完这门课程,我想您会对5G移动通信技术有一个相当程度的了解和掌握,您会感到“课有所值”。三、本课程主要内容本课程包括八个方面的内容:1、从1G到5G在这一部分主要讲述了蜂窝移动通信系统的基本概念,1G、2G、3G、4G和5G移动通信系统的特点、发展演变的过程,以及5G的三大应用场景—eMBB(增强移动宽带)、mMTC(海量大连接)、URLLC(低时延高可靠),并以VR/AR(虚拟现实/增强现实)、智能家居、农业传感、智能制造、自动驾驶等具体应用来说明5G在垂直行业的应用场景。2、5G的独立组网和非独立组网模式主要讲述5G的组网方案,包括独立组网的2种模式和非独立组网的3个系列8种模式。课程中对各种组网方式的网络结构、优缺点、对业务的支持情况等进行了详细的分析,讲解了双连接、用户面、控制面、锚点等概念,并且对目前5G网络运营商如何选择各种组网模式进行了介绍。3、5G核心网解析主要讲述5G核心网SBA(基于服务的架构)、网络功能虚拟化、微服务、NF的调用、CUPS(控制面和用户面分离)、网络切片等内容,课程中对5G核心网的总体结构和各个NF(NSSF、NEF、NRF、PCF、UDM、AUSF、AMF、SMF、UPF)的作用都进行了讲解。4、5G接入网架构在这一部分,首先为大家回顾了从2G到4G接入网的发展过程,简述了它们各自的结构和特点。接下来,重点讲解了5G接入网的总体架构,CU、DU、AAU的作用,以及它们之间的功能划分。最后介绍了5G标准支持的多种接入网设备部署方案,包括CU/DU合设的两种方案和CU/DU分设的两种方案,以及它们各自的特点和适用场景。5、5G承载网作为移动通信网的三大子网之一,5G时代的承载网同样需要向前演进。这部分课程首先讲解了5G网络对承载网在带宽、时延、时间同步和网络切片等方面的性能需求。在参考大量文献资料的基础上,我尽量将这些性能需求量化,以期达到能够对实际工作起到指导和参考的作用。在带宽需求方面,针对前传、中传和回传网,分别给出了带宽需求的范围。接下来,课程讲解了5G承载网的技术实现方案,包括前传网的三种技术方案:光纤直连、无源WDM和有源OTN,以及中传和回传网络的通用分层结构、PAM4技术、FLEX-E技术、SR技术等,并介绍了中国移动、中国电信和中国联通的5G中、回传网技术方案:SPN(切片分组网络)、M-OTN(面向移动承载优化的OTN)和IP RAN增强,讲解了这三种技术的发展由来和技术特点。6、MIMO及大规模MIMO技术这一章包括四个部分的内容。第一部分是MIMO技术的原理,主要讲述了MIMO技术的基本概念、历史发展、对网络性能的改善(提高系统容量、对抗多经衰落、降低系统内干扰)等。第二部分讲MIMO技术的应用,主要包括MIMO技术的三种应用方式—空间复用、传输分集和波束成形的技术特点和优势,以及MIMO技术在WLAN、3G、B3G和4G系统的应用。第三部分讲解大规模MIMO技术的原理,包括它的技术特点、对系统性能的改善(信道容量大幅增加、波束更窄、系统内干扰更低、可实现3D波束赋形)以及它的缺点(算法复杂度高等)。第四部分是大规模MIMO技术的应用,主要介绍了它在4G和5G网络的应用,分析了大规模MIMO技术对4G网络容量提升的实测结果。7、5G网络切片技术这一章首先介绍了在5G网络中引入网络切片技术的必要性,以及网络切片技术的定义等内容,然后讲解了实现网络切片的技术基础。网络切片的实现,需要两个主要的技术来支撑,一个是NFV(网络功能虚拟化),另外一个是SDN(软件定义网络),课程中对这两项技术进行了比较详细的介绍。最后讲述了5G网络切片的实现,内容包括核心网切片、接入网切片以及承载网切片的实现,涉及到网络切片的选择、GROUP A、B、C三种切片构成方式、子载波间隔的选择等内容。8、5G与移动边缘计算这一章首先介绍了MEC(移动边缘计算)的起源和发展,追溯了IBM与诺基亚西门子开发的最早的MEC,ETSI在MEC方面的工作,以及3GPP在4G和5G标准中关于MEC的相关内容。接下来,讲解了MEC在5G网络的部署,包括边缘级、区域级和地区级MEC三种部署方式以及它们的适用场景。最后列举了一些具体的应用场景来说明MEC的应用情况,包括视频优化加速、车联网、VR直播和视频优化分析。四、讲师简介老铁于1991年毕业于南开大学电子系。从1994年开始,进入移动通信行业,先后在摩托罗拉公司、中国联通和中国电信的省级公司工作。2011年进入高校,从事移动通信相关课程的教学工作。       在联通和电信工作期间,老铁从事过移动通信网络的建设、规划、优化等工作,可以说在移动通信网络技术方面积累了比较丰富的知识和经验。在联通工作期间,参加过许多技术项目,也获得了一些奖项,包括中国通信标准化协会颁发的科学技术奖一等奖、信息产业部颁发的“CDMA网络创新贡献”奖,以及中国联通的“科技进步奖”三等奖。
nRF24L01 介绍: nRF24L01是一款工作在 2.4~2.5GHz 世界通用ISM频段的单片无线收发器芯片,输出功率、频道选择和协议的设置可以通过SPI接口进行设置。有极低的电流消耗,当工作在发射模式下发射功率为-6dBm时电流消耗为9.0mA,接收模式时为12.3mA。掉电模式和待机模式下电流消耗更低。 nRF24L01参考数据: 供电电压:1.9 V~3.6V; 最大发射功率:0 dBm; 最大数据传输率:2000 kbps; 发射模式下电流消耗(0dBm时):11.3 mA; 接收模式下电流消耗(2000kbps):12.3 mA; 接收模式数据传输率为1000kbps下的 灵敏度:-85 dBm; 掉电模式下电流消耗:900 nA。 淘宝上面有两种nRF24L01模块,一种是单纯的nRF24L01模块,号称传输距离250m的,几块钱就有交易;另外一种是NRF24L01+PA+LNA模块,包含放大,号称可以传输1000m,价格几十块。实际距离视地形和障碍物而定,是否够远只能通过试用确定。 单纯nRF24L01模块做示例: nRF24L01Arduino UNO硬件连接 此模块是使用SPI方式连接,在标准SPI口基础增加CE和CSN引脚: nRF24L01 Arduino UNO VCC <-> 3.3V GND <-> GND CE <-> D9 CSN <-> D10 MOSI<-> D11 MISO<-> D12 SCK <-> D13 IRQ <-> 不接 还有就是nRF24L01属于对传模块。每块芯片既是发射器,也是接收器。所以一般来说,要使用两块nRF24L01+两块Arduino才能进行测试。 实验1 将Sender机A0的AD转换值无线发送到Receiver机,Sender机(A0端与电源两端接一个电位器,阻值随意,一般1k~100k均可) 原理图如截图: 代码: 首先需要安装Mirf库,可以在https://playground.arduino.cc/InterfacingWithHardware/Nrf24L01下载或者本文附件下载。 实验2 将上述的数据绘图表。修改一下输出格式,然后用现成的串口图表软件显示出来。详见附件内容操作说明文档。 上位机: 直接用现成软件比如这个串口猎人。配置如图。依照图片顺序配置成截图一样即可。 附件内容截图:

3,846

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 无线
社区管理员
  • 无线
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧