STM32 + 无线通信模块 NRF24L01 数据收发

article/2025/9/21 0:54:59

NRF24L01的模块资料,网上已很详尽了,在这不再重复描述知识点了。

这篇文章的目的,旨在把主要知识点胶接起来,梳理成一套完整的步骤,使器件快速上手汇入工作使用。

将按操作顺序,拆分成7个步骤,注解重点、暗坑。以方便自己进行知识管理,亦方便同行兄弟查阅。

代码方面,尽量做到一行代码一行解释。(如有订正和疑问,可留言交流,将迅速回复。)

目录

一、思维导图

二、 引脚连接,解释

三、SPI初始化、函数封装

四、NRF24L01参数写入

五、中断处理函数

六、发送数据

七、接收数据

八、代码下载


一、思维导图

3种主要工作模式、8个命令字、每包32字节有效数据,等等这些,直接思维导图更有效,不用文字啰嗦。

对主要点进行了组织,包括了工作模式、命令字等图例,认真过一遍,心里马上就能有个框框。

点击一下图片能变成清晰的大图。当然,右击保存就更方便查看了。


二、 引脚连接,解释

明确一个,NRF24L01和SI24R1的引脚、程序是通用的,无需任何修改,市面上大部份的NRF24L01模块,用的是SI24R1的芯片。两者间通信也互通,已测试确认!

下面是一个通用模块的引脚,以安信可的SI24R1模块为例:

共8个引脚:

  1. VCC:3.3V。1.9~3.6V都成,不要接5V,马上烧!
  2. GND:接地  
  3. CE:     模式控制。其高低电平,配合CONFIG寄存器PRIM_RX和PWR_UP两个位,可切换工作状态: 发送、接收 、待机 。
  4. IRQ:    中断信号引脚。发生以下三种中断时,引脚电平被NRF拉低:发送成功、接收到数据、已达最大重发次数
  5. CSN:   SPI的CS片选引脚
  6. SCK:   SPI的时钟线引脚
  7. MOSI: SPI的主出从入数据引脚
  8. MISO: SPI的主入从出数据引脚

三、SPI初始化、函数封装

NRF的配置,就是把各种参数(数值),如频道,速率,目标地址等,用SPI方式写到指定地址(芯片的寄存器).

 这个写入配置的动作,拆分开来看,理解为两部分,是在操作两种通信,别混乱。

首先主机按NRF datasheet的要求,设置和通过SPI通信,向NRF芯片特定地址(寄存器)写入参数值;

而这些写入的数值,就是用于控制NRF与别一个NRF的通信参数。

这两个通信,理解一下~

1:主机和NRF间的通信:       

  • 使用SPI,主机完成对NRF操控,所有操控其实就是4个操作:写参数、读参数、写要发送的数据,读出收到的数据
  • 上面的操控,分拆到SPI的操作上,就是常用的6个函数:SPI初始化、字节收发、写1字节,读1字节,写N字节,读N字节;
  • 写入参数:是NRF与NRF间通信的参数值, 如频道 ,速率,CRC校检,自动回答,自动重发,目标地址....
  • 读取参数,主要是STATUS状态寄存器的值,用于判断中断源;
  • 写入发送数据,把待发送的数据写到TX_FIFO. NRF按包发送数据,包中有效数据最大32字节;要手动做分包处理;
  • 读出收到数据,检测到RX_DR中断发生后(IRQ引脚被拉低),用SPI把RX_FIFO缓冲区的值,读取存放到指自已的缓冲区;
  • NRF的SPI通信速度可达10MHz,但为保证数据传输的完整不掉包,尽量不要超过8MHz;
  • NRF要求SPI通信时,在上升沿采样数据,要注意时序。

2:NRF和NRF间的收发通信:

  • NRF按主机刚才写到芯片的参数值开始工作(手动),通过电波传输到另一个芯片中或接收别一芯片的数据(自动)。
  • 这部份通信我们要做的,仅是控制CE引脚的高低电平,配合CONFIG寄存器,使NRF在接收、发送、待机三种状态切换。
  • NRF间的无线通信,基本没我们什么事。

编程顺序:  GPIO配置  >  SPI配置  >  SPI(5个小函数)  >  写NRF配置  >  NRF中断处理(3种情况)  >  NRF收、发(2个主函数)

GPIO初始化代码:

/*** SPI通信引脚, CS, SCK, MOSI, MISO  ***/
GPIOSet (NRF24L01_SPI_CSN_GPIO,  NRF24L01_SPI_CSN_PIN,   G_MODE_OUT , G_OTYPE_PP,  G_OSPEED_25M,  G_PUPD_UP ,     0);            // cs
GPIOSet (NRF24L01_SPI_CLK_GPIO , NRF24L01_SPI_CLK_PIN ,  G_MODE_AF ,  G_OTYPE_PP , G_OSPEED_25M , G_PUPD_DOWN ,   G_AF_SPI2 );  // sck
GPIOSet (NRF24L01_SPI_MOSI_GPIO ,NRF24L01_SPI_MOSI_PIN , G_MODE_AF ,  G_OTYPE_PP , G_OSPEED_25M , G_PUPD_DOWN ,   G_AF_SPI2 );  // mosi
GPIOSet (NRF24L01_SPI_MISO_GPIO ,NRF24L01_SPI_MISO_PIN , G_MODE_AF ,  G_OTYPE_PP , G_OSPEED_25M , G_PUPD_DOWN ,   G_AF_SPI2 );  // miso	/*** NRF控制引脚, CE, IRQ ***/
GPIOSet (NRF24L01_CE_GPIO ,      NRF24L01_CE_PIN ,       G_MODE_OUT , G_OTYPE_PP , G_OSPEED_25M , G_PUPD_DOWN ,   0);           // CE
GPIOSet (NRF24L01_IRQ_GPIO ,     NRF24L01_IRQ_PIN ,      G_MODE_IN  , G_OTYPE_PP , G_OSPEED_25M , G_PUPD_UP   ,   0);           // IRQ   NRF24L01芯片的IRQ引脚下拉能力很弱,注意外部上拉电阻大小,及MCU的上下拉

GPIOSet是个自己封装的初始化函数,不用管,重点看其中的参数就好,注意各上下拉。

SPI 初始化代码:

/*** SPI通信部分 ***/	
CSN_HIGH;                      //失能NRF
NRF24L01_SPI_EN_CLOCK ;        // 时钟
NRF24L01_SPIX->CR1 = 0;        // 清0
NRF24L01_SPIX->CR1 |= 0<<0;    // 采样沿数, NRF要求上升沿采样   CPHA:时钟相位,0x1=在第2个时钟边沿进行数据采样, 
NRF24L01_SPIX->CR1 |= 0<<1;    // 时钟线闲时极性,  CPOL:时钟极性,0x1=空闲状态时,SCK保持高电平
NRF24L01_SPIX->CR1 |= 1<<2;    // 主从模式,       0=从,1=主
NRF24L01_SPIX->CR1 |= 2<<3;    // 波特率控制[5:3], 0=fPCLK/2,  1=/4倍  2=/8  3/16
NRF24L01_SPIX->CR1 |= 0<<7;    // LSB先行,        0=MSB,  1=LSB
NRF24L01_SPIX->CR1 |= 1<<8;    // 内部从器件选择,根据9位设置(失能内部NSS)
NRF24L01_SPIX->CR1 |= 1<<9;    // 软件从器件管理 :  0=禁止软件管理从设备, 1=使能软件从器件管理(软件NSS)
NRF24L01_SPIX->CR1 |= 0<<11;   // 数据帧格式,       0=8位,  1=16位	NRF24L01_SPIX->CR1 |= 1<<6;    // 使能

SPI 初始化重点:

  • NRF要求在上升沿时采集数值。这就要闲时电平和采样沿要配合好。
  • NRF的SPI可达10MHz, 但实际使用时,不要超过8MHz。这个在SPI的波特率中可控制,因为SPI通信速率受限低速一方。
  • 重要:如果多个设备共用同一SPI,把各自的SPI配置封装成函数,每次使用SPI通信前各自调用一次,以使用自己的配置。

插个话题,为什么使用寄存器操作编程?因为:使用寄存器=简单+清晰,你看,不是吗?

SPI收发函数

/*****************************************************************************
*函  数: u8 SPI_RW(u8 Data)
*功  能: SPI写入一个字节,并返回一个字节
*参  数: 要写入的一字节
*返回值: 返回一字节数据
*****************************************************************************/
u8 SPI_SendByte(u8 Data)
{u8 retry =0;while((NRF24L01_SPIX ->SR & 2) == 0){   // 理解方式,应该把前式的结果理解为一个寄存器位值,如果这个位值是等号后面的值,就等待retry++;if(retry>200) return 0;}NRF24L01_SPIX ->DR = Data;retry=0;while((NRF24L01_SPIX->SR & 1) == 0 ){retry++;if(retry>200) return 0;}return NRF24L01_SPIX->DR ;
}/*****************************************************************************
*函  数:u8 Nrf24l01_WriteReg(u8 reg,u8 value)
*功  能:向指定寄存器地址,写一个字节数据
*参  数:reg: 寄存器地址
*       val:  要写入的值
*返回值:status
*****************************************************************************/
u8 Nrf24l01_WriteReg(u8 reg,u8 value)
{u8 status;    CSN_LOW;status = SPI_SendByte(reg) ;SPI_SendByte(value);CSN_HIGH;    return status;
}/*****************************************************************************
*函  数:u8 NRF24l01_read_reg(u8 reg)
*功  能:向指定寄存器地址,读出一字节数据
*参  数:reg: 寄存器地址
*返回值:reg_val(第二个读取到的字节)
*****************************************************************************/
u8 Nrf24l01_ReadReg(u8 reg)
{u8 reg_val;    CSN_LOW;SPI_SendByte(reg);reg_val = SPI_SendByte(0xFF);CSN_HIGH;    return reg_val;
}/*****************************************************************************
*函  数:u8 Nrf24l01_WriteBuf(u8 reg, u8 *pBuf, u8 len)
*功  能:写一组数据到寄存器
*参  数:reg: 寄存器地址
*       pBuf: 要写入数据的地址
*        len:  要写入的数据长度
*返回值:status
*备  注:NRF2401代码移植只需把SPI驱动修改成自己的即可
*****************************************************************************/
u8 Nrf24l01_WriteBuf(u8 reg, u8 *pBuf, u8 len)
{u8 status;    CSN_LOW;status = SPI_SendByte(reg);for(u8 i=0; i<len; i++)	{SPI_SendByte(pBuf[i]);		}CSN_HIGH;    return status;
}/*****************************************************************************
*函  数: u8 vNrf24l01_ReadBuf(u8 reg, u8 *pBuf, u8 len)
*功  能: 向指定寄存器地址,读出指定长度的数据
*参  数: reg :    寄存器地址
*        pBuf :   数据存放缓冲区
*        len  :   读取的字节数量
*返回值: status : 设备状态字
*****************************************************************************/
u8 Nrf24l01_ReadBuf(u8 reg, u8 *pBuf, u8 len)
{u8 status;	CSN_LOW;status = SPI_SendByte(reg);for(u8 i = 0; i<len ;i++){pBuf[i] = SPI_SendByte(0xFF);		}CSN_HIGH;    return status;
}

注意:在进入下一步配置NRF24L01前,必须先测试一下SPI通信是否成功 。一般是往NRF的发送地址寄存器写入五个字节,再读出来,把读出的数据和原数据对比, 就能知道SPI是否配置正确、 NRF24L01是否连接成功。

代码程序中,有个连接测试函数,可以作模块的连接,没有贴上来,留邮箱吧。


四、NRF24L01参数写入

使用上面初始化的SPI,和刚封装好的几个函数,就可以把需要的参数,写到NRF特定的地址(寄存器), 完成对其配置。

NRF24L01 参数配置代码:

/*** NRF24L01通信配置 30,2M,***/    
CE_LOW;                                                          // 热待机模式, 只有在ce置低时,才能配置寄存器
//delayUs(2000);                                                 // PowerDown 切换为 PowerUp需要1.5ms 
Nrf24l01_WriteReg(W_REGISTER + RF_CH,        30);                // 射频通道,即频率(0-125)
Nrf24l01_WriteReg(W_REGISTER + RF_SETUP,   0x0F);                // 设置TX发射参数,0db增益,2Mbps,低噪声增益关闭 (注意:低噪声增益关闭/开启直接影响通信,要开启都开启,要关闭都关闭0x0f)0x07
Nrf24l01_WriteReg(W_REGISTER + SETUP_AW,   0x03);                // 地址长度,默认值时0x03,即5字节
Nrf24l01_WriteBuf(W_REGISTER + TX_ADDR,    (u8*)TX_ADDRESS, 5);  // 写TX节点地址, 地址宽度:5字节,40位 
Nrf24l01_WriteBuf(W_REGISTER + RX_ADDR_P0, (u8*)TX_ADDRESS, 5);  // 设置TX节点地址,主要为了使能ACK,, 地址宽度:5字节,40位
Nrf24l01_WriteReg(W_REGISTER + SETUP_RETR, 0x0A);                // 设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次 0x1A	
Nrf24l01_WriteReg(W_REGISTER + EN_RXADDR,  0x01);                // 使能通道0的接收地址  
Nrf24l01_WriteReg(W_REGISTER + EN_AA,      0x01);                // 使能通道0自动应答
Nrf24l01_WriteReg(W_REGISTER + RX_PW_P0,     32);                // 选择通道0的有效数据宽度  
Nrf24l01_WriteReg(FLUSH_TX,                0xff);                // 清除TX_FIFO
Nrf24l01_WriteReg(W_REGISTER+STATUS,       0X7E);                // 清除所有中断,防止一进去接收模式就触发中断    
Nrf24l01_WriteReg(W_REGISTER+CONFIG,       0x0F);                // 配置为接收模式    
CE_HIGH;   	                                                 // CE置高,进入状态

重点:

  • CE引脚置低,方可配置NRF寄存器!  各教程都这教的,但测试过不置低也可正常配置。
  • RF_CH,:频道,2.4G为基址,1M为间隔值,如上面的30,代表使用2.430G的频率进行芯片间通信。可设值0~125。
  • RF_SETUP: 发射功率可配置,说白了就是的耗电程度。接收状态的功率是不能设置的,所以接收才是耗电的大头。数据传输率,常说的空中速率,一般设置2M
  • 地址长度,5字节,这个很独特
  • TX_ADDR:数据要发送到的目标地址
  • RX_ADDR_P0: 接收通道0的接收地址,接收这个地址设备发来的数据,这里设为和TX_ADDR一致,是为了自动应答。
  • NRF共有6个接收通道,p0~p5, 可同时监听6个不同地址的信号,p0通道也用于作自动应答作用。
  • TX_FIFO, 发送数据缓冲区,96字节,32字节为一组,共3组,可理解为缓冲区可存放3组发送数据。
  • RX_FIFO, 同上,两个FIFO相互独立。 虽然是FIFO,虽然有3组,但最好还是一包一包收发,状态切换时间难把握。
  • 倒数第二行,配置为接收模式,注意,这个时候还没开始工作的,还处于PownDown状态,状态和模式是两回事。
  • 最后一行,CE置高10us后,才进入工作状态,因之前配置的是接收模式,所以将进入接收状态

五、中断处理函数

为什么要先说中断?感觉先了解了中断,那么发送、接收就更好理解。

其实不应该叫中断的,但这样好理解,还是遵从约定俗成吧。

中断时, IRQ电平被拉低,是由NRF控制产生的,三种情况可触发:发送成功、达到重发最大次数、接收到数据

发送成功:

  • 1:PTX发送数据后,马上开始计时,130us后切换到接收模式,此时计时还在继续
  • 2:PRX在收到数据后,经CRC校检,数据完整后发回ACK信号
  • 3:PTX在规定时间内收到ACK信号,则置位TX_DS标志,IRQ引脚被拉低

达到重发最大次数:

  • 1:PTX发送数据后,马上开始计时,130us后切换到接收模式,此时计时还在继续
  • 2:PTX在规定时间内,没收到ACK信号,原因很多:如PRX没收到数据,CRC校验错误....
  • 3:PTX再次发送一次数据,重复步骤1
  • 4:SETUP_RETR寄存器可设置重发的次数,达到最大次数后,MAX_RT位被置位,IRQ引脚被拉低。

接收到数据:

  • PRX收到数据,经CRC校检,数据完整,有效数据存放到RX_FIFO,RX_DR位置高,IRQ引脚被拉低。

说说清理中断,要清理的中断有两处:

  • NRF的中断位,上面的三种标志中断位,都在寄存器STATUS中,各位置1可清0,IRQ引脚即回到高电平。
  • 单片机mcu的中断位,清理外部中断线标志位,否则会在中断函数里死循环。

中断处理函数代码:

void NRF24L01_IRQ_IRQHANDLER(void)
{                    u8  status=0 ;CE_LOW;                                               // 拉低CE,以便读取NRF中STATUS中的数据	status = Nrf24l01_ReadReg(R_REGISTER + STATUS);       // 读取STATUS中的数据,以便判断是由什么中断源触发的IRQ中断/*** 发送完成中断 ***/if(status & STATUS_TX){	                                     Nrf24l01_WriteReg(W_REGISTER+STATUS, STATUS_TX);  // 清NRF中断:发送完成Nrf24l01_WriteReg(FLUSH_TX, 0xff);                // 清发送缓冲区:TX_FIFOprintf("\r\n发送成功!!!!\r\n");vNrf24l01_RxMode ();                              // 切换为接收状态}/*** 接收完成中断 ***/if(status & STATUS_RX){ memset (NRF_RX_DATA , 0, 32);           Nrf24l01_ReadBuf(R_RX_PAYLOAD, NRF_RX_DATA , RX_PAYLO_WIDTH); // 读数据Nrf24l01_WriteReg(W_REGISTER+STATUS, STATUS_RX);              // 清NRF中断:收到数据Nrf24l01_WriteReg(FLUSH_RX,0xff);                             // 清除RX FIFO(注意:这句话很必要)   	printf("\r\n接收到数据: %s\r\n", NRF_RX_DATA);	        vNrf24l01_RxMode ();                             // 切换为接收状态}/*** 最大重发次数中断 ***/if(status & STATUS_MAX){	Nrf24l01_WriteReg(W_REGISTER+STATUS, 0x70);       // 清NRF中断:三个Nrf24l01_WriteReg(FLUSH_TX, 0xff);                // 清除TX_FIFO      printf("\r\n发送失败,达到最大重发次数!!!\r\n"); vNrf24l01_RxMode();                               // 切换为接收状态}EXTI->PR |= NRF24L01_IRQ_PIN ;                        // 清理外部中断线标志位
}    

六、发送数据

NRF的数据收发,是一包一包进行的,一包(帧)数据:包括了前导码、目标地址、包控制域、有效数据、CRC, 但我们只管有效数据,其它的不用我们负责,NRF发送时自动打包,接收到数据时自动拆包。

每一包的有效数据最大为32个字节。当然,也可以只发一个字节的数据。

要发送的数据大于32字节,就要分包进行,自行手动分包处理。

因为在配置部分时,已配置好了频道,速率,重发次数等各种参数,在需要发送数据时,只要往芯片写入要发送的数据和地址,然后切换为发送状态,芯片就会自动发送。

发送成功(收到ack),会产生TX_DS中断。

发送失败了(达到最大重发次数), 也会产生MAR_RT中断。

在中断函数里,根据情况作处理就好。

发送数据代码:

void vNrf24l01_TxPacket(u8 *txbuf)
{CE_LOW; Nrf24l01_WriteBuf(W_TX_PAYLOAD,           txbuf,          32);   // 写数据到TX_BUFF    Nrf24l01_WriteBuf(W_REGISTER+TX_ADDR,    (u8*)TX_ADDRESS,  5);   // 写入要发送的目标地址 Nrf24l01_WriteBuf(W_REGISTER+RX_ADDR_P0, (u8*)TX_ADDRESS,  5);   // 通道0的地址设为和目标地址一致,以接收自动回复auto_ack信号 Nrf24l01_WriteReg(W_REGISTER+CONFIG,      0x0E);	             // 设置为发送模式,开启所有中断	    CE_HIGH;	
}

发送就这几句!

重点:RX_ADDR_P0的地址和TX_ARRD一样,目的是自动应答。有个前提,在配置中已使能自动应答。

把操作封装成一个函数,要发什么,就往函数里掉数据就好,每次不要大于32字节。


七、接收数据

当系统或程序运行时,大部分时间是运行在接收状态下的。如:

  • 第四个部分配置步骤完成后,程序已处在接收状态。
  • 第五个部分,在中断处理函数中,三种中断处理后,也切换为接收状态,当然,也可以切换为更省电的待机状态。

NRF有6个接收通道,指在可同时监听接收同一个频道,同一速率的6个不同设备的数据。

常用的只是通道P0, 如果只使能了通道P0,那就只能接收到P0中地址设备发来的数据。

可以使能全部6个通道,设置6个不同设备地址,就可以监听接收6个设备发来的数据(同一时间,只能接收其中1个设备的数据);

注意,接收数据,指在接收中断发生后,我们从RX_FIFO中把数据读存到主机。而中断发生前的监听接收,NRF自动完成。

接收数据的代码:

接收本来就是最简单的,没啥特别代码,下面的代码,只是在中断处理函数里,再贴出来而已。

Nrf24l01_ReadBuf(R_RX_PAYLOAD, NRF_RX_DATA , RX_PAYLO_WIDTH); // 读数据到数组
Nrf24l01_WriteReg(W_REGISTER+STATUS, STATUS_RX);              // 清NRF中断:收到数据
Nrf24l01_WriteReg(FLUSH_RX,0xff);                             // 清除RX FIFO(注意:这句话很必要)  

把接收到的数据,先存放NRF_RX_DATA数组,再进行处理,不要在中断函数中处理。

读完后,记得要清理RX_FIFO,不然它一直占用NRF的缓冲区。RX_FIFO共96字节,分成32字节3组,NRF每次接收到数据就存放到最后面的一组中,当存满了3组,后面再接收到的数据,就会被NRF掉弃。


八、代码下载

两种方式,

1:代码已打包并上传成CSDN下载资源:

无线通信_NRF24L01.zip_nrf24l01发送前导码-嵌入式文档类资源-CSDN下载

2:由于咨询代码的人多,已把代码打包上传到Q群,群文件夹里找吧:262901124.


最后,如果你有更完善的代码,或修改后的代码,请回赠我一份,谢谢~~~

写了三四个小时,累~~~


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

相关文章

NRF24L01 无线模块

NRF24L01 简介 NRF24L01 可以实现点对点或者是1&#xff08;收&#xff09;对6&#xff08;发&#xff09;的无线通信。NRF24L01 采样SPI通信&#xff0c;很方便连接MCU NRF24L01 无线模块&#xff0c;采用的芯片是 NRF24L01&#xff0c;该芯片的主要特点如下&#xff1a; 1&a…

NRF2401模块

一、模块介绍 (1) 2.4Ghz 全球开放 ISM 频段免许可证使用 (2) 最高工作速率 2Mbps&#xff0c;高效 GFSK 调制&#xff0c;抗干扰能力强&#xff0c;特别适合工业控制场合 (3) 126 频道&#xff0c;满足多点通信和跳频通信需要 (4) 内置硬件 CRC 检错和点对多点通信地址控制…

Nrf24l01无线模块

Nrf24l01无线模块 一&#xff0c;模块介绍 二&#xff0c;接口电路&#xff0c; 模块连接注意点&#xff1a; (1) VCC 脚接电压范围为 1.9V~3.6V 之间&#xff0c;不能在这个区间之外&#xff0c;超 过 3.6V 将会烧毁模块。推荐电压 3.3V 左右。 (2) 除电源 VCC 和接地端&…

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;造成原…