USART串口协议

USART串口协议

文章目录

  • USART串口协议
    • 1. 通信接口
    • 2.串口通信
      • 2.1硬件电路
      • 2.2电平标准
      • 2.3串口参数及时序(软件部分)
    • 3.USART串口外设
      • 3.1串口外设
      • 3.2USART框图
      • 3.3USART基本结构
      • 3.4数据帧
    • 4.输入电路
      • 4.1起始位侦测
      • 4.2数据采样
    • 5.波特率发生器
    • 6.相关函数介绍
    • 7.串口发送
      • 7.1接线图
      • 7.2代码编写
        • 7.2.1主程序代码main.c
        • 7.2.2函数定义Serial.c
        • 7.2.3函数定义Serial.h
    • 8.串口发送+接收
      • 8.1接线图
      • 8.2代码编写
        • 8.2.1主程序代码
        • 8.2.2函数定义
        • 8.2.3函数定义
    • n.总结
      • n.1USART实现步骤

1. 通信接口

  • 通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统
  • 通信协议:制定通信的规则,通信双方按照协议规则进行数据收发

stm32中的通信协议(只列出最典型的参数)

名称引脚双工时钟电平设备说明
USARTTX、RX全双工异步单端点对点TX是数据发送引脚,TP是数据接收引脚
I2CSCL、SDA半双工同步单端多设备SCL是时钟,SDA是数据
SPISCLK、MOSI、MISO、CS全双工同步单端多设备MOSI主机输出数据脚,MISO主机输入数据脚,CS片选,用于指定通信的对象
CANCAN_H、CAN_L半双工异步差分多设备差分数据脚,用两个数据表示一个差分数据
USBDP、DM半双工异步差分点对点D+,D-,也是一对差分数据脚

全双工:就是指通信双方能够同时进行双向通信,一般来说全双工的通信都有两根通信线,表中的两个是合成一根的

单工:是指数据只能从一个设备到另一个设备,而不能反着来

同步:有单独的时钟线,可以在时钟信号的指引下进行采样

异步:没有时钟线,需要双方约定一个采样频率,且还要加一些帧头帧率等,进行采样位置对齐

单端:引脚的高低电平都是对GND的电压差,所以单端通信的双方需要共地,就是把GND接在一起

差分:靠两个引脚的电压差来传输信号的,通信的时候可以不需要GND,USB有些地方需要单端信号。优点:使用差分信号可以极大地提高抗干扰特性,所以差分信号一般传输信号和距离都会非常高

2.串口通信

  • 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信
  • 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力

串口转USB为例:

串口USB

2.1硬件电路

  • 简单双向串口通信有两根通信线(发送端TX和接收端RX)
  • TX与RX要交叉连接
  • 当只需单向的数据传输时,可以只接一根通信线
  • 当电平标准不一致时,需要加电平转换芯片

硬件电路

2.2电平标准

  • 电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

  • TTL电平:+3.3V或+5V表示1,0V表示0

  • RS232电平:-3-15V表示1,+3+15V表示0

  • RS485电平:两线压差+2+6V表示1,-2-6V表示0(差分信号),该电平可实现远距离通信

2.3串口参数及时序(软件部分)

  • 波特率:串口通信的速率,每秒传码元的个数,单位是码元每秒/s,或者直接叫波特(Baud)(发送和接收必须约定好速率)
  • 起始位:标志一个数据帧的开始,固定为低电平
  • 数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
  • 校验位:用于数据验证,根据数据位计算得来
  • 停止位:用于数据帧间隔,固定为高电平

串口数据

串口时序

串口时序

总结:TX引脚定时输出翻转的高低电平,RX引脚定时读取引脚的高低电平

字节数据的传递:每个字节的数据+起始位+停止位+可选校验位,打包成数据帧,依次输出在TX引脚,另一端RX引脚依次接收

3.USART串口外设

3.1串口外设

  • USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器
  • USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
  • 自带波特率发生器,最高达4.5Mbits/s
  • 可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
  • 可选校验位(无校验/奇校验/偶校验)
  • 支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN
  • STM32F103C8T6 USART资源: USART1、 USART2、 USART3

硬件控制流:例A向B发送数据,A发的太快了,如果B没有硬件流控制,那么B只有抛弃新数据或覆盖原数据。如果有硬件流控制,在硬件电路上,会多出一根线。如果B没有准备好,就置高电平,如果B准备好了就置低电平,A在接收到B的反馈后会做出反应

3.2USART框图

USART框图

3.3USART基本结构

USART基本结构

3.4数据帧

数据帧1

4.输入电路

4.1起始位侦测

起始位侦测

4.2数据采样

数据采样

5.波特率发生器

  • 发送器和接收器的波特率由波特率寄存器BRR里的DIV确定
  • 计算公式:波特率 = f PCLK2/1 f_{\text{PCLK2/1}} fPCLK2/1/ (16 * DIV)

波特率发生器

6.相关函数介绍

没解释

void USART_DeInit(USART_TypeDef* USARTx);
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);

用来配置同步时钟输出的,包括时钟是不是要输出,时钟的极性相位等参数

void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);//开启RXNE标志位的通道
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState);//开启USART到DMA的触发通道
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);//发送数据
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);//接收数据
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);//获取标志位状态
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

7.串口发送

7.1接线图

串口发射接线图

7.2代码编写

7.2.1主程序代码main.c
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
//#include "OLED_Font.h"
#include "Serial.h"


int main(void){
	
	OLED_Init();
	Serial_Init();
	
	Serial_SendByte(0x41);
	uint8_t MyArray[] = {0x42, 0x43, 0x44, 0x45};//定义一个数组
	Serial_SendArray(MyArray, 4);
	Serial_SendString("helloWorld!\n");
	Serial_SendNumber(123456,6);
	//方法1:重定向
	printf("Num2=%d\r\n", 222);
	//需要重定向fputc函数,并在工程选项里勾选Use MicroLIB
	/*方法2:使用sprintf打印到字符数组,再用串口发送字符数组,此方法打印到字符数组,之后想怎么处理都可以,可在多处使用*/
	char String[100];					//定义字符数组
	sprintf(String, "\r\nNum3=%d", 333);//使用sprintf,把格式化字符串打印到字符数组
	Serial_SendString(String);			//串口发送字符数组(字符串)
	
	/*方法3:将sprintf函数封装起来,实现专用的printf,此方法就是把方法2封装起来,更加简洁实用,可在多处使用*/
	Serial_Printf("\r\nNum4=%d", 444);	//串口打印字符串,使用自己封装的函数实现printf的效果
	Serial_Printf("\r\n");
	
	while(1){
	}
}

7.2.2函数定义Serial.c
#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

void Serial_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA	,ENABLE);
	
	//GPIO初始化,输出只需要初始化一个
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 9600;//波特率(我们给出函数会自己计算)
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制(直接复制参数名称,开启代码提示CTRL+ALT+空格)
	USART_InitStructure.USART_Mode = USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_No;//检验位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位,0.5、1、1.5、2
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长,可选8或9位
	
	USART_Init(USART1,&USART_InitStructure);
	
	//开启
	USART_Cmd(USART1,ENABLE);
}

//发送一个Byte
void Serial_SendByte(uint8_t Byte){
	USART_SendData(USART1,Byte);
	//发送数据寄存器空标志位,等待TXE置1,标志位不需要手动清除
															//USART_FLAG_TXE 是发送数据寄存器空标志位(Transmit data register empty)。当该标志位被置 1 时,表示 USART 的发送数据寄存器为空,可以继续写入新的数据;
														//当该标志位为 0(RESET)时,表示发送数据寄存器仍有数据,需要等待。
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

//遍历数组,并发送
void Serial_SendArray(uint8_t *Array,uint16_t Length){
	uint16_t i;
	
	for(i=0;i<Length;i++){
		Serial_SendByte(Array[i]);
	}
}

//遍历字符串,并发送
void Serial_SendString(char *String){
	uint8_t i;
	for(i=0;String[i] != '\0';i++){
		Serial_SendByte(String[i]);
	}
}

//拆分多位数
uint32_t Serial_Pow(uint32_t x,uint32_t y){
	uint32_t Result = 1;
	while(y--){
		Result = Result*x;
	}
	return Result;
}

//分别发送拆分的数
void Serial_SendNumber(uint32_t Number,uint8_t Length){
	uint8_t i;
	for(i=0;i<Length;i++){
		Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+'0');/*在串口通信中,通常需要发送字符的 ASCII 码。
																	数字 0 - 9 的 ASCII 码是连续的,字符 '0' 的 ASCII 码值为 48。
																	将数字加上 '0' 可以将其转换为对应的 ASCII 码字符。例如:
																	数字 1 加上 '0' 得到字符 '1',其 ASCII 码值为 49。
																	数字 2 加上 '0' 得到字符 '2',其 ASCII 码值为 50。
																	数字 3 加上 '0' 得到字符 '3',其 ASCII 码值为 51。
																*/
	}
}

//printf的底层代码,显示信息需要经过该函数
int fputc(int ch,FILE *f){
	Serial_SendByte(ch);
	
	return ch;
}

void Serial_Printf(char *format,...){
	char String[100];			
	va_list arg;					
    va_start(arg, format);			
    vsprintf(String, format, arg);	
    va_end(arg);					
    Serial_SendString(String);
}	

7.2.3函数定义Serial.h
#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array,uint16_t Length);
void Serial_SendString(char *String);
uint32_t Serial_Pow(uint32_t x,uint32_t y);
void Serial_SendNumber(uint32_t Number,uint8_t Length);
int fputc(int ch,FILE *f);
void Serial_Printf(char *format,...);

#endif

8.串口发送+接收

8.1接线图

串口发送+接收

8.2代码编写

8.2.1主程序代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "OLED.h"
//#include "OLED_Font.h"
#include "Serial.h"

uint8_t RxData;

int main(void){
	
	OLED_Init();
	Serial_Init();
	OLED_ShowString(1,1,"RxData:");
	
	while(1){
		//不断的判断RXNE标志位
//		if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET){
//			RxData = USART_ReceiveData(USART1);
//			OLED_ShowHexNum(1,1,RxData,2);
//		}

		if(Serial_GetRxFlag() == 1){
			RxData = Serial_GetRxData();
			Serial_SendByte(RxData);
			OLED_ShowHexNum(1,8,RxData,2);
	}
}}

8.2.2函数定义
#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

uint8_t Serial_RxFlag;
uint8_t Serial_RxData;

void Serial_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA	,ENABLE);
	
	//GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 9600;//波特率(我们给出函数会自己计算)
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流控制(直接复制参数名称,开启代码提示CTRL+ALT+空格)
	USART_InitStructure.USART_Mode = USART_Mode_Tx |USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;//检验位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位,0.5、1、1.5、2
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长,可选8或9位
	
	USART_Init(USART1,&USART_InitStructure);
	
	//开启RXNE到NVIC的通道
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//开启NVIC的通道
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	//开启
	USART_Cmd(USART1,ENABLE);
}

//标志位
uint8_t Serial_GetRxFlag(void)
{
	if(Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;//返回1,并自动清零标志位
	}
	return 0;
}

//Rx封装
uint8_t Serial_GetRxData(void)
{
		return Serial_RxData;
}

//中断函数
void USART1_IRQHandler(void){
	if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET)
	{
		Serial_RxData = USART_ReceiveData(USART1);
		Serial_RxFlag = 1;
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}
}

//发送一个Byte
void Serial_SendByte(uint8_t Byte){
	USART_SendData(USART1,Byte);
	//发送数据寄存器空标志位,等待TXE置1,标志位不需要手动清除
															//USART_FLAG_TXE 是发送数据寄存器空标志位(Transmit data register empty)。当该标志位被置 1 时,表示 USART 的发送数据寄存器为空,可以继续写入新的数据;
														//当该标志位为 0(RESET)时,表示发送数据寄存器仍有数据,需要等待。
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

//遍历数组,并发送
void Serial_SendArray(uint8_t *Array,uint16_t Length){
	uint16_t i;
	
	for(i=0;i<Length;i++){
		Serial_SendByte(Array[i]);
	}
}

//遍历字符串,并发送
void Serial_SendString(char *String){
	uint8_t i;
	for(i=0;String[i] != '\0';i++){
		Serial_SendByte(String[i]);
	}
}

//拆分多位数
uint32_t Serial_Pow(uint32_t x,uint32_t y){
	uint32_t Result = 1;
	while(y--){
		Result = Result*x;
	}
	return Result;
}

//分别发送拆分的数
void Serial_SendNumber(uint32_t Number,uint8_t Length){
	uint8_t i;
	for(i=0;i<Length;i++){
		Serial_SendByte(Number/Serial_Pow(10,Length-i-1)%10+'0');/*在串口通信中,通常需要发送字符的 ASCII 码。
																	数字 0 - 9 的 ASCII 码是连续的,字符 '0' 的 ASCII 码值为 48。
																	将数字加上 '0' 可以将其转换为对应的 ASCII 码字符。例如:
																	数字 1 加上 '0' 得到字符 '1',其 ASCII 码值为 49。
																	数字 2 加上 '0' 得到字符 '2',其 ASCII 码值为 50。
																	数字 3 加上 '0' 得到字符 '3',其 ASCII 码值为 51。
																*/
	}
}

//printf的底层代码,显示信息需要经过该函数
int fputc(int ch,FILE *f){
	Serial_SendByte(ch);
	
	return ch;
}

void Serial_Printf(char *format,...){
	char String[100];			
	va_list arg;					
    va_start(arg, format);			
    vsprintf(String, format, arg);	
    va_end(arg);					
    Serial_SendString(String);
}	

8.2.3函数定义
#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array,uint16_t Length);
void Serial_SendString(char *String);
uint32_t Serial_Pow(uint32_t x,uint32_t y);
void Serial_SendNumber(uint32_t Number,uint8_t Length);
int fputc(int ch,FILE *f);
void Serial_Printf(char *format,...);
uint8_t Serial_GetRxFlag(void);
uint8_t Serial_GetRxData(void);

#endif

n.总结

n.1USART实现步骤

  1. 开启时钟,把需要的USART和GPIO时钟开启
  2. GPIO初始化,把TX配置成复用输出,RX配置成输入
  3. 配置USART,直接使用一个结构体
  4. 如果只需要发送功能,直接开启USART时钟,初始化结束,

(如果需要配置接收的功能那么还需要配置中断,在开启USART之前,再加上ITConfig和NVIC的代码)

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

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

相关文章

2025 西湖论剑wp

web Rank-l 打开题目环境&#xff1a; 发现一个输入框&#xff0c;看一下他是用上面语言写的 发现是python&#xff0c;很容易想到ssti 密码随便输&#xff0c;发现没有回显 但是输入其他字符会报错 确定为ssti注入 开始构造payload&#xff0c; {{(lipsum|attr(‘global…

twisted实现MMORPG 游戏数据库操作封装设计与实现

在设计 MMORPG&#xff08;大规模多人在线角色扮演游戏&#xff09;时&#xff0c;数据库系统是游戏架构中至关重要的一部分。数据库不仅承担了游戏中各种数据&#xff08;如玩家数据、物品数据、游戏世界状态等&#xff09;的存储和管理任务&#xff0c;还必须高效地支持并发访…

PyCharm 批量替换

选择替换的内容 1. 打开全局替换窗口 有两种方式可以打开全局替换窗口&#xff1a; 快捷键方式&#xff1a; 在 Windows 或 Linux 系统下&#xff0c;按下 Ctrl Shift R。在 Mac 系统下&#xff0c;按下 Command Shift R。菜单操作方式&#xff1a;点击菜单栏中的 Edit&…

LabVIEW用户界面设计原则

在LabVIEW开发中&#xff0c;用户界面&#xff08;UI&#xff09;设计不仅仅是为了美观&#xff0c;它直接关系到用户的操作效率和体验。一个直观、简洁、易于使用的界面能够大大提升软件的可用性&#xff0c;尤其是在复杂的实验或工业应用中。设计良好的UI能够减少操作错误&am…

网络防御高级-第8章及之前综合作业

标准版 接口ip配置 r2 [r2]interface GigabitEthernet 0/0/0 [r2-GigabitEthernet0/0/0]ip address 13.0.0.3 24 [r2-GigabitEthernet0/0/0]interface GigabitEthernet 0/0/1 [r2-GigabitEthernet0/0/1]ip address 100.1.1.254 24 [r2-GigabitEthernet0/0/1]interface Gigab…

若依系统环境搭建记录

开源若依系统网上资料也很全的&#xff0c;本篇博文记录下自己搭建环境过程中遇到的一些问题。 配置Maven和编辑器选择 我懒得配置Eclipse了&#xff0c;直接用vscode作为编辑器&#xff0c;后面构建运行都用命令行。 配置数据库连接 按照mysql5.7按网上教程即可&#xff1…

C# 运算符

总目录 前言 在C#中&#xff0c;运算符是用于执行特定操作的符号。它们可以用于处理变量、常量或其他表达式。C# 提供了丰富的运算符集合&#xff0c;用于执行各种操作&#xff0c;如算术运算、逻辑判断、位操作等。了解这些运算符及其使用方式对于编写高效且功能强大的C#程序…

为AI聊天工具添加一个知识系统 之103 详细设计之44 自性三藏 之4 祖传代码 之2

本文要点 要点 前面的所有讨论都是为了给出我的设计项目&#xff08;为使用AI聊天工具的聊天者 开挂一个知识系统&#xff09; 的祖传代码 的完整设计&#xff0c;其中 的“槽”&#xff08;占位符变量&#xff09;的 库元&#xff08;宝性和自性creator -本俱 替换内容标准模…

wireshark网络抓包

由于图片和格式解析问题&#xff0c;可前往 阅读原文 到这里已经讲了两个抓包工具的使用了&#xff0c;大家应该对抓包不是很陌生了。而wireshark相对于fiddler和charles更加偏向于网络层面的抓包或者说是一个网络封包分析工具。使用对象更适合于网络相关人员(网络管理员/相关运…

深入理解Linux网络随笔(一):内核是如何接收网络包的(下篇)

3、接收网络数据 3.1.1硬中断处理 数据帧从网线到达网卡时候&#xff0c;首先到达网卡的接收队列&#xff0c;网卡会在初始化时分配给自己的RingBuffer中寻找可用内存位置&#xff0c;寻找成功后将数据帧DMA到网卡关联的内存里&#xff0c;DMA操作完成后&#xff0c;网卡会向…

新版电脑通过wepe安装系统

官方下载链接 WIN10下载 WIN11下载 微PE 启动盘制作 1&#xff1a;选择启动盘的设备 2&#xff1a;选择对应的U盘设备&#xff0c;点击安装就可以&#xff0c;建议大于8g 3&#xff1a;在上方链接下载需要安装的程序包&#xff0c;放入启动盘&#xff0c;按需 更新系统 …

蓝桥杯之KMP算法

算法思想 代码实现 int* getnext() {int* next new int[s2.size()];int j 0;//用来遍历子串int k -1;//子串中公共子串的长度next[0] -1;while (j < s2.size() - 1){if (k-1||s2[k] s2[j]){k;j;if (s2[k] s2[j]){next[j] next[k];}else{next[j] k;}}else{k next[k…

jsp页面跳转失败

今天解决一下jsp页面跳转失败的问题 在JavaWeb的学习过程中&#xff0c;编写了这样一段代码&#xff1a; <html> <body> <h2>Hello World!</h2><%--这里提交的路径&#xff0c;需要寻找到项目的路径--%> <%--${pageContext.request.context…

如何实现对 ELK 各组件的监控?试试 Metricbea

上一章基于 Filebeat 的日志收集使用Filebeat收集文件中的日志&#xff0c;而Metricbeat则是收集服务器存活性监测和系统指标的指标。 1. Filebeat和Metricbeat的区别 特性FilebeatHeartbeat作用收集和转发日志监测服务可用性数据来源服务器上的日志文件远程主机、API、服务主…

DeepSeek-VL2 环境配置与使用指南

DeepSeek-VL2 环境配置与使用指南 DeepSeek-VL2 是由 DeepSeek 公司开发的一种高性能视觉-语言模型&#xff08;VLM&#xff09;。它是 DeepSeek 系列多模态模型中的一个版本&#xff0c;专注于提升图像和文本之间的交互能力。 本文将详细介绍如何配置 DeepSeek-VL2 的运行环…

Golang的并发编程问题解决思路

Golang的并发编程问题解决思路 一、并发编程基础 并发与并行 在计算机领域&#xff0c;“并发”和“并行”经常被混为一谈&#xff0c;但它们有着不同的含义。并发是指一段时间内执行多个任务&#xff0c;而并行是指同时执行多个任务。在 Golang 中&#xff0c;通过 goroutines…

多能互补综合能源系统,改变能源结构---安科瑞 吴雅芳

多能互补综合能源系统是一种通过整合多种能源的形势&#xff08;如电力、天然气、热能、冷能等&#xff09;和多种能源技术&#xff08;如可再生能源、储能技术、智能电网等&#xff09;&#xff0c;实现能源利用和配置调整的系统。其目标是通过多能互补和协同优化&#xff0c;…

Linux部署DeepSeek r1 模型训练

之前写过一篇windows下部署deepseekR1的文章&#xff0c;有小伙伴反馈提供一篇linux下部署DeepSeek r1 模型训练教程&#xff0c;在 Linux 环境下&#xff0c;我找了足够的相关资料&#xff0c;花费了一些时间&#xff0c;我成功部署了 DeepSeek R1 模型训练任务&#xff0c;结…

使用pyCharm创建Django项目

使用pyCharm创建Django项目 1. 创建Django项目虚拟环境&#xff08;最新版版本的Django) 使用pyCharm的创建项目功能&#xff0c;选择Django,直接创建。 2. 创建Django项目虚拟环境&#xff08;安装特定版本&#xff09; 2.1创建一个基础的python项目 2.2 安装指定版本的D…

基于vue3实现的课堂点名程序

设计思路 采用vue3实现的课堂点名程序&#xff0c;模拟课堂座位布局&#xff0c;点击开始点名按钮后&#xff0c;一朵鲜花在座位间传递&#xff0c;直到点击结束点名按钮&#xff0c;鲜花停留的座位被点名。 课堂点名 座位组件 seat.vue <script setup>//组合式APIimpo…