Nrf24l01无线模块

article/2025/9/21 0:56:38

Nrf24l01无线模块

一,模块介绍

二,接口电路,

在这里插入图片描述

模块连接注意点:
(1) VCC 脚接电压范围为 1.9V~3.6V 之间,不能在这个区间之外,超
过 3.6V 将会烧毁模块。推荐电压 3.3V 左右。
(2) 除电源 VCC 和接地端,其余脚都可以直接和普通的 5V 单片机 IO

直接相连,无需电平转换。当然对 3V 左右的单片机更加适用了。
(3) 硬件上面没有 SPI 的单片机也可以控制本模块,用普通单片机 IO
口模拟 SPI 不需要单片机真正的串口介入,只需要普通的单片机 IO 口
就可以了,当然用串口也可以了。

然后我接的就是CE连的A4,CSN连的C4,SCK连的A5,MOSI连的A7,MISO连的A6,IRQ是中断脚,可以接外部中断,不过我没有接。这里注意一下哈,中断脚要想低电平触发的三种情况:1,发送端发送完了数据并接收到接收端的ACK应答;2,接收端接受到数据;3,达到最大重发次数(外部中断的时候需要考虑的)

三,工作模式

工作模式由 PWR_UP register 、PRIM_RX register 和 CE 决定,有如下表格中那么多的工作模式
在这里插入图片描述
(英文版)
在这里插入图片描述
(中文版)
其中收发模式有 Enhanced ShockBurstTM 收发模式、ShockBurstTM 收
发模式和直接收发模式三种,收发模式由器件配置字决定,但是主要用到的是 Enhanced ShockBurstTM 收发模式,只有该模式支持自动ANK,和自动重发。
下面也都是介绍的这个接收模式。

在这里插入图片描述
就是上面这张图,想象一下,这一个圈就是一个带有8个爪子的无线模块,RX是接收功能的(设为接收模式)模块,TX是发送功能的(设为发送模式)模块,这样就是被设为接收模式的端子有6个接受通道,而被,设为发送模式的端子有1个发送通道,它们的传输是这样子的:
发送端子的TX_add寄存器存放的是接收端子6个通道中的其中一个通道的地址,然后传送完数据之后,接收端在确认收到数据后记录发送端的地址,并以此地址(接收端某个通道的地址)为目标地址发送应答信号这个是自动的,不是程序设置的,应属于硬件实现)
发送端的2401会用自己接收通道0来接受接收端的2401发送来的相应信号。但是接收端的2401发送应答信号的时候,也发送的地址就是接收端的某个接受通道的地址。所以发送端的接收通道0的地址要设置成这个地址。注意就只能是发送通道的通道0作为应答信号
通道0有40位自身地址,通道1—5都为8位自身地址和32位公用地址。

例子:

TX5:TX_ADDR=0xB3B4B5B605

TX5:RX_ADDR_P0=0xB3B4B5B605

RX:RX_ADDR_P5=0xB3B4B5B605

介绍完模式之后就来看

该模式的发送的流程以及初始化该发送模式
在这里插入图片描述
在这里插入图片描述
该模式的接收流程以及初始化该接收模式
在这里插入图片描述

在这里插入图片描述

知道了这个无线模块的接收和发送操作流程还有接收和发送的模式配置,然后就要关注它的通信方式spi了:发送spi读写指令,并对寄存器读写,(读出寄存器里面的值或者像寄存器里面写入数据)主要学习的是库函数的版本,与之有关的寄存器也要了解一下哈~

四,相关寄存器介绍

这里是重点,找机会补上。

五, spi通信有关的库函数调用

stm32是有硬件spi的,这里连的是a5,6,7三个脚,(虽然一般上认为spi通信是4个脚,但是有一个是片选脚,在spi封装的库函数模块里面,没有加进去)
然后原子例程里是由现成的spi封装好的函数模块的,可以直接加进去用来着。

无线模块有关的库函数调用

NRF24L01初始化函数,因为是原子的代码,MINI板的测试代码,
这里NRF24L01也是使用的SPI1,和W25Q64以及SD卡等共用一个SPI接口,所以在使用的时候,他们分时复用SPI1。所以需要把SD卡和W25Q64的片选信号置高,以防止这两个器件对NRF24L01的通信造成干扰。所以也对没有用到的脚进行了拉高处理,就是代码中的A2,A3脚。所以自己实际在用的过程中可以不去处理这两个脚。emmmm大佬们都是可以自己写的,我只会拉人家的来用~(卑微)

void NRF24L01_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE );
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);
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);
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);
GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4);SPI1_Init(); //初始化 SPI
SPI_Cmd(SPI1, DISABLE); //
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
//设置 SPI 单向或者双向的数据模式:SPI 设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置为主 SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // 8 位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; //时钟悬空低电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; //数据捕获于第一个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //内部 NSS 信号有 SSI 位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
//定义波特率预分频的值:波特率预分频值为 256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从 MSB 位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC 值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //初始化外设 SPIx 寄存器
NRF24L01_CE=0; //使能 24L01
NRF24L01_CSN=1; //SPI 片选取消
}//检测 24L01 是否存在
//返回值:0,成功;1,失败

然后是模式设置,就是上面第三点所说的,如下是接收模式

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 为高,进入接收模式
}

还有发送模式

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 后启动发送
}

模式确定完了就要写具体的收发流程,如果是接受模式,那接收流程如下


u8 NRF24L01_RxPacket(u8 *rxbuf)
{
u8 sta;
SPI2_SetSpeed(SPI_BaudRatePrescaler_8); //spi 速度为 9Mhz
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(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;//没收到任何数据
}

若为发送模式,发送流程为

u8 NRF24L01_TxPacket(u8 *txbuf)
{
u8 sta;
SPI2_SetSpeed(SPI_BaudRatePrescaler_8);//spi 速度为 9Mhz
NRF24L01_CE=0;
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); //写数据到 TX BUF
NRF24L01_CE=1; //启动发送
while(NRF24L01_IRQ!=0); //等待发送完成
sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
NRF24L01_Write_Reg(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;//其他原因发送失败
}

接收和发送的操作是基于用spi的通信方式对无线模块寄存器的读和写的操作,所以,spi读写寄存器的指令如下

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); //返回状态值
}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); //返回状态值
}

指令发送了,就是说好啦,寄存器,我要开始对你进行读写数据了,然后就是对寄存器里面的数据进行读写

读寄存器的值

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<len;u8_ctr++)pBuf[u8_ctr]=SPI2_ReadWriteByte(0XFF);
NRF24L01_CSN=1; //关闭 SPI 传输
return status; //返回读到的状态值
}

像寄存器写入数据

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<len; u8_ctr++)SPI2_ReadWriteByte(*pBuf++); //写入数据
NRF24L01_CSN = 1; //关闭 SPI 传输
return status; //返回读到的状态值
}

这就是关于无线模块24L01的数据传输的函数部分了,最后我们还要写一个自检函数,这个是为了检测能不能检测到有24l01的存在

u8 NRF24L01_Check(void)
{
u8 buf[5]={0XA5,0XA5,0XA5,0XA5,0XA5}; u8 i;
SPI2_SetSpeed(SPI_BaudRatePrescaler_8); //spi 速度为 9Mhz
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,buf,5);//写入 5 个字节的地址.
NRF24L01_Read_Buf(TX_ADDR,buf,5); //读出写入的地址
for(i=0;i<5;i++)if(buf[i]!=0XA5)break;
if(i!=5)return 1;//检测 24L01 错误
return 0; //检测到 24L01
}

好啦,然后就可以写一个主函数来检测是否能够通信啦~~~~


http://chatgpt.dhexx.cn/article/P1TrLrWf.shtml

相关文章

51驱动NRF24L01通信,NRF24L01与TTL转NRF24L01模块通信

51驱动NRF24L01通信&#xff0c;NRF24L01与TTL转NRF24L01模块通信 NRF24L01一、简介二、引脚功能描述 程序设计一、对 24L01 的程序编程的基本思路如下&#xff1a;二、Tx 与 Rx 的配置过程1、Tx 模式初始化过程&#xff1a;2、Rx 模式初始化过程&#xff1a; 三、基本程序函数…

详解NRF24L01无线收发模块

近日有粉丝朋友留言&#xff0c;希望介绍一下nRF24L01这款无线收发芯片&#xff0c;正巧前不久的电赛有些涉及&#xff0c;因此将自己的一些经验写在这里&#xff0c;希望能有所收获。 前面我们介绍过单片机的几种通信协议&#xff0c;并且初步了解如何操作寄存器进而控制芯片的…

nRF24L01芯片(模块)介绍

nRF24L01芯片&#xff08;模块&#xff09;简介 nRF24L01是由NORDIC生产的工作在2.4GHz~2.5GHz的ISM 频段的单片无线收发器芯片。无线收发器包括&#xff1a;频率发生器、增强型“SchockBurst”模式控制器、功率放大器、晶体振荡器、调制器和解调器。 输出功率频道选择和协议的…

2.4G通信

文章目录 2.4G无线通信实验一、模块简介二、Enhanced ShockBurstTM模式介绍三. 编程1.初始化IO口2.Enhanced ShockBurstTM发送流程3.Enhanced ShockBurstTM发送模式初始化4.Enhanced ShockBurstTM接收流程5.Enhanced ShockBurstTM接收模式初始化6.读函数7.写函数8.主函数 总结 …

无线收发模块——NRF24L01

1、什么是nRF24L01 nRF24L01是由NORDIC生产的工作在2.4GHz~2.5GHz的ISM 频段的单片无线收发器芯片。有着极低的电流消耗。 nRF24L01与5V单片机的连接通过SPI接口进行通讯&#xff0c;输出功率频道选择和协议的设置可以通过SPI 接口进行设置&#xff0c;几乎可以连接到各种单片…

分布式集群脑裂问题

Zookeeper集群"脑裂"问题 - 运维总结 在分布式集群的脑裂问题中&#xff0c;zookeeper脑裂是一个经典的例子。 在zookeeper集群中&#xff0c;有一个leader和多个follower&#xff08;observer不参与选举&#xff0c;可以忽略&#xff09;&#xff0c;leader通过周…

分布式脑裂问题

"脑裂"定义 脑裂(split-brain)就是“大脑分裂”&#xff0c;也就是本来一个“大脑”被拆分了两个或多个“大脑”&#xff0c;我们都知道&#xff0c;如果一个人有多个大脑&#xff0c;并且相互独立的话&#xff0c;那么会导致人体“手舞足蹈”&#xff0c;“不听使唤…

Redis常见问题——脑裂问题

文章目录 背景一、脑裂问题产生二、选举完成三、总结四、解决方法 背景 脑裂问题&#xff1a;有三台服务器一台主服务器&#xff0c;两台从服务器&#xff0c;还有一个哨兵&#xff08;哨兵就相当于一个代码段&#xff0c;不参与实际业务&#xff09; 一、脑裂问题产生 解释一…

Redis脑裂现象

Redis脑裂现象 什么是Redis的脑裂现象 当Redis主从集群环境出现两个主节点为客户端提供服务&#xff0c;这时客户端请求命令可能会发生数据丢失的情况。 脑裂出现的场景 场景一 主从哨兵集群中如果当发生主从集群切换时&#xff0c;那么一定是超过预设quorum数量的哨兵和主…

redis集群(主从)脑裂及解决方案

什么是redis的集群脑裂&#xff1f; redis的集群脑裂是指因为网络问题&#xff0c;导致redis master节点跟redis slave节点和sentinel集群处于不同的网络分区&#xff0c;此时因为sentinel集群无法感知到master的存在&#xff0c;所以将slave节点提升为master节点。此时存在两个…

redis脑裂

脑裂&#xff1a;在主从集群中&#xff0c;同时有两个主节点他们都能接收写请求。而脑裂最直接影响的就是客户端不知道往哪个主节点写入数据&#xff0c;结果就是不同的客户端往不同的主节点写入数据。而且严重的会导致数据丢失。 为什么会发生脑裂&#xff1f; 1.确认是不是数…

【集群】脑裂是什么?Zookeeper是如何解决的?

文章目录 什么是脑裂Zookeeper集群中的脑裂场景过半机制 什么是脑裂 脑裂(split-brain)就是“大脑分裂”&#xff0c;也就是本来一个“大脑”被拆分了两个或多个“大脑”&#xff0c;我们都知道&#xff0c;如果一个人有多个大脑&#xff0c;并且相互独立的话&#xff0c;那么…

PXC脑裂问题分析与解决

前言 在使用PXC架构做mysql集群时,线上出现过一次PXC脑裂的故障,通过问题排查,分析与定位,最终针对这个问题以及解决方法做一次记录 脑裂现象表现 1、产品访问MySQL,出现数据不一致的情况(脑裂后一个集群分裂成两个独立的集群,如PXC前置是通过LVS架构访问,当VIP发生…

keepalived脑裂现象

Keepealived最常见的问题是会出现脑裂现象&#xff1a; Master一直发送心跳消息给backup主机&#xff0c;如果中间的链路突然断掉&#xff0c;backup主机将无法收到master主机发送过来的心跳消息&#xff08;也就是vrrp报文&#xff09;&#xff0c;backup这时候会立即抢占mas…

zookeeper的脑裂问题

关于集群中的"脑裂"问题&#xff0c;不清楚的可以看这里(https://www.cnblogs.com/kevingrace/p/7205846.html)&#xff0c;下面重点说下 Zookeeper 脑裂问题的处理办法。ZooKeeper 是用来协调(同步)分布式进程的服务&#xff0c;提供了一个简单高性能的协调内核&…

什么是脑裂问题

所谓脑裂问题就是在多机热备的高可用系统中&#xff0c;当两个结点心跳突然断开&#xff0c;纠纷列为两个独立的个体&#xff0c;由于互相失去联系&#xff0c;都认为对方出现了故障&#xff0c;因此都会争抢对方的资源&#xff0c;这就是脑裂问题 当从节点们发现和主节点连接不…

集群脑裂问题分析

1.什么是集群脑裂 集群的脑裂通常是发生在集群中部分节点之间不可达而引起的&#xff08;或者因为节点请求压力较大&#xff0c;导致其他节点与该节点的心跳检测不可用&#xff09;。当上述情况发生时&#xff0c;不同分裂的小集群会自主的选择出master节点&#xff0c;造成原…

Redis中的常见问题(穿透、雪崩、脑裂)

文章目录 1.Redis的缓存穿透2.Redis缓存雪崩的问题3.Redis的脑裂问题 1.Redis的缓存穿透 2.Redis缓存雪崩的问题 3.Redis的脑裂问题 客户端向主服务器写入了数据 但是主服务器还没有来得及同步的情况下 主服务器死了 那么这个时候就会选举新的主服务器 原来的主服务器在一段时间…

脑裂是什么,zk是如何解决脑裂问题的

什么是脑裂 脑裂(split-brain)就是“大脑分裂”&#xff0c;也就是本来一个“大脑”被拆分了两个或多个“大脑”&#xff0c;我们都知道&#xff0c;如果一个人有多个大脑&#xff0c;并且相互独立的话&#xff0c;那么会导致人体“手舞足蹈”&#xff0c;“不听使唤”。 脑裂…

堆叠脑裂

堆叠脑裂 一、什么是堆叠脑裂二、堆叠脑裂的危害三、如何解决堆叠脑裂四、DAD是如何工作的五、DAD恢复机制&#xff1a;六、DAD检测方式&#xff1a;1、 业务口直连检测方式2、Eth-Trunk口代理检测方式3、管理网口检测方式4、堆叠端口检测方式 一、什么是堆叠脑裂 堆叠建立后&…