完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一.NRF2401无线模块
1.模块介绍 功能介绍 (1)2.4Ghz 全球开放ISM 频段免许可证使2) 最高工作速率2Mbps,高效GFSK调制,抗干扰能力强,特别适合工业控制场合(3)126 频道,满足多点通信和跳频通信需要(4) 内置硬件CRC 检错和点对多点通信地址控制(5) 低功耗1.9-3.6V 工作,待机模式下状态为22uA;掉电模式下为900nA(6) 内置2.4Ghz 天线,体积小巧 15mmX29mm(7) 模块可软件设地址,只有收到本机地址时才会输出数据(提供中断指示),可直接接各种单片机使用,软件编程非常方便(8) 内置专门稳压威廉希尔官方网站 ,使用各种电源包括DC/DC 开关电源均有很好的通信效果(9)2.54MM间距接口, DIP封装(10)工作于EnhancedShockBurst 具有Automaticpackethandling,Auto packettransactionhandling,具有可选的内置包应答机制,极大的降低丢包率。 2.硬件与接口 nRF24L01芯片 nRF24L01模块 (1) VCC脚接电压范围为1.9V~3.6V之间,不能在这个区间之外,超过3.6V将会烧毁模块。推荐电压3.3V左右。(2) 除电源VCC和接地端,其余脚都可以直接和普通的5V单片机IO口直接相连,无需电平转换。当然对3V左右的单片机更加适用了。(3) 硬件上面没有SPI的单片机也可以控制本模块,用普通单片机IO口模拟SPI也可以 各管脚位置和定义: [tr]8.IRQ7MISO[/tr]
1.vcc:接1.9V~3.6V间的电压 2.GND:接地 3.CE:芯片的模式控制线。在 CSN 为低的情况下,CE 协同NRF24L01 的CONFIG 寄存器共同决定NRF24L01 的状态 4.CSN:为芯片的片选线 CSN 为低电平芯片工作 5.SCK:为芯片控制的时钟线(SPI时钟) 6.MOSI:为芯片控制数据线,主设备数据输出 从设备数据输入 7.MISO:芯片控制数据线,主设备数据输入 从设备数据输出 8.IRQ:中断信号引脚。中断时变为低电平,即NRF24L01内部发生中断时IRQ引脚从高电平变为低电平。引脚会在以下三种情况变低:(1)Tx FIFO 发完并且收到ACK(使能ACK情况下);(2)Rx FIFO 收到数据;(3)达到最大重发次数。 3.工作模式 工作模式设定 [tr]模式PWR_UPPRIM_RXCEFIFO寄存器状态[/tr]
PRIM_RX: 掉电 CE: 芯片使能 PWR_UP和PRIM_RX 在配置寄存器(CONFIG)中设置位0和位1: [tr]地址参数位复位值类型描述[/tr]
收发模式有Enhanced(增强型) ShockBurstTM收发模式、ShockBurstTM收发模式和直接收发模式三种。 3.1.1 ShockBurstTM 模式 ShockBurstTM收发模式下,使用片内的先入先出堆栈区,数据低速从微控制器送入,但高速(1Mbps) 发射,这样可以尽量节能,因此,使用低速的微控制器也能得到很高的射频数据发射速率。与射频协议相 关的所有高速信号处理都在片内进行,这种做法有三大好处:尽量节能;低的系统费用(低速微处理器也能 进行高速射频发射);数据在空中停留时间短,抗干扰性高。nRF2401 的 ShockBurstTM 技术同时也减小 了整个系统的平均工作电流。 在 ShockBurstTM 收发模式下,nRF2401 自动处理字头和 CRC 校验码。在接收数据时,自动把字头和 CRC 校验码移去。在发送数据时,自动加上字头和 CRC 校验码,当发送过程完成后,数据准备好引脚通 知微处理器数据发射完毕。 3.1.2 Enhanced(增强型) ShockBurstTM 模式 增强型ShockBurst TM 典型的双链方式为:发送方要求终端设备在接收到数据后有应答信号,以便发送方检测有无数据丢失,一旦丢失则重发数据。重发数据设置在地址为 04 的数据重发设置寄存器 用于设置其重发次数及设置在未收到应答信号后等待重发的时间。 数据重发设置寄存器(SETUP_RETR): [tr]地址参数位复位值类型描述[/tr]
每一个数据通道使用不同的地址,但是共用相同的频道。 也就是说6 个不同的nRF24L01 设置为发送模式后可以与同一个设置为接收模式的nRF24L01 进行通讯,而设置为接收模式的nRF24L01 可以对这6 个发射端进行识别。 数据通道0 是唯一 的一个可以配置为40 位自身地址的数据通道。1~5 数据通道都为8 位自身地址和32 位公用地址。所有的 数据通道都可以设置为增强型ShockBurst 模式。 NRF24L01在确认收到数据后记录地址,并以此地址为目标地址发送应答信号,在发送端,数据通道0被用作接收应答信号,因此属通道0 的接收地址要与发送地址端地址相等,以确保接收到正确的应答信号。 当MCU控制NRF24L01发送数据时,NRF24L01就会启动发送数据,发送完后NRF24L01就会转到接收模式并等待终端的应答信号。 如果没有收到应答信号,NRF24L01就会重发数据包,直到收到应答信号,或达到重发次数寄存器设定的最大值为止,如果重发次数超过了设定值则产生MAX_RT(最大重发次数中断)(应该在该中断没有被屏蔽的情况下的时候才会发生) 只要收到确认信号,nRF24L01 就认为最后一包数据已经发送成功(接收方已经收到数据),把TX FIFO 中的数据清除掉并产生TX_DS中断(数据发送完中断)(IRQ 引脚置高)。 3.1.2.1 Enhanced ShockBurstTM发射流程 1.配置CONFIG寄存器位PRIM_RX 为低,进入发送模式 2.当MCU 有数据要发送时,接收节点地址(TX_ADDR)和有效数据(TX_PLD)通过SPI 接口写入 nRF24L01。发送数据的长度以字节计数从MCU 写入TX FIFO。当CSN 为低时数据被不断的写入。 发送端发送完数据后,将通道0 设置为接收模式来接收应答信号,其接收地址(RX_ADDR_P0)与接 收端地址(TX_ADDR)相同。 例:在上图 中数据通道5 的发送端(TX5)及接收端(RX)地址设置如下: TX5:TX_ADDR=0xB3B4B5B605 TX5:RX_ADDR_P0=0xB3B4B5B605 RX:RX_ADDR_P5=0xB3B4B5B605 3.把CE置高,最小时间为10us,激发nRF24L01进行Enhanced ShockBurstTM 发射 4.nRF24L01 Enhanced ShockBurstTM 模式: (1) 无线系统上电 (2) 频数据打包(加字头、 CRC校验码) (3) 高速发射数据包(由MCU 设定为1Mbps 或2Mbps) 5、 如果启动了自动应答模式(自动重发计数器不等于0,ENAA_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. 相关寄存器: 自动应答寄存器: [tr]地址参数位复位值类型描述[/tr]
[tr]地址参数位复位值类型描述[/tr]
[tr]地址参数位复位值类型描述[/tr]
1.配置CONFIG寄存器位PRIM_RX 为高,进入接收模式准备接收数据的通道必须 被使能(EN_RXADDR 寄存器),所有工作在增强型ShockBurstTM 模式下的数据通道的自动应答功 能是由(EN_AA 寄存器)来使能的,有效数据宽度是由RX_PW_Px 寄存器来设置的。地址的建立过 程见增强型ShockBurstTM 发送章节。 2、 接收模式由设置CE 为高来启动。 3、 130us 后nRF24L01 开始检测空中信息。 4、 接收到有效的数据包后(地址匹配、CRC 检验正确),数据存储在RX_FIFO 中,同时RX_DR 位 置高,并产生中断。状态寄存器中RX_P_NO 位显示数据是由哪个通道接收到的。 5、 如果使能自动确认信号,则发送确认信号。 6、 MCU 设置CE 脚为低,进入待机模式I(低功耗模式)。 7、 MCU 将数据以合适的速率通过SPI 口将数据读出。 8、 芯片准备好进入发送模式、接收模式或掉电模式。 相关寄存器: 接收数据使能寄存器: [tr]地址参数位复位值类型描述[/tr]
[tr]地址参数位复位值类型描述[/tr]
|
|||||
|
|||||
3.1.3两种数据双方向的通讯方式:
如果想要数据在双方向上通讯,PRIM_RX 寄存器必须紧随芯片工作模式的变化而变化。 处理器必须保证PTX 和PRX 端的同步性。在RX_FIFO 和TX_FIFO 寄存器中可能同时存有数据。 3.1.4数据包识别和CRC校验应用于增强型ShockBurstTM模式下: 每一包数据都包括两位的PID(数据包识别)来识别接收的数据是新数据包还是重发的数据包。 PID识别可以防止接收端同一数据包多次送入MCU。 在发送方每从MCU取得一包新数据后PID值加一。 PID和CRC校验应用在接收方识别接收的数据是重发的数据包还是新数据包。 如果链接中有一些数据丢失了,则PID值与上一包数据的PID值相同。 接收方对新接收的数据包进行比较:如果一包数据拥有与上一包数据相同的PID值,nRF24L01将对两包数据的CRC值进行比较。如果CRC值也相同的话就认为后面一包是前一包的重发数据包而被舍弃。 3.1.5 数据通道: nRF24L01 配置为接收模式时可以接收==6== 路不同地址相同频率的数据。每个数据通道拥有自己的地址并且可以通过寄存器来进行分别配置。 数据通道是通过寄存器==EN_RXADDR== 来设置的,默认状态下只有数据通道==0== 和数据通道==1== 是开启状态的。 每一个数据通道的地址是通过寄存器==RX_ADDR_Px== 来配置的。通常情况下不允许不同的数据通道设 置完全相同的地址。 数据通道==0== 有==40== 位可配置地址。数据通道==1-5== 的地址为:==32== 位共用地址+各自的地址(最低字节)。 下图所示的是数据通道==1-5== 的地址设置方法举例。所有数据通道可以设置为多达==40== 位,但是==1-5== 数据通道的最低位必须不同。 **当从一个数据通道接收到数据,并且此数据通道设置为应答方式的话,则nRF24L01 在收到数据后 产生应答信号,此应答信号的目标地址为接收通道地址** 3.2待机模式 待机模式1在保证快速启动的同时减少系统平均消耗电流。 在待机模式1下,晶振正常工作。 在待机模式2下部分时钟缓冲器处在工作模式。 当发送端TX FIFO寄存器位空并且CE为高电平时进入待机模式2。 在待机模式期间,寄存器配置字内容保持不变。 3.3掉电模式 在掉电模式下,nRF24L01各功能关闭,保持电流消耗最小。 进入掉电模式后,nRF24L01停止工作,但寄存器内容保持不变。 掉电模式由寄存器中PWR_UP位来控制。 二、SPI介绍 SPI 是英语 Serial Peripheral interface 的缩写串行外围设备接口。 SPI,是一种高速的,全双工, 同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局 上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信 协议, STM32 也有 SPI 接口。 ==SPI 接口一般使用 4 条线通信:== MISO 主设备数据输入,从设备数据输出。 MOSI 主设备数据输出,从设备数据输入。 SCLK 时钟信号,由主设备产生。 CS 从设备片选信号,由主设备控制。 SPI内部结构简明图: SPI 总线四种工作方式 SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置, 时钟极性(CPOL)配置串行同步时钟空闲状态: 如果CPOL=0,串行同步时钟的空闲状态为低电平; 如果CPOL=1,串行同步时钟的空闲状态为高电 平。 时钟相位(CPHA)能够配置用于选择两种不同的传输协议之一进行数据传输: 如果 CPHA=0, 在串行同步时钟的第一个跳变沿(上升或下降)数据被采样; 如果 CPHA=1,在串行同步时钟 的第二个跳变沿(上升或下降)数据被采样。 ==SPI 主模块和与之通信的外设备时钟相位和极性应该一致== 不同时钟相位下的总线数据传输时序如图: 三、STM32开发板控制NRF24L01 ALIENTKEMiniSTM32 开发板带有一个 2.4G 无线模块(NRF24L01 模块)通信接口,采用 8 脚插针方式与开发板连接,用两块板子,一块接收,一块发送,实现无线传输。 1.宏定义 nRF24L01 SPI指令格式 由nRF24L01的SPI指令格式和寄存器地址进行相关操作和寄存器地址的宏定义 相关操作和地址宏定义: //NRF24L01寄存器操作命令 #define NRF_READ_REG 0x00 //读配置寄存器,低5位为寄存器地址 #define NRF_WRITE_REG 0x20 //写配置寄存器,低5位为寄存器地址 #define RD_RX_PLOAD 0x61 //读RX有效数据,1~32字节 #define WR_TX_PLOAD 0xA0 //写TX有效数据,1~32字节 #define FLUSH_TX 0xE1 //清除TX FIFO寄存器.发射模式下用 #define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用 #define REUSE_TX_PL 0xE3 //重新使用上一包数据,CE为高,数据包被不断发送. #define NOP 0xFF //空操作,可以用来读状态寄存器 //SPI(NRF24L01)寄存器地址 #define CONFIG 0x00 //配置寄存器地址;bit0:1接收模式,0发射模式;bit1:电选择;bit2:CRC模式;bit3:CRC使能; //bit4:中断MAX_RT(达到最大重发次数中断)使能;bit5:中断TX_DS使能;bit6:中断RX_DR使能 #define EN_AA 0x01 //使能自动应答功能 bit0~5,对应通道0~5 #define EN_RXADDR 0x02 //接收地址允许,bit0~5,对应通道0~5 #define SETUP_AW 0x03 //设置地址宽度(所有数据通道):bit1,0:00,3字节;01,4字节;02,5字节; #define SETUP_RETR 0x04 //建立自动重发;bit3:0,自动重发计数器;bit7:4,自动重发延时 250*x+86us #define RF_CH 0x05 //RF通道,bit6:0,工作通道频率; #define RF_SETUP 0x06 //RF寄存器;bit3:传输速率(0:1Mbps,1:2Mbps);bit2:1,发射功率;bit0:低噪声放大器增益 #define STATUS 0x07 //状态寄存器;bit0:TX FIFO满标志;bit3:1,接收数据通道号(最大:6);bit4,达到最多次重发 //bit5:数据发送完成中断;bit6:接收数据中断; #define MAX_TX 0x10 //达到最大发送次数中断 #define TX_OK 0x20 //TX发送完成中断 #define RX_OK 0x40 //接收到数据中断 #define OBSERVE_TX 0x08 //发送检测寄存器,bit7:4,数据包丢失计数器;bit3:0,重发计数器 #define CD 0x09 //载波检测寄存器,bit0,载波检测; #define RX_ADDR_P0 0x0A //数据通道0接收地址,最大长度5个字节,低字节在前 #define RX_ADDR_P1 0x0B //数据通道1接收地址,最大长度5个字节,低字节在前 #define RX_ADDR_P2 0x0C //数据通道2接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; #define RX_ADDR_P3 0x0D //数据通道3接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; #define RX_ADDR_P4 0x0E //数据通道4接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; #define RX_ADDR_P5 0x0F //数据通道5接收地址,最低字节可设置,高字节,必须同RX_ADDR_P1[39:8]相等; #define TX_ADDR 0x10 //发送地址(低字节在前),ShockBurstTM模式下,RX_ADDR_P0与此地址相等 #define RX_PW_P0 0x11 //接收数据通道0有效数据宽度(1~32字节),设置为0则非法 #define RX_PW_P1 0x12 //接收数据通道1有效数据宽度(1~32字节),设置为0则非法 #define RX_PW_P2 0x13 //接收数据通道2有效数据宽度(1~32字节),设置为0则非法 #define RX_PW_P3 0x14 //接收数据通道3有效数据宽度(1~32字节),设置为0则非法 #define RX_PW_P4 0x15 //接收数据通道4有效数据宽度(1~32字节),设置为0则非法 #define RX_PW_P5 0x16 //接收数据通道5有效数据宽度(1~32字节),设置为0则非法 #define NRF_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 PAout(4) //24L01片选信号 #define NRF24L01_CSN PCout(4) //SPI片选信号 #define NRF24L01_IRQ PAin(1) //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字节的用户数据宽度 2.初始化 NRF24L01的SPI通信时序: 从图中可以看出, SCK 空 闲的时候是低电平的,而数据在 SCK 的上升沿被读写。所以,我们需要设置 SPI 的 CPOL 和 CPHA均为 0,来满足 NRF24L01 对 SPI 操作的要求。 NRF24L01使用STM32的SPI1,和W25Q64以及SD卡共用一个SPI接口,所以在使用的时候,他们分时复用SPI1,需要把SD卡和W25Q64的片选信号置高,以防这两个器件对NRF24L01的通信造成干扰。 NRF24L01的SPI接口是标准的SPI接口,其最大的数据传输率为10Mbps。 STM32的SPI与nRF2401初始化代码: SPI_InitTypeDef SPI_InitStructure; //全局变量SPI结构体 void NRF24L01_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC|RCC_APB2Periph_SPI1, ENABLE ); // 使能GPIOA,GPIOC,SPI1时钟 //PA5.SPI1_SCK; PA6.SPI_MISO; PA7.SPI_MOSI GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);//初始化SPI1的GPIO口 //PA2.CE W25Q4片选信号; PA3.CE SD卡片选信号; PA4.CE 24L01片选信号 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //PC4.CSN SPI片选信号 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_SetBits(GPIOC,GPIO_Pin_4); //PA1.IRQ IRQ主机数据输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //上拉输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //PA1(中断信号引脚)置高,中断时变为低电平 //PA2(W25Q4片选信号)与PA3(SD卡片选信号)置高,以防这两个器件对NRF24L01造成干扰 //PA4(24L01片选信号)置高 GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //选择了串行时钟的稳态:时钟悬空低电平 //即(CPOL=0) SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第一个时钟沿 //即(CPHA=0) SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; //定义波特率预分频的值:波特率预分频值为8 //spi速度为9Mhz(24L01的最大SPI时钟为10Mhz) SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式 SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI1,ENABLE);//使能SPI1 //CE低电平 待机模式 NRF24L01_CE=0; //使能24L01 //CSN为低电平芯片工作 NRF24L01_CSN=1; //SPI片选取消 } |
|
|
|
3.功能函数
3.1 SPI1的发送与接收 //通过SPI1发送或者接收一个字节的数据 u8 SPI1_ReadWriteByte(u8 TxData) { u8 retry=0; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //检查发送缓存空标志位设置与否 { retry++; if(retry>200)return 0; } SPI_I2S_SendData(SPI1, TxData); //通过外设SPI1发送一个数据 retry=0; while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)//检查接受缓存非空标志位设置与否 { retry++; if(retry>200)return 0; } return SPI_I2S_ReceiveData(SPI1); //返回通过SPI1最近接收的数据 } 3.1 向nRF24L01指定寄存器写入或者读取 //SPI写寄存器 //入口参数: reg:指定寄存器地址; value:写入的值 u8 NRF24L01_Write_Reg(u8 reg,u8 value) { u8 status; NRF24L01_CSN=0; //使能SPI传输 status =SPI1_ReadWriteByte(reg);//发送寄存器号 SPI1_ReadWriteByte(value); //写入寄存器的值 NRF24L01_CSN=1; //禁止SPI传输 return(status); //返回状态值 } //读取SPI寄存器值 //入口参数:reg:要读的寄存器 u8 NRF24L01_Read_Reg(u8 reg) { u8 reg_val; NRF24L01_CSN = 0; //使能SPI传输 SPI1_ReadWriteByte(reg); //发送寄存器号 reg_val=SPI1_ReadWriteByte(0XFF);//读取寄存器内容 NRF24L01_CSN = 1; //禁止SPI传输 return(reg_val); //返回状态值 } 3.3 初始化nRF24L01的接收(TX)和发送(RX)模式 const u8 TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //发送地址 const u8 RX_ADDRESS[RX_ADR_WIDTH]={0x34,0x43,0x10,0x10,0x01}; //接收地址 //该函数初始化NRF24L01到RX模式 //设置RX地址,写RX数据宽度,选择RF频道,波特率和LNA HCURR //当CE变高后,即进入RX模式,并可以接收数据了 void NRF24L01_RX_Mode(void) { NRF24L01_CE=0; NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //写RX节点地址 NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通信频率 NRF24L01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度 //即32个字节 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 //向CONFIG(00)写入0000 1111;PRIM_RX=1 接收模式; PWR_UP=1 上电; CRCO=1 16位CRC校验; EN_CRC =1 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(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH); //写TX节点地址 NRF24L01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK NRF24L01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01); //使能通道0的自动应答 NRF24L01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址 NRF24L01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_CH,40); //设置RF通道为40 NRF24L01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f); //设置TX发射参数,0db增益,2Mbps,低噪声增益开启 NRF24L01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e); //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断 //向CONFIG(00)写入0000 1111;PRIM_RX=0 发射模式; PWR_UP=1 上电; CRCO=1 16位CRC校验; EN_CRC =1 CRC使能 NRF24L01_CE=1;//CE为高,10us后启动发送 } 3.4 向nRF24L01指定位置写入和读出指定长度数据 //在指定位置读出指定长度的数据 //入口参数:reg:寄存器(位置); *pBuf:数据指针; len:数据长度 //返回值,此次读到的状态寄存器值 u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len) { u8 status,u8_ctr; NRF24L01_CSN = 0; //使能SPI传输 status=SPI1_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 = SPI1_ReadWriteByte(reg);//发送寄存器值(位置),并读取状态值 for(u8_ctr=0; u8_ctr NRF24L01_CSN = 1; //关闭SPI传输 return status; //返回读到的状态值 } 3.5 启动NRF24L01接收和发送一次数据 //启动NRF24L01发送一次数据 //txbuf:待发送数据首地址 //返回值:发送完成状况 u8 NRF24L01_TxPacket(u8 *txbuf) { u8 sta; 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(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志 if(sta&MAX_TX)//达到最大重发次数 { NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 return MAX_TX; } if(sta&TX_OK)//发送完成 { return TX_OK; } return 0xff;//其他原因发送失败 } //启动NRF24L01接收一次数据 //txbuf:待发送数据首地址 //返回值:0,接收完成;其他,错误代码 u8 NRF24L01_RxPacket(u8 *rxbuf) { u8 sta; sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值 NRF24L01_Write_Reg(NRF_WRITE_REG+STATUS,sta); //清除TX_DS或MAX_RT中断标志 if(sta&RX_OK)//接收到数据 { NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据 NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 return 0; } return 1;//没收到任何数据 } 3.6 检测nRF24L01是否存在 //检测24L01是否存在 //返回值:0,成功;1,失败 u8 NRF24L01_Check(void) { u8 buf[5]={0XAA,0XAA,0XAA,0XAA,0XAA};//写入5个0XAA字节 u8 i; NRF24L01_Write_Buf(NRF_WRITE_REG+TX_ADDR,buf,5);//写入5个字节的地址. NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址 for(i=0;i<5;i++) if(buf!=0XAA) break; if(i!=5)return 1;//检测24L01错误 return 0; //检测到24L01 } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1884 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1663 浏览 1 评论
1149 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
763 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1720 浏览 2 评论
1964浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
790浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
614浏览 3评论
631浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
593浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-13 21:13 , Processed in 0.890147 second(s), Total 79, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (威廉希尔官方网站 图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号