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发送信息,并指出其中的易坑点。希望对大家有所帮助!如果还有什么问题,欢迎评论区留言,谢谢!

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

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

相关文章

嵌入式linux系统中图片处理详解

大家好,今天给大家分享一下,嵌入式中如何进行图像处理,常见的处理方式有哪几种?这次将详细分析一下 第一:BMP图形处理方式 图形的基本特点,所有的图像文件,都是一种二进制格式文件,每一个图像文件,都可以通过解析文件中的每一组二进制数的含义来获得文件中的各种信息…

DataCube 漏洞小结

在这里分享一下通过拖取 DataCube 代码审计后发现的一些漏洞&#xff0c;包括前台的文件上传&#xff0c;信息泄露出账号密码&#xff0c;后台的文件上传。当然还有部分 SQL 注入漏洞&#xff0c;因为 DataCube 采用的是 SQLite 的数据库&#xff0c;所以SQL 注入相对来说显得就…

海外高清短视频:四川京之华锦信息技术公司

海外高清短视频&#xff1a;探索世界的新窗口 在数字化时代的浪潮下&#xff0c;海外高清短视频成为了人们探索世界、了解异国风情的新窗口。四川京之华锦信息技术公司这些短视频以其独特的视角、丰富的内容和高清的画质&#xff0c;吸引了无数观众的目光&#xff0c;让人们足…

关于前端代码移动端的适配方案

为什么需要适配&#xff1f; 由于PC端和移动端的分辨率不同&#xff0c;前端展示的页面在两端设备如果原模原样的搬运则会导致PC端或移动端看到的画面相对于其设备的分辨率及其的不合理。 最为常见的是PC端正常浏览的网页没有做移动端适配&#xff0c;由于移动端分辨率普遍低于…

ChaosBlade混沌测试实践

ChaosBlade: 一个简单易用且功能强大的混沌实验实施工具 官方仓库&#xff1a;https://github.com/chaosblade-io/chaosblade 1. 项目介绍 ChaosBlade 是阿里巴巴开源的一款遵循混沌工程原理和混沌实验模型的实验注入工具&#xff0c;帮助企业提升分布式系统的容错能力&…

【CVE-2021-3156】——漏洞复现、原理分析以及漏洞修复

文章目录 前言1、漏洞概述2、漏洞复现2.1、漏洞复现测试环境2.2、漏洞复现具体步骤 3、漏洞原理3.1、前置知识3.1.1、sudo3.1.2、sudoedit3.1.3、转义字符 3.2、漏洞分析 4、漏洞修复5、参考文献总结 前言 2021年01月27日&#xff0c;RedHat官方发布了Sudo缓冲区/栈溢出漏洞的风…

基于SSM前后端分离版本的论坛系统-自动化测试

目录 前言 一、测试环境 二、环境部署 三、测试用例 四、执行测试 4.1、公共类设计 创建浏览器驱动对象 测试套件 释放驱动类 4.2、功能测试 注册页面 登录页面 版块 帖子 用户个人中心页 站内信 4.3、界面测试 注册页面 登录页面 版块 帖子 用户个人中心页…

【Qt秘籍】[005]-Qt的首次邂逅-创建

一、如何创建文件&#xff1f; 当我们打开Qt Creator&#xff0c;你会发现整个界面类目繁多。现在&#xff0c;让我们直接开始新建一个项目。 1.点击左上角的“文件”>点击“新建文件或项目” 2.如图&#xff0c;选择“Application”>“Qt Wifgets application”> “…

奇偶校验位

描述 题目描述&#xff1a; 现在需要对输入的32位数据进行奇偶校验,根据sel输出校验结果&#xff08;1输出奇校验&#xff0c;0输出偶校验&#xff09; 信号示意图&#xff1a; 波形示意图&#xff1a; 输入描述&#xff1a; 输入信号 bus sel 类型 wi…

rust安装

目录 一、安装1.1 在Windows上安装1.2 在Linux下安装 二、包管理工具三、Hello World3.1 安装IDE3.2 输出Hello World 一、安装 1.1 在Windows上安装 点击页面 安装 Rust - Rust 程序设计语言 (rust-lang.org)&#xff0c;选择"下载RUSTUP-INIT.EXE(64位&#xff09;&qu…

2021JSP普及组第三题:插入排序

2021JSP普及组第三题 题目&#xff1a; 思路&#xff1a; 题目要求排序后根据操作进行对应操作。 操作一需要显示某位置数据排序后的位置&#xff0c;所以需要定义结构体数组储存原数据的位置和数据本身排序后所得数据要根据原位置输出排序后的位置&#xff0c;所以建立一个新…

Linux网络编程:应用层协议|HTTPS

目录 1.预备知识 1.1.加密和解密 1.2.常见加密方式 1.2.1.对称加密 1.2.2.非对称加密 ​编辑 1.3.数据摘要&#xff08;数据指纹&#xff09;和数据签名 1.4.证书 1.4.1.CA认证 1.4.2.证书和数字签名 2.HTTPS协议 2.1.自行设计HTTPS加密方案 2.1.1.只使用对称加密 …

构建企业级AI私有知识库

一、引言 在当今竞争激烈的市场环境中&#xff0c;企业为了保持竞争优势&#xff0c;需要高效地管理和利用内部知识资源。构建一个企业级AI私有知识库&#xff0c;不仅可以集中存储和管理企业知识&#xff0c;还能通过人工智能技术实现知识的智能化处理和利用。本文将详细介绍…

软考系统集成项目管理工程师第7章思维导图发布

2024年开年&#xff0c;软考系统集成项目管理工程师官方教程&#xff0c;迎来了阔别7年的大改版&#xff0c;改版之后的软考中项考试&#xff0c;离同宗兄弟高项考试渐行渐远。 中项第3版教程&#xff0c;仅仅从教程来看&#xff0c;其难度已经不亚于高级的信息系统项目管理师&…

WebGL开发三维家装设计

使用WebGL开发三维家装设计软件是一项复杂而有趣的任务&#xff0c;涉及3D建模、渲染、用户交互等多个方面。以下是详细的开发步骤和技术要点。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 需求分析 目标用户 家装设计师家装公…

AVL树(C++)

文章目录 1. 键值对2. AVL树2.1 AVL树的概念2.2 AVL树节点的定义2.3 AVL树的插入2.3.1 按照二叉搜索树的方式插入新节点2.3.2 调整节点的平衡因子 2.4 AVL树的旋转2.4.1 右单旋2.4.2 左单旋2.4.3 左右双旋2.4.4 右左双旋 3. AVL树的删除4. AVL树的验证4. 源码 1. 键值对 键值对…

用follow.it为您的网站添加邮箱订阅功能(附2024版教程)

多数情况下网站用户浏览一次就不会来了&#xff08;即使用户已收藏您的网站&#xff09;&#xff0c;因为用户很可能已把您的网站忘了。那么怎么样才能抓住网站回头客&#xff0c;让用户再次回到您的网站呢&#xff1f;除了提供更优质的原创内容外&#xff0c;比较好的方法是给…

笔试强训week7

day1 Q1 难度⭐⭐ 旋转字符串_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 字符串旋转: 给定两字符串A和B&#xff0c;如果能将A从中间某个位置分割为左右两部分字符串&#xff08;可以为空串&#xff09;&#xff0c;并将左边的字符串移动到右边字符串后面组成新的…

c++新闻发布系统(支持登录注册)

c新闻发布系统(支持登录注册),支持新闻发布标题和内容 首先查看效果,系统主界面 vx:sredxc 这段代码是一个简单的新闻管理系统的实现。它包括两个类&#xff1a;UserManager&#xff08;用户管理&#xff09;和NewsManager&#xff08;新闻管理&#xff09;。UserManager负责用…

机器学习模型调试学习总结

1.学习内容 模型调试方法&#xff1a;冻结部分层&#xff0c;训练剩余层 实践&#xff1a;在一个预训练的 BERT 模型上冻结部分层&#xff0c;并训练剩余的层 模型调试方法&#xff1a;线性探测&#xff08;Linear Probe&#xff09; 实践&#xff1a;在一个预训练的 BERT …