STM32(九):USART串口通信 (标准库函数)

前言

上一篇文章已经介绍了如何用STM32单片机中独立看门狗来实现检测按键点灯的程序。这篇文章我们来介绍一下如何用STM32单片机中USART通信协议来串口通信,并向XCOM发送信息。

一、实验原理

1.通信的介绍

首先,我们先介绍一下通信,何为通信,就跟平时我们面对面沟通一样,对于STM32,通信是将一个设备的数据传送到另一个设备,同时,我们平时沟通需要共同语言才能理解,STM32的通信也要制定通信协议,双方按照协议规则进行数据收发。

通信协议主要有以下几种:

名称引脚通信方式时钟电平设备
USARTTX、RX全双工异步单端点对点
I2CSCL、SDA半双工同步单端多设备

SPI

SCLK、MOSI、MISO、CS全双工同步单端多设备
CANCAN_H、CAN_L半双工异步差分多设备
USBDP、DM半双工异步差分点对点

 区别可以看下面的链接,这边就不多加赘述了,此篇重点还是介绍一下USART

IIC、SPI、UART、USART、USB、CAN等通讯协议原理及区别_iic,spi,usart,uart,can特点-CSDN博客

2.通信的分类

通信按数据通信方式分类,可分为串行通信和并行通信两种。

串行通信和并行通信主要有效率、复杂性、抗干扰性3方面的区别,区别如下:

  • 效率:串行通信由于线路少,结构简单,适用于长距离和高速传输;并行通信适用于短距离的高速数据传输,因为同步问题限制了其传输距离。
  • 复杂性:串行通信更简单,成本低;而并行通信复杂且成本高。
  • 抗干扰性:串行通信抗干扰性强,适用于噪声较大的环境;并行通信易受干扰,适用于短距离和低噪声环境。

通信按同步方式分类,可分为同步通信和异步通信两种,主要区别在于数据同步方式和时钟信号的使用。

同步通信:

  • 时钟信号驱动:

        同步通信依赖一个共同的时钟信号来同步发送方和接收方的数据传输。该时钟信号通常由发送方提供,并通过单独的一根时钟线传输。数据的采样时刻通常是在时钟信号的上升沿或下降沿进行的,确保了发送和接收过程中的同步性。

  • 数据传输

        在同步通信中,由于数据传输是基于时钟信号进行同步的,传输的数据大部分都是有效数据,没有额外的同步标识符,这使得同步通信的效率较高。典型的同步通信协议包括SPI和I2C。

 异步通信:

  • 时钟信号驱动

        异步通信不依赖外部时钟信号,而是在数据流中嵌入同步信息,如起始位和停止位,以实现发送和接收的同步。数据传输速率通常在通信双方提前约定,并通过硬件或软件进行配置。

  • 数据传输

        异步通信中的数据传输通常包含起始位、数据位、校验位和停止位。这些额外的标识符用于同步和错误检测,导致数据传输效率相对较低。UART是异步通信的一种典型协议。

3.USART的介绍

理解USART要先理解串口通信。串口通信(Serial Communication)顾名思义也就是利用串行接口进行通信,是一种数据传输方式。它以位为单位逐个传输数据。而串口是一种可以将接收来自CPU的并行数据字符转换为连续的串行数据流发送出去,同时可将接收的串行数据流转换为并行的数据字符供给CPU的器件。

USART的主要特性如下:

  • USART是一种通用同步/异步收发器/发射器,也是一种串行通信接口。 
  • USART是STM32 内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从 Tx 引脚发送出去,也可自动接收 Rx 引脚的数据帧时序,拼接为一个字节数据存在数据寄存器里。
  • 自带波特率发生器(相当于分频器),一般设置为9600/115200。
  • 可配置数据位长度(8/9),停止位长度(0.5-2)
  • 可选检验位(无校验/奇校验/偶校验)
  • 支持同步模式(clk 时钟输出),硬件流控制(防止接收端处理慢而导致数据丢失的问题)

为了更加清楚的了解USART的工作原理,同样要对其功能框图进行理解,功能框图如下所示:

1.功能引脚

上图各引脚功能解释如下:
TX发送数据输出引脚
RX接收数据输入引脚
SW_RX数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚
nRTS请求以发送 (Request To Send),n 表示低电平有效。如果使能 RTS 流控制,当 USART接收器准备好接收新数据时就会将 nRTS 变成低电平;当接收寄存器已满时,nRTS 将被设置为高电平。该引脚只适用于硬件流控制
nCTS清除以发送 (Clear To Send),n 表示低电平有效。如果使能 CTS 流控制,发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完 当前数据帧之后停止发送。该引脚只适用于硬件流控制
SCLK发送器时钟输出引脚。这个引脚仅适用于同步模式

2.数据寄存器

  •  USART 数据寄存器 (USART_DR) 只有低 9 位有效,并且第 9 位数据是否有效要取决于 USART 控制寄存器 1(USART_CR1) 的 M 位设置,当 M 位为 0 时表示 8 位数据字长,当 M 位为 1 表示 9 位数据字长,我们一般使用 8 位数据字长。
  • USART_DR 包含了已发送的数据或者接收到的数据。 USART_DR 实际是包含了两个寄存器,一 个专门用于发送的可写 TDR ,一个专门用于接收的可读 RDR 。当进行发送操作时,往 USART_DR 写入数据会自动存储在 TDR 内;当进行读取操作时,向 USART_DR 读取数据会自动提取 RDR 数据。
  • TDR 和 RDR 都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR 内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到 RDR。

3.控制器

USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用USART 之前需要向 USART_CR1 寄存器的 UE 位置 1 使能 USART,UE 位用来开启供给给串口的时钟。发送或者接收数据字长可选 8 位或 9 位,由 USART_CR1 的 M 位控制。
对于发送器、接收器等大家可以去查一下手册,体会也更深,篇幅原因,此就不多加赘述了,有问题可以私信。
 

4.分数波特率

波特率是指每秒钟传输的符号数或信号单元的数量,单位是波特 (Baud)。一个波特可以包含一个或多个比特。而USART波特率计算公式如下:

这里的fCK是给外设的时钟(PCLK1用于USART2、3、4、5,PCLK2用于USART1)
接收器和发送器的波特率在USARTDIV 的整数和小数寄存器中的值应设置成相同。

二、实验步骤

1.配置NVIC

主要是设定USART接收中断优先级,这边的对于优先级配置不懂的可以看之前的文章

STM32(三):外部中断 (标准库函数)_stm32外部中断的库函数程序怎么写-CSDN博客

void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure; 
	 /* 嵌套向量中断控制器组选择 */  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	
   /* 配置USART为中断源 */
	NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;	 
	 /* 抢断优先级为0 */
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	 /* 子优先级为1 */
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	 /* 使能中断 */
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 /* 初始化配置NVIC */
	NVIC_Init(&NVIC_InitStructure);
}

2.串口参数配置

需要使能USART时钟和USART功能GPIO时钟,这边使用的仍是宏定义,可以直接看实操代码里面的h文件

/* 使能USART时钟 */
USARTx_ClockCmd(USARTx_CLK,ENABLE);
/* 使能USART功能GPIO时钟 */
USARTx_GPIO_ClockCmd(USARTx_TX_CLK | USARTx_RX_CLK | RCC_APB2Periph_AFIO,ENABLE);

接下来是USART功能的GPIO初始化,主要是发送和接收IO口的配置

/* 设定USART发送对应IO编号 */
	GPIO_InitStructure.GPIO_Pin =  USARTx_TX_PIN;
/* 设定USART发送对应IO模式:复用推挽输出 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
/* 设定USART发送对应IO最大操作速度 :GPIO_Speed_50MHz */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* 初始化USART发送对应IO */
	GPIO_Init(USARTx_TX_PORT, &GPIO_InitStructure);    
  
/* 设定USART接收对应IO编号 */
	GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;
/* 设定USART发送对应IO模式:浮空输入 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
/* 初始化USART接收对应IO */
	GPIO_Init(USARTx_RX_PORT, &GPIO_InitStructure);	

最后,是USART工作环境的配置,主要是要定义波特率USART_BaudRate、字长USART_WordLength、停止位USART_StopBits和校验位USART_Parity

/* USART波特率:115200 */
	USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE;
/* USART字长(有效位):8位 */
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
/* USART停止位:1位 */
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
/* USART校验位:无 */
	USART_InitStructure.USART_Parity = USART_Parity_No ;
/* USART硬件数据流控制(硬件信号控制传输停止):无 */
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
/* USART工作模式使能:允许接收和发送 */
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
/* 初始化USART */
	USART_Init(USARTx, &USART_InitStructure);

值得注意的是,还需要清除发送完成标志!

USART_ClearFlag(USARTx, USART_FLAG_TC|USART_FLAG_TXE|USART_FLAG_RXNE);

3.发送数据函数

这边主要给出了4种数据类型的发送函数:发送一个字节数据、发送指定长度的字符串、发送字符串直到遇到字符串结束符以及重定义Printf函数。

1.发送一个字节数据

void Usart_SendByte(uint8_t ch)
{
  /* 发送一个字节数据到USART1 */
  USART_SendData(USARTx,ch);

  /* 等待发送完毕 */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);	
}

2.发送指定长度的字符

void Usart_SendStr_length(uint8_t *str,uint32_t strlen)
{
  unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(k < strlen);
}

3.发送字符串直到遇到字符串结束符

void Usart_SendString(uint8_t *str)
{
	unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(*(str + k)!='\0');
}

4.重定义printf函数

/**
  * 函数功能: 重定向c库函数printf到USARTx
  */
int fputc(int ch, FILE *f)
{
  /* 发送一个字节数据到调试串口 */
  USART_SendData(USARTx, (uint8_t) ch);

  /* 等待串口数据发送完毕 */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);		

  return (ch);
}

/**
  * 函数功能: 重定向c库函数getchar,scanf到USARTx
  */
int fgetc(FILE *f)
{
  /* 等待串口输入数据 */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);

  return (int)USART_ReceiveData(USARTx);
}

4.串口中断函数

值得注意的是,需要加上USARTx_IRQHANDLER(void)

void USARTx_IRQHANDLER(void)
{
	if(USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET)
	{ 	
	  Rxflag=1;		
		ucTemp = USART_ReceiveData(USARTx);
	} 
	 
}

三、实操代码

程序分为3个文件:bsp_usartx.c、bsp_usartx.h、main.c

1.bsp_usartx.c 

/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp/usart/bsp_usartx.h"


/**
  * 函数功能: 配置NVIC,设定USART接收中断优先级.
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure; 
	 /* 嵌套向量中断控制器组选择 */  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
	
   /* 配置USART为中断源 */
	NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;	 
	 /* 抢断优先级为0 */
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	 /* 子优先级为1 */
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	 /* 使能中断 */
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	 /* 初始化配置NVIC */
	NVIC_Init(&NVIC_InitStructure);
}

/**
  * 函数功能: 串口参数配置.
  */
void USARTx_Init(void)
{
  /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 定义USART初始化结构体变量 */
	USART_InitTypeDef USART_InitStructure;
  
  /* 配置NVIC,设定USART接收中断优先级 */
  NVIC_Configuration();
  
  /* 使能USART时钟 */
  USARTx_ClockCmd(USARTx_CLK,ENABLE);
  /* 使能USART功能GPIO时钟 */
  USARTx_GPIO_ClockCmd(USARTx_TX_CLK | USARTx_RX_CLK | RCC_APB2Periph_AFIO,ENABLE);
  
	/* 调试USART功能GPIO初始化 */
	/* 设定USART发送对应IO编号 */
	GPIO_InitStructure.GPIO_Pin =  USARTx_TX_PIN;
  /* 设定USART发送对应IO模式:复用推挽输出 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  /* 设定USART发送对应IO最大操作速度 :GPIO_Speed_50MHz */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  /* 初始化USART发送对应IO */
	GPIO_Init(USARTx_TX_PORT, &GPIO_InitStructure);    
  
	/* 设定USART接收对应IO编号 */
	GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;
  /* 设定USART发送对应IO模式:浮空输入 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  /* 其他没有重新赋值的成员使用与串口发送相同配置 */
  /* 初始化USART接收对应IO */
	GPIO_Init(USARTx_RX_PORT, &GPIO_InitStructure);	
			
	/* USART工作环境配置 */
  /* USART波特率:115200 */
	USART_InitStructure.USART_BaudRate = USARTx_BAUDRATE;
  /* USART字长(有效位):8位 */
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  /* USART停止位:1位 */
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
  /* USART校验位:无 */
	USART_InitStructure.USART_Parity = USART_Parity_No ;
  /* USART硬件数据流控制(硬件信号控制传输停止):无 */
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	/* USART工作模式使能:允许接收和发送 */
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  /* 初始化USART */
	USART_Init(USARTx, &USART_InitStructure);
  
	/* 使能接收中断 */
  USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);	
  
  /* 使能USART */
	USART_Cmd(USARTx, ENABLE);
 /* 清除发送完成标志 */
	USART_ClearFlag(USARTx, USART_FLAG_TC|USART_FLAG_TXE|USART_FLAG_RXNE);
}

/**
  * 函数功能: 串口发送一个字节数据 
  * 输入参数: ch:待发送字符
  */
void Usart_SendByte(uint8_t ch)
{
  /* 发送一个字节数据到USART1 */
  USART_SendData(USARTx,ch);

  /* 等待发送完毕 */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);	
}

/**
  * 函数功能: 串口发送指定长度的字符串
  * 输入参数: str:待发送字符串缓冲器
  *           strlen:指定字符串长度
  */
void Usart_SendStr_length(uint8_t *str,uint32_t strlen)
{
  unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(k < strlen);
}

/**
  * 函数功能: 串口发送字符串,直到遇到字符串结束符
  * 输入参数: str:待发送字符串缓冲器
  */
void Usart_SendString(uint8_t *str)
{
	unsigned int k=0;
  do 
  {
    Usart_SendByte(*(str + k));
    k++;
  } while(*(str + k)!='\0');
}

/**
  * 函数功能: 重定向c库函数printf到USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  /* 发送一个字节数据到调试串口 */
  USART_SendData(USARTx, (uint8_t) ch);

  /* 等待串口数据发送完毕 */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);		

  return (ch);
}

/**
  * 函数功能: 重定向c库函数getchar,scanf到USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  /* 等待串口输入数据 */
  while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);

  return (int)USART_ReceiveData(USARTx);
}

2.bsp_usartx.h

#ifndef __BSP_USARTX_H__
#define __BSP_USARTX_H__

/* 包含头文件 ----------------------------------------------------------------*/
#include <stm32f10x.h>

/* 类型定义 ------------------------------------------------------------------*/
/* 宏定义 --------------------------------------------------------------------*/
#define USARTx_BAUDRATE                        115200

#define USARTx_ClockCmd                        RCC_APB2PeriphClockCmd
#define USARTx_CLK                             RCC_APB2Periph_USART1

#define USARTx_GPIO_ClockCmd                   RCC_APB2PeriphClockCmd
    
#define USARTx_TX_PORT                         GPIOA   
#define USARTx_TX_PIN                          GPIO_Pin_9
#define USARTx_TX_CLK                          RCC_APB2Periph_GPIOA 
#define USARTx_RX_PORT                         GPIOA 
#define USARTx_RX_PIN                          GPIO_Pin_10
#define USARTx_RX_CLK                          RCC_APB2Periph_GPIOA

#define USARTx_IRQHANDLER                      USART1_IRQHandler
#define USARTx_IRQn                            USART1_IRQn
#define USARTx                                 USART1

/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
void USARTx_Init(void);
void Usart_SendByte(uint8_t ch);
void Usart_SendStr_length(uint8_t *str,uint32_t strlen);
void Usart_SendString(uint8_t *str);

#endif  // __BSP_USARTX_H__

3.main.c


/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp/led/bsp_led.h"
#include "bsp/key/bsp_key.h"
#include "bsp/delay/delay.h"
#include "bsp/systick/bsp_SysTick.h"
#include "bsp/GeneralTIM/bsp_GeneralTIM.h" 
#include "bsp/wdg/bsp_iwdg.h"
/* 函数体 --------------------------------------------------------------------*/
//static uint16_t timecount;
__IO uint16_t timer_count=0;
#include "bsp/usart/bsp_usartx.h"


uint8_t Rxflag=0;
uint8_t ucTemp;

/**
  * 函数功能: 主函数.
  */
int main(void)
{
  
  uint8_t ucaRxBuf[256];
	uint16_t usRxCount;
  
  /* USART 配置模式为 115200 8-N-1,中断接收 */
  USARTx_Init();


	/* 简单的通信协议,遇到回车换行符认为1个命令帧 */  
	usRxCount = 0;
  while (1)
  {
	   	/** 
			* 接收COM1口的数据,分析并处理 
			* 可以将此段代码封装为一个函数,在主程序其它流程调用
		  */
		if(Rxflag)
		{
			if (usRxCount < sizeof(ucaRxBuf))
			{
				ucaRxBuf[usRxCount++] = ucTemp;
			}
			else
			{
				usRxCount = 0;
			}
			
			/* 遇到换行字符,认为接收到一个命令 */
			if (ucTemp == 0x0A)	/* 换行字符 */
			{		
				Usart_SendStr_length(ucaRxBuf,usRxCount);
				usRxCount = 0;
			}
			Rxflag=0;
		}
	  
  Usart_SendString("越努力越幸运!\n");
  Usart_SendString("加油!\n");
  Delay(1000);


}



void USARTx_IRQHANDLER(void)
{
	if(USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET)
	{ 	
	  Rxflag=1;		
		ucTemp = USART_ReceiveData(USARTx);
	} 
	 
}

四、实验效果

USART串口通信

参考博客:

(八)STM32 USART —— 串口通讯_usart串口电路-CSDN博客

结束语

本文以STM32VET6为例讲解了如何用STM32单片机中USART通信协议来串口通信,并向XCOM发送信息,并指出其中的易坑点。希望对大家有所帮助!如果还有什么问题,欢迎评论区留言,谢谢!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | Leetcode C语言题解之第128题最长连续序列

题目&#xff1a; 题解&#xff1a; typedef struct {int key;UT_hash_handle hh; }Hash; int longestConsecutive(int* nums, int numsSize) {Hash* headNULL;Hash* tempNULL;for(int i0;i<numsSize;i){int numnums[i];HASH_FIND_INT(head,&num,temp);if(!temp){temp…

数据结构与算法04-栈和队列

介绍 栈和队列。事实上它们并不是全新的东西&#xff0c;只不过是多加了一些约束条件的数组而已。但正是这些约束条件为它们赋予了巧妙的用法。 栈和队列都是处理临时数据的灵活工具。在操作系统、打印任务、数据遍历等各种需要临时容器才能构造出美妙算法的场景&#xff0c;…

SQL实验 带函数查询和综合查询

一、实验目的 1&#xff0e;掌握Management Studio的使用。 2&#xff0e;掌握带函数查询和综合查询的使用。 二、实验内容及要求 1&#xff0e;统计年龄大于30岁的学生的人数。 --统计年龄大于30岁的学生的人数。SELECT COUNT(*) AS 人数FROM StudentWHERE (datepart(yea…

Medieval Lowpoly City with Toon Shader

介绍中世纪低地城市,这是一个创造历史场景、城市和环境的杰作,带有中世纪时期的魔力。 该包拥有70多个精心制作的模型,包括模块化选项,并通过着色器进行了增强,捕捉到了乡村建筑和细节道具的精髓。 用精心挑选的色彩和材料,让自己沉浸在历史的魅力中,仿佛漫步在中世纪的…

YOLOv3深入解析与实战:实时目标检测的高效多尺度架构网络

参考&#xff1a; https://arxiv.org/pdf/1804.02767.pdf https://blog.csdn.net/weixin_43334693/article/details/129143961 网上有很多关于yolo的文章&#xff0c;有些东西没讲清楚&#xff0c;基于自己对论文的理解&#xff0c;也做一个按照自己的想法做的理解。 1. 预测…

Rustdesk 自建服务器教程

一、环境 阿里云轻量服务器、debian11 系统 二、服务端搭建 2.1、开放防火墙指定端口 TCP(21115, 21116, 21117, 21118, 21119)UDP(21116) 2.2、安装 rustdesk 服务器文件 在 github 下载页https://github.com/rustdesk/rustdesk-server/releases/&#xff0c;下载 rustde…

大饼在一个比较关键的转折点,等某个东风来。。。。

1、历史数据对比&#xff0c;看多 图上方指标为BTC价格&#xff1b; 下方链上指标为BTC长期持有者成本均价跟BTC短期持有者成本均价之比。 从历史来看&#xff0c;我们正在启动往顶部的路上&#xff0c;不要畏惧。 2、结构为下降趋势&#xff0c;看空 3、长期持有者MVRV&…

几种更新 npm 项目依赖的实用方法

引言 在软件开发的过程中&#xff0c;我们知道依赖管理是其中一个至关重要的环节。npm&#xff08;Node Package Manager&#xff09; 是 Node.js 的包管理器&#xff0c;它主要用于 Node.js 项目的依赖管理和包发布。随着项目的不断发展&#xff0c;依赖库的版本更新和升级成…

Windows 2000 Server:安全配置终极指南

"远古技术&#xff0c;仅供娱乐" &#x1f4ad; 前言&#xff1a;Windows 2000 服务器在当时的市场中占据了很大的比例&#xff0c;主要原因包括操作简单和易于管理&#xff0c;但也经常因为安全性问题受到谴责&#xff0c;Windows 2000 的安全性真的那么差吗&#x…

YOLOv9改进策略 | Conv篇 | 利用YOLOv10提出的SCDown魔改YOLOv9进行下采样(附代码 + 结构图 + 添加教程)

一、本文介绍 本文给大家带来的改进机制是利用YOLOv10提出的SCDown魔改YOLOv9进行下采样&#xff0c;其是更高效的下采样。具体而言&#xff0c;其首先利用点卷积调整通道维度&#xff0c;然后利用深度卷积进行空间下采样。这将计算成本减少到和参数数量减少到。同时&#xff…

【人工智能003】图像识别算法模型常见术语简单总结(已更新)

1.熟悉、梳理、总结数据分析实战中的AI图像识别等实战研发知识体系&#xff0c;这块领域很大&#xff0c;需要耗费很多精力&#xff0c;逐步总结、更新到位&#xff0c;&#xff0c;&#xff0c; 2.欢迎点赞、关注、批评、指正&#xff0c;互三走起来&#xff0c;小手动起来&am…

3、flex弹性盒布局(flex:1?、水平垂直居中、三栏布局)

一、flex布局 任何一个容器都可以指定为 Flex 布局。块元素&#xff0c;行内元素即可。 div{ display: flex; } span{ display: inline-flex; } 注意&#xff0c;设为 Flex 布局以后&#xff0c;子元素的float、clear和vertical-align属性将失效。 二、flex属性 父容器…

WordPress子比内容同步插件

1.支持分类替换 将主站同步过来的文章分类进行替换 2.支持本地化文章图片 &#xff08;使用储存桶可能会导致无法保存图片&#xff09; 3.支持自定义文章作者&#xff08;选择多个作者则同步到的文章作者将会随机分配&#xff09; 4.支持将同步过来的文章自定义文章状态&…

ThinkBook 14 G6+ IMH(21LD)原厂Win11系统oem镜像下载

lenovo联想笔记本电脑原装出厂Windows11系统安装包&#xff0c; 恢复开箱状态自带预装系统&#xff0c;含恢复重置还原功能 链接&#xff1a;https://pan.baidu.com/s/1WIPNagHrC0wqYC3HIcua9A?pwdhzqg 提取码&#xff1a;hzqg 联想原装出厂系统自带所有驱动、出厂主题壁…

基于Win11下的Wireshark的安装和使用

Wireshark的安装和使用 前言一、Wireshark是什么简介 二、下载Wireshark下载过程查看自己电脑配置 三、安装Wireshark安装过程安装组件创建快捷方式winPacpNpcap 打开检验 四、使用Wireshark实施抓包捕获数据包 五、基于Wireshark使用显示过滤器简介使用方法注意ICMP的请求和应…

dibbler-DHCPv6 的开源框架(C++ 实现)2

前置 在 dibbler-DHCPv6 的开源框架&#xff08;C 实现&#xff09;1 说了 dibbler 的安装和编译、使用。在这里说一下 server 的源码分析。 一、主函数文件 dibbler/Port-linux/dibbler-server.cpp 代码路径&#xff1a; 二、主要函数解释 1. 加载配置文件和设置 DUID …

【Python Cookbook】S01E12 根据字段将记录分组

目录 问题解决方案讨论 问题 如果有一系列的字典或对象实例&#xff0c;我们想根据某个特定的字段来分组迭代数据。 解决方案 假设有如下字典列表&#xff1a; rows [{address: 5412 N CLARK, date: 07/01/2012},{address: 5148 N CLARK, date: 07/04/2012},{address: 580…

----JAVA 继承----

引言 再java中你能创造出很多的类&#xff0c;但如果这些类中的成员再另一个类中也要使用&#xff0c;那么就要用到继承来实现指定类中成员的使用了 那么也就可以写出这样的代码 再类Cat中使用了类Animal的成员&#xff0c;这里我们称Cat叫子类&#xff0c;Animal叫父类 概念…

上位机图像处理和嵌入式模块部署(f407 mcu中tf卡读写和fatfs挂载)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 很早之前&#xff0c;个人对tf卡并不是很重视&#xff0c;觉得它就是一个存储工具而已。后来在移植v3s芯片的时候&#xff0c;才发现很多的soc其实…

蓝奏管理器iapp源码V3

蓝奏登录注册&#xff0c;简单管理文件夹等都没问题&#xff0c;就是上传接口需要有能力的人抓包进行修复一下&#xff08;我留了之前还能正常使用的接口&#xff0c;也是蓝奏官方的&#xff0c;所以参照一下就行。&#xff09;&#xff0c;这个应该也不是什么大问题&#xff0…