【STM32外设系列】NRF24L01无线收发模块

news2025/1/12 12:22:15

🎀 文章作者:二土电子

🌸 关注公众号获取更多资料!

🐸 期待大家一起学习交流!


文章目录

  • 一、NRF24L01简介
    • 1.1 什么是NRF24L01
    • 1.2 NRF24L01引脚介绍
    • 1.3 NRF24L01工作模式
    • 1.4 NRF24L01的SPI时序
    • 1.5 Enhanced ShockBurstTM收发模式介绍
      • 1.5.1 Enhanced ShockBurstTM发送流程
      • 1.5.2 Enhanced ShockBurstTM接收流程
    • 1.6 NRF24L01用途
  • 二、程序设计
    • 2.1 NRF24L01初始化
    • 2.2 NRF24L01连接检测
    • 2.3 设置为发送模式
    • 2.4 设置为接收模式
    • 2.5 发送一次数据
    • 2.6 接收一次数据
  • 三、无线摇杆测试
    • 3.1 NRF24L01发送端初始化程序
    • 3.2 NRF24L01接收端初始化程序
    • 3.3 效果展示

一、NRF24L01简介

1.1 什么是NRF24L01

  NRF24L01是NORDIC公司生产的一款工作在2.4GHz的无线收发模块,采用FSK调制,通常由频率发生器、增强型SchockBurstTM模式控制器、功率放大器、晶体放大器、调制器、解调器等组成,可以实现点对点或者1对6的无线通信,无线通信速度最高可达2Mbps,在空旷地带通信距离可达180~240m(未实测)。

  NRF24L01采用SPI通信,关于SPI通信的知识,这里就不再详细介绍了,具体可查看STM32速成笔记专栏中关于SPI的介绍。

NRF24L01

1.2 NRF24L01引脚介绍

  不太友好的是,买来的NRF24L01后发现实物上没有对应的引脚标注,这里贴一下引脚图

NRF24L01引脚图

  我们简单地介绍一下它各个引脚的功能

NRF24L01引脚功能描述
CE模式控制线,在CSN为低电平时,CE协同Config寄存器共同决定NRF24L01的状态(关于NRF24L01的状态后续会有介绍)
CSNSPI片选线
SCKSPI时钟线
MOSI主机输出从机输入
MISO主机输入从机输出
IRQ中断信号线,中断时变为低电平,有三种中断,分别是TxFIFO发送完并收到ACK(使能ACK的情况)、RxFIFO收到数据、达到最大重发次数

1.3 NRF24L01工作模式

  NRF24L01的工作模式由CE引脚电平和Config寄存器的PWR_UP和PRIM_RX为共同控制。

NRF24L01工作状态PWR_UPPRIM_RXCEFIFO寄存器状态
接收模式11-
发送模式10数据在TxFIFO中
发送模式10高—>低停留在发送模式,直至发送完成
待机模式II10TxFIFO为空
待机模式I1-无数据传输

  其中收发模式有Enhanced ShockBurstTM收发模式和ShockBurstTM收发模式,只有前者支持自动ACK和自动重发。开启了自动ACK,实际也就默认选择了Enhanced ShockBurstTM收发模式。

  Enhanced ShockBurstTM收发模式使用片内先入先出堆栈区,数据可以低速从微控制器送入,然后以高速发射。在Enhanced ShockBurstTM收发模式下,NRF24L01自动处理字头和CRC校验码。在接收数据时,自动把字头和CRC校验码去掉。在发送数据时,自动加上字头和CRC校验码。在发送模式下,置CE为高,至少10us,将使能发送过程。

1.4 NRF24L01的SPI时序

  NRF24L01需要设置时钟极性为0,也就是空闲状态时SCK时钟线为低电平;时钟相位设置为0,也就是在时钟线SCK的第一个跳变沿采样数据。

1.5 Enhanced ShockBurstTM收发模式介绍

  Enhanced ShockBurstTM收发模式的发送方要求终端设备在接收到数据后有应答信号,以便发送方检测有无数据丢失,一旦检测到丢失则重发数据。在接收模式下,最多可以接收6路不同的数据,每一个数据通道使用不同的地址。也就是说6个不同的NRF24L01设置为发送模式后,可以与同一个设置为接收模式的NRF24L01进行通讯,接收端的NRF24L01可以对这6个发射端进行识别。

  上面说了,可以1收6发,接收端可以识别6个不同的发送端,这是怎么做到的呢?其实上面也说了,通过不同的地址。我们举个简单的例子来说明一下。

  在开始介绍例子之前我们要知道一个前提条件,无论是接收端还是发送端,他们的寄存器都是一样的,无非就是一个是接收模式一个是发送模式,知道了这个前提之后我们开始介绍。

  假设NRF24L01的6个接收数据的地址分别为0x0、0x1、0x2、0x3、0x4、0x5。当第一个NRF24L01发送数据时,通过数据通道0x0发送数据,接收端的0x0寄存器收到数据之后就知道是第一个NRF24L01发送的,在给0x0地址返回一个应答信号,其他5个也是相同的原理。

  简单总结一下

  • 在接收端,确认收到数据后记录地址,并一次地址为目的地址返回应答信号。
  • 在发送端,发送地址和接收地址要保持一致,以确保接收到正确的应答信号。

1.5.1 Enhanced ShockBurstTM发送流程

  • 把地址和要发送的数据按时序送入NRF24L01;
  • 配置Config寄存器,使NRF24L01进入发送模式;
  • 微控制器将CE置高(至少10us),触发Enhanced ShockBurstTM发射;

1.5.2 Enhanced ShockBurstTM接收流程

  • 配置接收地址和要接收的数据包大小(接收地址要确保和发送时配置的地址是一致的);
  • 配置Config寄存器,使NRF24L01进入接收模式,把CE置高;
  • 130us后,NRF24L01进入监听状态,等待数据包的到来;
  • 但接收到正确的数据包(正确的地址和CRC校验码)后,NRF24L01自动把字头、地址和CRC校验码去掉;
  • NRF24L01通过把STATUS寄存器的RX_DR置位,通知控制器接收完成;
  • 微控制器利用指令把数据从FIFO中读出;
  • 所有数据读取完毕后,清除STATUS寄存器;

  关于NRF24L01的指令,在后续的程序设计中会有详细介绍。

1.6 NRF24L01用途

  简单了解了之后,我们用NRF24L01可以做什么呢?这里博主打算是拿NRF2401来做一辆遥控的麦克纳姆轮小车,NRF24L01充当无线遥控的功能。当然,除了做遥控手柄外,它也可以做其他的远距离无线控制,比如无线开关等。

二、程序设计

  下面我们开始设计一下NRF24L01的程序,我们使用的是两个STM32F103C8T6核心板和两个NRF24L01,一个作为发送端,一个作为接收端,在开始程序设计之前我们先确定一下引脚分配。

NRF24L01引脚主控GPIO
GNDGND
VCC3.3V
CEPB11
CSNPB12
IRQPB10
SCKPB13
MISOPB14
MOSIPB15

  我们使用的是SPI2来与NRF24L01进行通信,关于SPI2的程序这就就不再展示了,可以到STM32速成笔记专栏中查看,这里着重介绍一下NRF24L01的程序。

2.1 NRF24L01初始化

  初始化包括两部分,一部分是初始化GPIO,另一部分是初始化SPI,程序设计如下

/*
 *==============================================================================
 *函数名称:Drv_Nrf24l01_Gpio_Init
 *函数功能:NRF24L01引脚初始化
 *输入参数:无
 *返回值:无
 *备  注:用来初始化NRF24L01的CS、IRQ和CE的引脚
 *==============================================================================
*/
void Drv_Nrf24l01_Gpio_Init (void)
{
	// 结构体定义
	GPIO_InitTypeDef GPIO_InitStructure;
	
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	// 配置结构体 CSN CE
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽输出
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);				
  
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_10;   
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;   // 下拉输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_SetBits(GPIOB,GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12);   // 上拉	
}
/*
 *==============================================================================
 *函数名称:Med_Nrf24l01_Init
 *函数功能:初始化NRF24L01
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
*/
void Med_Nrf24l01_Init (void)
{
	// 结构体定义
	SPI_InitTypeDef  SPI_InitStructure;
	
	Drv_Nrf24l01_Gpio_Init();   // 初始化NRF24L01引脚
	
	SPI2_Init();   // 初始化SPI2
	SPI_Cmd(SPI2, DISABLE);   // 不使能SPI2,因为要针对NRF24L01重新配置结构体
	
	// 配置SPI结构体
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;   // 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;   // 数据捕获于第1个时钟沿
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;   // NSS信号由软件控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;   // 定义波特率预分频的值:波特率预分频值为16
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;   // 数据传输从MSB位开始
	SPI_InitStructure.SPI_CRCPolynomial = 7;   // CRC值计算的多项式
	SPI_Init(SPI2,&SPI_InitStructure);   // 根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
 
	SPI_Cmd(SPI2, ENABLE);   // 使能SPI外设
			 
	NRF24L01_CE = 0;   // 使能24L01
	NRF24L01_CSN = 1;   // SPI片选取消  
}

2.2 NRF24L01连接检测

  连接检测的原理比较简单,我们往NRF24L01的特定寄存器写入特定值之后再读取,如果读取到的值和写入的相同,那么认为NRF24L01连接正常,程序设计如下

/*
 *==============================================================================
 *函数名称:Med_Nrf24l01_Connect_Check
 *函数功能:检查NRF24L01的连接状态
 *输入参数:无
 *返回值:0:连接正常;1:连接异常
 *备  注:无
 *==============================================================================
*/
u8 Med_Nrf24l01_Connect_Check (void)
{
	u8 buf[5] = {0XA5,0XA5,0XA5,0XA5,0XA5};
	u8 i;
	SPI2_SetSpeed(SPI_BaudRatePrescaler_4);   // spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   	 
	Med_Nrf24l01_Write_Buf(NRF_WRITE_REG + TX_ADDR,buf,5);   // 写入5个字节的地址.	
	Med_Nrf24l01_Write_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
}

  在初始化时可以进行连接检测,但是最好是加入一个超时检测,防止在NRF24L01连接异常时程序卡死。

2.3 设置为发送模式

  设置NRF24L01为发送模式程序设计如下

/*
 *==============================================================================
 *函数名称:Med_Nrf24l01_TX_Mode
 *函数功能:初始化NRF24L01到TX模式
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
*/
void Med_Nrf24l01_TX_Mode (void)
{														 
	NRF24L01_CE = 0;	    
	Med_Nrf24l01_Write_Buf(NRF_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);   // 写TX节点地址 
	Med_Nrf24l01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);   // 设置TX节点地址,主要为了使能ACK	  

	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);   // 使能通道0的自动应答    
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);   // 使能通道0的接收地址  
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);   // 设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+RF_CH,40);   // 设置RF通道为40
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);   // 设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+CONFIG,0x0e);   // 配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
	NRF24L01_CE = 1;   // CE为高,10us后启动发送
}

2.4 设置为接收模式

  设置NRF24L01为接收模式程序设计如下

/*
 *==============================================================================
 *函数名称:Med_Nrf24l01_RX_Mode
 *函数功能:初始化NRF24L01到RX模式
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
*/
void Med_Nrf24l01_RX_Mode (void)
{
	NRF24L01_CE = 0;	  
	Med_Nrf24l01_Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);   // 写RX节点地址
	
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+EN_AA,0x01);   // 使能通道0的自动应答    
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01);   // 使能通道0的接收地址  	 
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+RF_CH,40);   // 设置RF通信频率		  
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);   // 选择通道0的有效数据宽度 	    
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);   // 设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+CONFIG, 0x0f);   // 配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式 
	NRF24L01_CE = 1;   // CE为高,进入接收模式 
}

2.5 发送一次数据

/*
 *==============================================================================
 *函数名称:Med_Nrf24l01_TxPacket
 *函数功能:NRF24L01发送一次数据
 *输入参数:txbuf;要发送的数据首地址指针
 *返回值:发送完成情况
 *备  注:无
 *==============================================================================
*/
u8 Med_Nrf24l01_TxPacket (u8 *txbuf)
{
	u8 sta;
 	SPI2_SetSpeed(SPI_BaudRatePrescaler_8);   // spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   
	NRF24L01_CE = 0;
	Med_Nrf24l01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);   // 写数据到TX BUF  32个字节
 	NRF24L01_CE = 1;   // 启动发送	   
	while(NRF24L01_IRQ != 0);   // 等待发送完成
	sta = Med_Nrf24l01_Read_Reg(STATUS);   // 读取状态寄存器的值	   
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG + STATUS,sta);   // 清除TX_DS或MAX_RT中断标志
	if(sta & MAX_TX)   // 达到最大重发次数
	{
		Med_Nrf24l01_Write_Reg(FLUSH_TX,0xff);   // 清除TX FIFO寄存器 
		return MAX_TX; 
	}
	if(sta & TX_OK)   // 发送完成
	{
		return TX_OK;
	}
	return 0xff;   // 其他原因发送失败
}

2.6 接收一次数据

/*
 *==============================================================================
 *函数名称:Med_Nrf24l01_RxPacket
 *函数功能:NRF24L01接收一次数据
 *输入参数:rxbuf;存储接收数据的首地址指针
 *返回值:0:接收成功;1:接收失败
 *备  注:无
 *==============================================================================
*/
u8 Med_Nrf24l01_RxPacket (u8 *rxbuf)
{
	u8 sta;		    							   
	SPI2_SetSpeed(SPI_BaudRatePrescaler_8);   // spi速度为9Mhz(24L01的最大SPI时钟为10Mhz)   
	sta = Med_Nrf24l01_Read_Reg(STATUS);   // 读取状态寄存器的值    	 
	Med_Nrf24l01_Write_Reg(NRF_WRITE_REG+STATUS,sta);   // 清除TX_DS或MAX_RT中断标志
	if(sta & RX_OK)   // 接收到数据
	{
		Med_Nrf24l01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);   // 读取数据
		Med_Nrf24l01_Write_Reg(FLUSH_RX,0xff);   // 清除RX FIFO寄存器 
		return 0;
	}	   
	return 1;   // 没收到任何数据
}

三、无线摇杆测试

  下面我们结合之前我们介绍的外设双轴按键PS2来简单实现无线摇杆,关于双轴按键PS2摇杆的内容,可以移步至STM32外设系列专栏查看,这里就不再指路了。

3.1 NRF24L01发送端初始化程序

/*
 *==============================================================================
 *函数名称:Med_Mcu_Iint
 *函数功能:初始化系统
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
*/
void Med_Mcu_Iint (void)
{
	u8 outTimeCheck = 0;   // 超时检测变量
	
	delay_init();   //延时函数初始化
	uart_init(115200);   // 初始化串口
	ADC1_Init();   // ADC初始化
	Drv_Ps2_Gpio_Init();   // 初始化PS2摇杆引脚
	Med_Nrf24l01_Init();   // 初始化NRF24L01
	
	// NRF24L01连接检测
	printf ("Ready to check NRF24L01 connect...\r\n");
	while(Med_Nrf24l01_Connect_Check())
	{
		outTimeCheck = outTimeCheck + 1;
		delay_ms(200);
		
		// 超时退出
		if (outTimeCheck >= 100)
		{
			printf ("NRF24L01 connect error!\r\n");
			break;
		}
	}
	printf ("NRF24L01 connect ok!\r\n");
	
	Med_Nrf24l01_TX_Mode();   // 初始化为发送模式
	printf ("NRF24L01 set send mode ok!\r\n");
}

3.2 NRF24L01接收端初始化程序

/*
 *==============================================================================
 *函数名称:Med_Mcu_Iint
 *函数功能:初始化系统
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
*/
void Med_Mcu_Iint (void)
{
	u8 outTimeCheck = 0;   // 超时检测变量
	
	delay_init();   //延时函数初始化
	uart_init(115200);   // 初始化串口
	ADC1_Init();   // ADC初始化
	Med_Nrf24l01_Init();   // 初始化NRF24L01
	
	// NRF24L01连接检测
	printf ("Ready to check NRF24L01 connect...\r\n");
	while(Med_Nrf24l01_Connect_Check())
	{
		outTimeCheck = outTimeCheck + 1;
		delay_ms(200);
		
		// 超时退出
		if (outTimeCheck >= 100)
		{
			printf ("NRF24L01 connect error!\r\n");
			break;
		}
	}
	printf ("NRF24L01 connect ok!\r\n");
	
	Med_Nrf24l01_RX_Mode();   // 初始化为接收模式
	printf ("NRF24L01 set receive mode ok!\r\n");
}

3.3 效果展示

  最后我们来看一下实现效果

实现效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1219033.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图解分布式事务实现原理(三)

参考 本文参考https://zhuanlan.zhihu.com/p/650791238从零到一搭建 TCC 分布式事务框架&#xff0c;并在小徐的基础上增加个人见解笔记。 项目地址&#xff1a;https://github.com/xiaoxuxiansheng/gotcc 图解分布式事务实现原理&#xff08;一&#xff09;&#xff1a;https…

Kubernetes学习-概念2

参考&#xff1a;关于 cgroup v2 | Kubernetes 关于 cgroup v2 在 Linux 上&#xff0c;控制组约束分配给进程的资源。 kubelet 和底层容器运行时都需要对接 cgroup 来强制执行为 Pod 和容器管理资源&#xff0c; 这包括为容器化工作负载配置 CPU/内存请求和限制。 Linux 中…

CentOs 7 PHP安装和配置

目录 1 安装epel源 2 安装REMI源 3 安装yum源管理工具 4 安装PHP7.3 5 启动php服务 6 设置PHP 6.1 查找安装包 6.2 查找PHP安装位置 6.3 查找php配置文件位置 6.4 配置PHP 6.5 设置快捷命令 6.6 查看php版本 6.7 更新php 1 安装epel源 yum -y install epel-release 2 安…

这次轮到微软炸场了;5000+AI工具调研报告 (500万字);狂打一星开喷AI聊天机器人;CMU LLM课程;AI创业的方向与时机 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f251; Microsoft Ignite 2023 技术大会&#xff1a;微软的年度炸场时刻&#xff0c;而且连炸四天 https://ignite.microsoft.com OpenAI 开发…

【ARM Trace32(劳特巴赫) 使用介绍 2.2 -- TRACE32 进阶命令之 DIAG 弹框命令】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 上篇文章&#xff1a;【ARM Trace32(劳特巴赫) 使用介绍 2.1 – TRACE32 Practice 脚本 cmm 脚本学习】 下篇文章&#xff1a;【ARM Trace32(劳特巴赫) 使用介绍 3 - trace32 访问运行时的内存】 文章目录 DIALOG.OK 命令DIA…

2023年中国恒温蜡疗仪发展趋势分析:应用前景存有很大发展与探索空间[图]

恒温电蜡疗仪可将蜡熔化&#xff0c;利用蜡自身特点&#xff0c;能阻止热的传导、散热慢、气体和水分不易消失&#xff0c;保温性能优越。利用蜡能紧密贴于体表的可塑性&#xff0c;可加入其他药物协同进行治疗&#xff0c;也可将中药与蜡疗有机地结合在一起&#xff0c;产生柔…

Axure基础详解二十二:随机点名效果

效果演示 组件 建立一个【中继器】&#xff0c;内部插入一个“文本框”。【中继器】每页项目数为1&#xff0c;开始页为1。 设置交互 页面载入时交互 给【中继器】新曾行&#xff0c;“name”数据列添加10行数据&#xff0c;填入相应的名字&#xff1b;“shunxu”数据列全部…

【迅搜01】安装运行并测试XunSearch

安装运行并测试XunSearch 这回的新系列&#xff0c;我们将学习到的是一个搜索引擎 迅搜 XunSearch 的使用。这个搜索引擎在 PHP 圈可能还是有一点名气的&#xff0c;而且也是一直在更新的&#xff0c;虽说现在 ElasticSearch 已经是实际上的搜索引擎霸主了&#xff0c;而且还有…

容性负载箱与电容器的关系是什么?

容性负载箱用于测试电容器性能的设备&#xff0c;电容器是储存电能的元件&#xff0c;具有储存和释放电荷的能力。容性负载箱通过对电容器施加不同的负载&#xff0c;可以测量电容器的容量、电压响应、损耗等参数。 容性负载箱与电容器的关系主要体现在以下几个方面&#xff1a…

快递鸟荣获全球电子商务创业创新大赛总决赛一等奖

日前&#xff0c;以“开放、连接、协同、赋能”为主题&#xff0c;由商务部中国国际电子商务中心指导&#xff0c;浙江省商务厅、中共省委组织部、中共省委宣传部、中共省委网信办、省发展和改革委、省教育厅、省科技厅、省财政厅、省人力社保厅、团省委主办&#xff0c;湖州市…

聊聊ThreadLocal(二)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 大部分面试官喜欢问Thr…

idea一键打包docker镜像并推送远程harbor仓库的方法(包含spotify和fabric8两种方法)--全网唯一正确,秒杀99%水文

我看了很多关于idea一键打包docker镜像并推送harbor仓库的文章&#xff0c;不论国内国外的&#xff0c;基本上99%都是瞎写的&#xff0c; 这些人不清楚打包插件原理&#xff0c;然后就是复制粘贴一大篇&#xff0c;写了一堆垃圾&#xff0c;然后别人拿来也不能用。 然后这篇文…

使用html2canvas转换table为图片时合并单元格rowspan失效,无边框显示问题解决(React实现)

最近使用 html2canvas导出Table表单为图片&#xff0c;但是转换出的图片被合并的单元格没有显示边框 查了原因是因为我为tr设置了背景色&#xff0c;然后td设置了rowspan&#xff0c;设置了rowspan的单元格就会出现边框不显示的问题。 解决方法就是取消tr的背景色&#xff0c;然…

小米手环8pro重新和手机配对解决办法

如果更换了手机&#xff0c;那么小米手环8pro是无法和新手机自动连接的。 但是在新手机上直接连接又连接不上&#xff0c;搜索蓝牙根本找不到手环的蓝牙。 解决办法就是&#xff1a; 把手环恢复出厂&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 是的&…

Ubuntu 20.04 调整交换分区大小

Ubuntu 调整交换分区大小 一、系统情况二、去除旧的交换分区文件三、配置并启用交换分区四、查看swap文件大小 一、系统情况 Ubuntu &#xff1a;Ubuntu 20.04.6 LTS 交换分区位置&#xff1a; cat /proc/swaps二、去除旧的交换分区文件 去掉旧的交换分区有两个步骤&#x…

为什么嵌入式没有35岁危机?

为什么嵌入式没有35岁危机? 在当今数字化时代&#xff0c;IT行业变化迅速&#xff0c;技术的更新迭代速度惊人。然而&#xff0c;有一个技术领域却能够在这个竞争激烈的行业中稳步前行&#xff0c;而且不受35岁危机所困扰&#xff0c;那就是嵌入式技术。 嵌入式技术是指将计算…

Android开发:(AndroidStudio模拟器)如何将模拟器语言设置为中文 模拟器输入法更改为中文输入 键盘输入中文

文章目录 Android开发模拟器设置将模拟器语言设置为中文输入法中文的设置 Android开发模拟器设置 将模拟器语言设置为中文 第一步&#xff1a;打开模拟器后&#xff0c;上滑打开下面的设置图标。 第二步&#xff1a;找到 System (系统) &#xff0c;点击进入。 第三步&am…

外贸自建站怎么做?做外贸要怎样建设网站?

外贸自建站如何建立&#xff1f;海洋建站的具体步骤有哪些&#xff1f; 通过建立自己的外贸网站&#xff0c;您可以更好地展示公司的产品和服务&#xff0c;吸引更多的潜在客户&#xff0c;提高品牌知名度&#xff0c;拓展海外市场。那么&#xff0c;如何建立一个成功的外贸自…

千兆光模块和万兆光模块需要注意哪些事项

随着网络通信技术的发展&#xff0c;千兆光模块和万兆光模块已经成为了网络设备中不可或缺的关键组件。光模块的制造涉及到许多技术和工艺问题&#xff0c;需要严格的控制和管理。本文将从工艺流程、材料选用、测试认证等方面&#xff0c;详细介绍制造千兆光模块和万兆光模块需…

React实战演练项⽬一需求分析及vite_react搭建项目

React实战演练项⽬一需求分析及项目初始化 需求分析 刚学完React,开始找项目进行上手练习&#xff01; 页面组件拆分&#xff1a; 头部&#xff1a;导航tab、搜索框、登录注册 中间&#xff1a;分类导航、轮播图、新人福利、高单价产品导航 课程分类列表、底部内容、登陆提…