tag 标签: nRF24L01

相关博文
  • 热度 8
    2015-7-16 17:29
    1469 次阅读|
    0 个评论
    ZQ-CC2500PA模块可适用于多种无线通讯应用,如超低功耗无线收发器、无线传感网络、家庭和楼宇自动化、高级抄表架构(AMI)、无线计量、无线报警和安全系统等。
  • 热度 35
    2014-4-17 16:47
    1215 次阅读|
    0 个评论
      近年来, 随着无线通信技术的发展, 无线通讯设备的集成化越来越高。本文介绍了一种选用高性能、低功耗的32位微处理器STM32F103和射频收发芯片nRF24L01来设计短距离无线数据传输系统的具体方法。   1 系统设计   短距离无线数传系统主要由电源管理器AMC7635、微控制器STM32F103、射频收发器nrf24l01三部分组成。下面分别介绍其关键电路。    1.1 电源电路   本设计的电源采用3.7V锂电池供电, 然后经低压降电源管理芯片AMC7635, 以产生3.0V的电压来为STM32F103和nRF24L01供电, 图1所示是本系统的供电电路。 图1 系统供电电路    1.2 微控制器电路   微控制器选用带ARM Cortex -M3 内核的STM32F103。STM32F103控制器具有高性能、低功耗、低电压等特性, 同时具有高集成度和易于开发的优势。图2所示是该系统中的微控制器电路。控制器与射频收发器nRF24L01的接口采用SPI口来实现, 即图2 中SPICS、MOSI、MISO和SCK四条信号线和CE和INT0两条信号线。另外,该控制器还可以扩展一路主板RS232 口和8 路GPIO口输出。 图2 微控制器电路   1.3 射频收发电路   nRF24L01可工作于2.4 GHz~2.5 GHz ISM 频段, 该收发器内置频率合成器、功率放大器、晶体振荡器、调制器等功能模块, 是一款集成度较高的无线收发器。nRF24L01的外部电路比较简单, 而且融合了增强型ShockBurst技术, 其中输出功率和通信频道可通过程序进行配置。同时,该芯片的功耗极低, 在以-6 dBm的功率发射时,其工作电流只有9 mA;而在接收时, 工作电流只有12.3 mA。nRF24L01的控制电路可与STM32控制器的SPI口和GPIO口相连接。图3所示是该芯片组成的射频收发电路原理图。 图3 射频收发电路   2 系统程序设计   本系统可在STM32F103上移植UCOSII操作系统。系统程序主要分为主机的系统初始化程序、键盘和显示程序及射频收发器nRF24L01的控制程序三大部分。图4所示是其软件程序流程。 图4 系统程序流程图   系统程序设计的关键是UCOSII操作系统的移植和SPI口通信控制。有关操作系统的移植, 芯片厂商在官网上已有范例提供, 本文不再赘述。   下面列出系统SPI初始化及收发函数的程序源码。   void SPI_Initial (void)   当然, 也可以用GPIO口来实现SPI通信, 但前提是通信速率要求不是很高。由于要通过GPIO口模拟实现SPI的突发传送协议, 而且要兼顾其通用性, 故其程序较为复杂。    3 结束语   经现场调试证明, 本文给出的无线数传系统具有成本低, 速率高, 传输可靠等优点。在实际应用中, 还可根据需要将nRF24LOl组成一对一、一对多、多对多的结构。因此, 该系统可以广泛应用于无线测控、文件传输、家庭无线应用、工业控制等场合。
  • 热度 28
    2013-3-26 22:47
    3085 次阅读|
    2 个评论
      第三十七章  无线通信实验       ALIENTKE战舰STM32开发板带有一个2.4G无线模块(NRF24L01模块)通信接口,采用8脚插针方式与开发板连接。本章我们将以NRF24L01模块为例向大家介绍如何在ALIENTEK战舰STM32开发板上实现无线通信。在本章中,我们将使用两块战舰STM32开发板,一块用于发送收据,另外一块用于接收,从而实现无线数据传输。本章分为如下几个部分: 37.1 NRF24L01无线模块简介 37.2 硬件设计 37.3 软件设计 37.4 下载验证 37.1 NRF24L01无线模块简介 NRF24L01无线模块,采用的芯片是NRF24L01,该芯片的主要特点如下: 1)2.4G全球开放的ISM频段,免许可证使用。 2)最高工作速率2Mbps,高校的GFSK调制,抗干扰能力强。 3)125个可选的频道,满足多点通信和调频通信的需要。 4)内置CRC检错和点对多点的通信地址控制。 5)低工作电压(1.9~3.6V)。 6)可设置自动应答,确保数据可靠传输。 该芯片通过SPI与外部MCU通信,最大的SPI速度可以达到10Mhz。本章我们用到的模块是深圳云佳科技生产的NRF24L01,该模块已经被很多公司大量使用,成熟度和稳定性都是相当不错的。该模块的外形和引脚图如图37.1.1所示:     图37.1.1 NRF24L01无线模块外观引脚图 模块VCC脚的电压范围为1.9~3.6V,建议不要超过3.6V,否则可能烧坏模块,一般用3.3V电压比较合适。除了VCC和GND脚,其他引脚都可以和5V单片机的IO口直连,正是因为其兼容5V单片机的IO,故使用上具有很大优势。 关于NRF24L01的详细介绍,请参考NRF24L01的技术手册。 37.2 硬件设计 本章实验功能简介:开机的时候先检测NRF24L01模块是否存在,在检测到NRF24L01模块之后,根据KEY0和KEY1的设置来决定模块的工作模式,在设定好工作模式之后,就会不停的发送/接收数据,同样用DS0来指示程序正在运行。 所要用到的硬件资源如下: 1)  指示灯DS0  2)  KEY0和KEY1按键 3) TFTLCD模块 4)  NRF24L01模块 NRF24L01模块属于外部模块,这里我们仅介绍开发板上NRF24L01模块接口和STM32的连接情况,他们的连接关系如图37.2.1所示:     图37.2.1 NRF24L01模块接口与STM32连接原理图        这里NRF24L01也是使用的SPI2,和W25Q64以及SD卡等共用一个SPI接口,所以在使用的时候,他们分时复用SPI2。本章我们需要把SD卡和W25Q64的片选信号置高,以防止这两个器件对NRF24L01的通信造成干扰。 由于无线通信实验是双向的,所以至少要有两个模块同时能工作,这里我们使用2套ALIENTEK战舰STM32开发板来向大家演示。 37.3 软件设计 打开上一章的工程,首先在HARDWARE文件夹下新建一个NRF24L01的文件夹。然后新建一个24l01.c和24l01.h的文件保存在NRF24L01文件夹下,并将这个文件夹加入头文件包含路径。        打开24l01.c文件,输入如下代码: #include "24l01.h" #include "lcd.h" #include "delay.h" #include "spi.h" const u8 TX_ADDRESS ={0x34,0x43,0x10,0x10,0x01}; //发送地址 const u8 RX_ADDRESS ={0x34,0x43,0x10,0x10,0x01}; //发送地址 //初始化24L01的IO口 void NRF24L01_Init(void) {     RCC-APB2ENR|=13;     //使能PORTB时钟             RCC-APB2ENR|=15;     //使能PORTD时钟     RCC-APB2ENR|=18;     //使能PORTG时钟     //这里pb12和pd2拉高,是为了防止互相影响 .     //因为他们共用一个SPI口.         GPIOB-CRH=0XFFF0FFFF;     GPIOB-CRH|=0X00030000; //PB12 推挽              GPIOB-ODR|=112;      //PB12上拉 防止W25X的干扰                     GPIOD-CRL=0XFFFFF0FF;     GPIOD-CRL|=0X00000300; //PD2 推挽          GPIOD-ODR|=12;       //PD2上拉   禁止SD卡的干扰       GPIOG-CRL=0X00FFFFFF;     GPIOG-CRL|=0X33000000; //PG6 7 推挽             GPIOG-CRH=0XFFFFFFF0;     GPIOG-CRH|=0X00000008; //PG8 输入          GPIOG-ODR|=76;       //PG6 7 8 上拉      SPI2_Init();            //初始化SPI       //针对NRF的特点修改SPI的设置     SPI2-CR1=~(16);     //SPI设备失能     SPI2-CR1=~(11);     //空闲模式下SCK为0 CPOL=0     SPI2-CR1=~(10);     //数据采样从第1个时间边沿开始,CPHA=0      SPI2-CR1|=16;        //SPI设备使能       NRF24L01_CE=0;          //使能24L01     NRF24L01_CSN=1;         //SPI片选取消                } //检测24L01是否存在 //返回值:0,成功;1,失败    u8 NRF24L01_Check(void) {     u8 buf ={0XA5,0XA5,0XA5,0XA5,0XA5};     u8 i;     SPI2_SetSpeed(SPI_SPEED_4); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)     NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址.       NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址      for(i=0;i5;i++)if(buf !=0XA5)break;                                     if(i!=5)return 1;//检测24L01错误       return 0;       //检测到24L01 }        //SPI写寄存器 //reg:指定寄存器地址 //value:写入的值 u8 NRF24L01_Write_Reg(u8 reg,u8 value) {     u8 status;     NRF24L01_CSN=0;                 //使能SPI传输     status =SPI2_ReadWriteByte(reg);//发送寄存器号     SPI2_ReadWriteByte(value);      //写入寄存器的值     NRF24L01_CSN=1;                 //禁止SPI传输         return(status);                 //返回状态值 } //读取SPI寄存器值 //reg:要读的寄存器 u8 NRF24L01_Read_Reg(u8 reg) {     u8 reg_val;         NRF24L01_CSN = 0;          //使能SPI传输           SPI2_ReadWriteByte(reg);   //发送寄存器号     reg_val=SPI2_ReadWriteByte(0XFF);//读取寄存器内容     NRF24L01_CSN = 1;          //禁止SPI传输               return(reg_val);           //返回状态值 }   //在指定位置读出指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len) {     u8 status,u8_ctr;              NRF24L01_CSN = 0;           //使能SPI传输     status=SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值           for(u8_ctr=0;u8_ctr //读出数据     NRF24L01_CSN=1;       //关闭SPI传输     return status;        //返回读到的状态值 } //在指定位置写指定长度的数据 //reg:寄存器(位置) //*pBuf:数据指针 //len:数据长度 //返回值,此次读到的状态寄存器值 u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len) {     u8 status,u8_ctr;           NRF24L01_CSN = 0;          //使能SPI传输     status = SPI2_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值     for(u8_ctr=0; u8_ctr     return status;          //返回读到的状态值 }                  //启动NRF24L01发送一次数据 //txbuf:待发送数据首地址 //返回值:发送完成状况 u8 NRF24L01_TxPacket(u8 *txbuf) {     u8 sta;     SPI2_SetSpeed(SPI_SPEED_8);//spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)       NRF24L01_CE=0;     NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); //写数据到TX BUF  32个字节     NRF24L01_CE=1;//启动发送           while(NRF24L01_IRQ!=0);//等待发送完成     sta=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值           NRF24L01_Write_Reg(WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志     if(staMAX_TX)//达到最大重发次数     {         NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器         return MAX_TX;     }     if(staTX_OK) return TX_OK;//发送完成     return 0xff;//其他原因发送失败 } //启动NRF24L01发送一次数据 //txbuf:待发送数据首地址 //返回值:0,接收完成;其他,错误代码 u8 NRF24L01_RxPacket(u8 *rxbuf) {     u8 sta;                                             SPI2_SetSpeed(SPI_SPEED_8); //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)       sta=NRF24L01_Read_Reg(STATUS);//读取状态寄存器的值            NRF24L01_Write_Reg(WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志     if(staRX_OK)//接收到数据     {         NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据         NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器         return 0;     }          return 1;//没收到任何数据 }                       //该函数初始化NRF24L01到RX模式 //设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR //当CE变高后,即进入RX模式,并可以接收数据了       void NRF24L01_RX_Mode(void) {     NRF24L01_CE=0;        NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //写RX节点地址       NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);    //使能通道0的自动应答        NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01);//使能通道0的接收地址           NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);      //设置RF通信频率            NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //选择通道0的有效数据宽度          NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启       NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式     NRF24L01_CE = 1; //CE为高,进入接收模式 }                       //该函数初始化NRF24L01到TX模式 //设置TX地址,写TX数据宽度,设置RX自动应答的地址,填充TX发送数据,选择RF频道, //波特率和LNA HCURR //PWR_UP,CRC使能 //当CE变高后,即进入RX模式,并可以接收数据了       //CE为高大于10us,则启动发送.   void NRF24L01_TX_Mode(void) {                                                           NRF24L01_CE=0;          NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址     NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK         NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答        NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址      NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a); //设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次     NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);       //设置RF通道为40     NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启       NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断     NRF24L01_CE=1;//CE为高,10us后启动发送 } 此部分代码我们不多介绍,在这里强调一个要注意的地方,在NRF24L01_Init函数里面,我们调用了SPI2_Init()函数,该函数我们在第二十八章曾有提到,在第二十八章的设置里面,SCK空闲时为高,但是NRF24L01的SPI通信时序如图37.3.1所示:   图37.3.1 NRF24L01读写操作时序 上图中Cn代表指令位,Sn代表状态寄存器位,Dn代表数据位。从图中可以看出,SCK空闲的时候是低电平的,而数据在SCK的上升沿被读写。所以,我们需要设置SPI的CPOL和CPHA均为0,来满足NRF24L01对SPI操作的要求。所以,我们在NRF24L01_Init函数里面又单独添加了将CPOL和CPHA设置为0的代码。保存24l01.c文件,加入到HARDWARE组下。接下来打开24l01.h,输入如下代码: #ifndef __24L01_H #define __24L01_H                      #include "sys.h"     //NRF24L01寄存器操作命令 #define READ_REG        0x00  //读配置寄存器,低5位为寄存器地址 ......//省略部分定义 #define FIFO_STATUS     0x17  //FIFO状态寄存器;bit0,RX FIFO寄存器空标志; //bit1,RX FIFO满标志;bit2,3,保留 bit4,TX FIFO空标志;bit5,TX FIFO满标志; //bit6,1, 循环发送上一数据包.0,不循环; //24L01操作线 #define NRF24L01_CE   PGout(6) //24L01片选信号 #define NRF24L01_CSN  PGout(7) //SPI片选信号     #define NRF24L01_IRQ  PGin(8)  //IRQ主机数据输入 //24L01发送接收数据宽度定义 #define TX_ADR_WIDTH    5       //5字节的地址宽度 #define RX_ADR_WIDTH    5       //5字节的地址宽度 #define TX_PLOAD_WIDTH  32     //32字节的用户数据宽度 #define RX_PLOAD_WIDTH  32     //32字节的用户数据宽度 void NRF24L01_Init(void);                 //初始化 void NRF24L01_RX_Mode(void);       //配置为接收模式 void NRF24L01_TX_Mode(void);              //配置为发送模式 u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s); //写数据区 u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s);  //读数据区              u8 NRF24L01_Read_Reg(u8 reg);                                   //读寄存器 u8 NRF24L01_Write_Reg(u8 reg, u8 value);              //写寄存器 u8 NRF24L01_Check(void);                                     //检查24L01是否存在 u8 NRF24L01_TxPacket(u8 *txbuf);                         //发送一个包的数据 u8 NRF24L01_RxPacket(u8 *rxbuf);                        //接收一个包的数据 #endif 部分代码,主要定义了一些24L01的命令字(这里我们省略了一部分),以及函数声明,这里还通过TX_PLOAD_WIDTH和RX_PLOAD_WIDTH决定了发射和接收的数据宽度,也就是我们每次发射和接受的有效字节数。NRF24L01每次最多传输32个字节,再多的字节传输则需要多次传送。 保存24l01.h文件,接下来我们在主函数里面写入我们的实现代码,来达到我们所要求的功能。打开test.c文件在该文件内修改main函数如下: //编辑器限制,省略部分内容 ;       ;u8_ctr++)pbuf =spi2_readwritebyte(0xff);      
  • 热度 23
    2012-2-22 15:06
    895 次阅读|
    0 个评论
    NRF24L01/NRF24L01+是挪威NordicVLSI公司出品的一款新型射频收发器件,采用4 mm×4 mmQFN20封装;NRF24L01/NRF24L01+工作在ISM频段:2.4~2.524 GHz。且内置频率合成器、功率放大器、晶体振荡器、调制器等功能,并融合增强型ShockBurst技术,其中地址、输出功率和通信频道可通过程序进行配置,适合用于多机通信。NRF24L01/NRF24L01+功耗很低,在以-6 dBm的功率发射时,工作电流也只有9 mA;而对应接收机的工作电流只有12.3 mA,多种低功率工作模式(掉电模式和空闲模式)使节能设计更方便。NRF24L01/NRF24L01+在业界领先的低功耗特点使其特别适合采用钮扣电池供电的2.4G应用,整个解决方案包括链路层和MultiCeiver功能提供了比现有的nRF24XX更多的功能和更低的电源消耗,与目前的蓝牙技术相比在提供更高速率的同时,而只需花更小的功耗.最新采用的nRF24L01+与nRF24L01兼容,并增加250kbps低速功能。 NRF24L01/NRF24L01+基本特性 工作电压:1.9-3.6V 调制方式: GFSK 最大发射功率: 0dBm 最大传输数率:2Mbps 瞬间最大工作电流: 15mA 工作频率:(2.400-2.524GHZ) ========================================== 1.低电压工作1.9-3.6V 2.掉电模式下的功耗400nA 3.待机模式下的功耗32uA 4.130us 的快速切换和唤醒时间 5.具有片内稳压器oltage regulators 6.2Mbit/s速率下接收时的峰值电流12.5mA 7.2Mbit/s速率下@0dBm输出时的峰值电流11mA 8.MultiCeiverMT硬件提供同时6个接收机的功能,2Mbit/s 使得高质量的VoIP 成为可能业界领先的低功耗NRF24L01/NRF24L01+特别适合采用钮扣电池供电的2.4G应用,整个解决方案包括链路层和MultiCeiver功能提供了比现有的 nRF24XX 更多的功能和更低的电源消耗,与目前的蓝牙技术相比 在提供更高速率的同时,而只需花更小的功耗 9.开阔通信距离60米左右,室内30米左右 ========================================== NRF24L01系列无线模组: 板载天线NRF24L01/NRF24L01+模块: http://item.taobao.com/item.htm?id=8487822260 外置天线NRF24L01/NRF24L01+模块: http://item.taobao.com/item.htm?id=1035140242 功率放大NRF24L01/NRF24L01+模块: http://item.taobao.com/item.htm?id=4073639196 USB 接口NRF24L01/NRF24L01+模块: http://item.taobao.com/item.htm?id=1993121052 NRF24L01+430-RFID系列无线模块: http://item.taobao.com/item.htm?id=8274101190 NRF24L01+51--RFID系列无线模块: http://item.taobao.com/item.htm?id=8753654192 NRF24L01/NRF24L01+无线应用评估: http://item.taobao.com/item.htm?id=278987910  
相关资源