【STM32】串口和printf

1.数据通信的基本知识

1.串行/并行通信

2.单工/半双工/全双工通信

类似于【广播  对讲 电话】

不是有两根线就是全双工,而是输入和输出都有对应的数据线。

3.同步/异步通信

区分同步/异步通信的根本:判断是否有时钟信号(时钟线)。如果有时钟线则是同步通信,如果没有时钟线则是异步通信。

4.波特率  VS  比特率

5.常见的串行通信接口

2.串口(RS-232)

1.什么是串口

实际上就是按位来对数据进行发送和接收

2.RS232电平和CMOS/TTL电平对比

3.设备间的RS232通信示意图

MAX323:将RS232电平---》TTL/CMOS电平

DB9接口就是COM接口

 4.STM32串口与电脑USB口通信示意图

USB/串口转换电路CH340C:USB电平---》TTL/CMOS电平

5.RS232异步通信协议

注意:异步通信协议中是没有使用到时钟线(SCLK)

1.通讯的起始和停止信号

串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑0的数据位表示,而数据包的停止信号可由0.5、1、1.5或2个逻辑1的数据位表示,只要双方约定一致即可。

2.数据校验

3.STM32USART

1.STM32USART简介

USART虽然是同步和异步都可以进行使用,但是我们大多数情况下使用的都是异步通信

2.STM32USART主要特征

3.在选型手册中查看USART/UART对应的引脚定义

4.STM32F1的USART框图

1.引脚说明

2.接收/发送数据的存放/处理位置

数据要先放在DR寄存器中,然后再通过DR寄存器操作CPU

3.波特率的处理

5.框图简化版

4.设置USART/UART波特率

1.计算公式

baud:波特率是用户自己定义的,然后求出USARTDIV,然后分为整数部分和小数部分,在存储到USART_BRR寄存器

2.波特比率寄存器(BRR)

3.举个例子

4.公式推导

因为小数部分和整数部分都要往左移动4位,所以将整个值*16

5.USART寄存器

USART_DR包含了已发送的数据或者接收到的数据。USART_DR实际是包含了两个寄存器,一个专门用于发送的可写TDR,一个专门用于接收的可读RDR。当进行发送操作时,往USART_DR写入数据会自动存储在TDR内;当进行读取操作时,向USART_DR读取数据会自动提取RDR数据。

TDR和RDR都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到RDR。

1.控制寄存器 1(USART_CR1)

2.控制寄存器 2(USART_CR2)

3. 控制寄存器 3(USART_CR3)

4. 数据寄存器(USART_DR)

1)具体传输多少位取决于寄存器USART_CR1中的位12M【字长】

2)设置好控制和波特率寄存器后,往该寄存器写入数据即可发送,接收数据则读该寄存器

5.状态寄存器(USART_SR)

根据TC位(发送完成位)可以知道能否发数据,根据RXNE位(读数据寄存器非空)知道是否收到数据。

6.需要配置的时序总结

6.USART/UART异步通信配置步骤

1.HAL_USART_Init

对USART进行初始化

2.HAL_USART_Receive_IT

USART的中断使能函数

这个函数是非阻塞式的,没有执行完也可以出来

3.HAL_USART_Receive

没有开启中断的UASRT

这个函数是阻塞式的,没有执行完不可以出来

7.通过串口接收或者发送一个字符

1.连接注意点

2.原理图分析

3.代码编写

usart_init()

相关的设置参数和开启usart的中断

hal_usart_mspinit()

1)使能USART1和对应的IO时钟

2)初始化IO

3)使能USART1中断,设置NVIC优先级

usart1_IRQHandler

中断回调服务函数

2)HAL_UART_iRQHandler()会清除中断

HAL_USART_RxCpltCallback

串口接收数据的回调函数

1.CubeMX和HAL库的串口实战

1、CubeMX中打开并设置串口

1.设置对应的RCC

2.查看原理图上对应的RX和TX

注意点:我们的串口对应的应该是RX--》TX,TX--》RX

我们要先查看原理图中是否已经帮我们接反了,如果没有则需要我们自己手动接反。

我们使用的STM32F103C8xx直接接入USB口即可

由上面分析可知,我们使能PA9和PA10即可

3.设置相关的USART

4.设置相关的时钟

5.在usart.c文件中添加输入/输出的函数

在使用之前记得先定义一个宏定义

#include<stdio.h>

“PUTCHAR_PROTOTYPE’’的含义

PUTCHAR_PROTOTYPE 是一个在使用HAL库时,用户可以定义的宏,通常用于重定向 printf 函数的输出。这个宏的目的是提供一个适配不同硬件平台的接口,以实现 printf 输出到用户定义的设备或串口。

#ifdef __GNUC__//当前在Linux系统下#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else//在windows下#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
/*** @brief  Retargets the C library printf function to the USART.* @param  None* @retval None*/
//PUTCHAR_PROTOTYPE 宏是一个用户在使用HAL库时可以自定义的宏,
//用于实现 printf 函数的输出重定向。
PUTCHAR_PROTOTYPE
//int fputc(int ch, FILE *f)
{/* Place your implementation of fputc here *//* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}

2、串口操作

(1)阻塞模式串口发送:CPU不做其他事情

MCU的CPU一个字节一个字节的将要发送的内容丢给串口模块,然后看着串口模块将这个字节发送出去,然后CPU再去拿下一个字节来丢给串口模块。直到本次要发送的所有字节全部发完,CPU才会去做其他事。

(2)中断模式串口发送:CPU轮询式查询

MCU的CPU向串口模块丢一个字节,然后串口模块慢慢发,CPU丢完这个字节后会跳出去做其他事情,等串口模块发完这个字节后会生成一个中断,中断会通知CPU过来继续丢下一个字节。

2.源码分析和串口发送的实现

1、阻塞式串口发送/接收

1.1 阻塞式发送:HAL_UART_Transmit(常用)

HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{uint16_t *tmp;uint32_t tickstart = 0U;/* Check that a Tx process is not already ongoing *///查看状态if (huart->gState == HAL_UART_STATE_READY){if ((pData == NULL) || (Size == 0U)){return  HAL_ERROR;}/* Process Locked *///将串口模块锁住了,将变量的值设置为"HAL_LOCKED"__HAL_LOCK(huart);huart->ErrorCode = HAL_UART_ERROR_NONE;huart->gState = HAL_UART_STATE_BUSY_TX;/* Init tickstart for timeout managment *///获取当前的时候,用于判断是否超时tickstart = HAL_GetTick();huart->TxXferSize = Size;//表示要发送的个数huart->TxXferCount = Size;//还要发送的个数=总个数-已经发送while (huart->TxXferCount > 0U){huart->TxXferCount--;if (huart->Init.WordLength == UART_WORDLENGTH_9B){//等待标志发生,查看是否超时if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK){return HAL_TIMEOUT;//超时}tmp = (uint16_t *) pData;huart->Instance->DR = (*tmp & (uint16_t)0x01FF);if (huart->Init.Parity == UART_PARITY_NONE){pData += 2U;}else{pData += 1U;}}else{if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK){return HAL_TIMEOUT;}//真正干活的代码huart->Instance->DR = (*pData++ & (uint8_t)0xFF);}}//查看发送是否已经完成【阻塞等待串口发完】if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK){return HAL_TIMEOUT;}/* At end of Tx process, restore huart->gState to Ready *///将状态设置回去huart->gState = HAL_UART_STATE_READY;/* Process Unlocked *///解锁__HAL_UNLOCK(huart);return HAL_OK;}else{return HAL_BUSY;}
}

1.2 阻塞式接收:HAL_UART_Receive(不常用)

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{uint16_t *tmp;uint32_t tickstart = 0U;/* Check that a Rx process is not already ongoing */if (huart->RxState == HAL_UART_STATE_READY){if ((pData == NULL) || (Size == 0U)){return  HAL_ERROR;}/* Process Locked */__HAL_LOCK(huart);huart->ErrorCode = HAL_UART_ERROR_NONE;huart->RxState = HAL_UART_STATE_BUSY_RX;/* Init tickstart for timeout managment */tickstart = HAL_GetTick();huart->RxXferSize = Size;huart->RxXferCount = Size;/* Check the remain data to be received */while (huart->RxXferCount > 0U){huart->RxXferCount--;if (huart->Init.WordLength == UART_WORDLENGTH_9B){//检查UART_FLAG_RXNE是否为空,如果为非空,表示接收到数据if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK){return HAL_TIMEOUT;}tmp = (uint16_t *) pData;if (huart->Init.Parity == UART_PARITY_NONE){*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);pData += 2U;}else{*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);pData += 1U;}}else{if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK){return HAL_TIMEOUT;}if (huart->Init.Parity == UART_PARITY_NONE){*pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);}else{*pData++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);}}}/* At end of Rx process, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;/* Process Unlocked */__HAL_UNLOCK(huart);return HAL_OK;}

3.延时时间的设置

如果我们设置的延时时间太长,则我们可能会在延时的时候错过一些字符的发送和接收。

 

4.总结

int main(void)
{//定义一个要进行发送的数据uint8_t sbuf[8]="stm32";//定义一个要进行接收的数据uint8_t rbuf[20]="";HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();while (1){//第一个参数要传入的是地址//size:要发送的大小//0x0000ffff:超时时间//	HAL_UART_Transmit(&huart1,sbuf,5,0x0000ffff);//	HAL_Delay(1000);//阻塞式的接收:接收一个后马上接着下一个接收//此方法最好一次发送一个bitHAL_UART_Receive(&huart1,rbuf,1,0x0000ffff);//将接收到的数值发送出来HAL_UART_Transmit(&huart1,rbuf,1,0x0000ffff);//这个延时时间不能太久,要不然可能会在延时的时候接收了一个字符,从而错过这个//HAL_Delay(100);}
}

阻塞式的发送实际用的很多,因为编程简单。缺陷是浪费高速CPU的部分性能,没有追求到串口发送和整个系统性能的最高。

2、非阻塞式(中断)串口发送

1.HAL_UART_Transmit_IT

这个函数没有超时时间,因为我们不用等。

注意点::要打开中断

HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{/* Check that a Tx process is not already ongoing */if (huart->gState == HAL_UART_STATE_READY){if ((pData == NULL) || (Size == 0U)){return HAL_ERROR;}/* Process Locked */__HAL_LOCK(huart);//因为我们使用中断方式,则需要在串口内部定义一个buf,使得buf指向data的地址huart->pTxBuffPtr = pData;huart->TxXferSize = Size;huart->TxXferCount = Size;huart->ErrorCode = HAL_UART_ERROR_NONE;huart->gState = HAL_UART_STATE_BUSY_TX;/* Process Unlocked */__HAL_UNLOCK(huart);/* Enable the UART Transmit data register empty Interrupt *///使能UART发送数据寄存器空中断__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);return HAL_OK;}else{return HAL_BUSY;}
}

2.注意点 

我们使用这个中断式的应该打开Usart的中断

int main(void)
{//定义一个要进行发送的数据uint8_t sbuf[8]="stm32";//定义一个要进行接收的数据uint8_t rbuf[20]="";HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();while (1){/**中断式发送和接收*/HAL_UART_Transmit_IT(&huart1,sbuf,5);HAL_Delay(100);}
}

3.printf重定向的实现

printf的实现其实就是重载fputc函数

要实现printf就要重写fputc

fputc-->printf

在使用USART(通用异步收发传输)时,fputc 函数通常用于将一个字符发送到串口。fputc 是标准C库函数,它用于将一个字符写入指定的输出流(通常是标准输出流 stdout)。

在使用USART进行串口通信时,fputc 的使用场景可能是在使用标准C库的 printf 函数时。printf 是一个格式化输出函数,通过重定向标准输出流,可以将格式化的数据发送到USART,从而实现通过串口发送数据的功能。

1.原始代码 

#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
/*** @brief  Retargets the C library printf function to the USART.* @param  None* @retval None*/
PUTCHAR_PROTOTYPE
{/* Place your implementation of fputc here *//* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;
}

2.注意点1: 

一定一定要勾选User MicroLIB

3.注意点2:

我们使用到了fputc,其中FILE中是定义在<stdio.h>中的宏定义

定义在usart.h中

int main(void)
{/* USER CODE BEGIN 1 *///定义一个要进行发送的数据uint8_t sbuf[8]="stm32";//定义一个要进行接收的数据uint8_t rbuf[20]="";HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();while (1){float a=4.532;printf("a=%f\n",a);printf("test\r");}
}

4.串口接收编程实战

1、阻塞式串口接收

CPU等着过来。所以当CPU临时去处理其他事情时,可能会错过一些串口的输出。所以我们基本上不用。如果真的要使用,则要协调好延时和串口的接收和发送。

2、中断式串口接收

使用中断的方式向串口发送数据并且输出

1.先开启uart中断

2.写中断处理函数:HAL_UART_RxCpltCallback

在main函数中

//rc用来暂存和处理串口接收到的字节内容的
uint8_t receive_char;//这个就是HAL库对接的中断处理程序
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{//判断是否为usart1if(huart->Instance == USART1){//这里就是真正的中断处理代码//我们这里的处理就是接收到一个字节后原封不动的发回去HAL_UART_Transmit(&huart1, &receive_char, 1,0xFF);//发送字符//等待本次接收完毕,同时开启下一次接收【更新receive_char】//HAL_UART_Receive_IT:开启中断处理流程while(HAL_UART_Receive_IT(&huart1, &receive_char, 1) != HAL_OK);}}

3.注册中断

由上面分析可以知道,我们在进入中断处理函数中,是将接收到的字符发送出去,所以我们需要在外部先接收到字符【触发中断】,才可以发送。所以我们需要在其他模块初始化的位置先进入一次中断,接收串口发送的数据。

3.测试代码

此代码:在我们不向串口发送字符时,每3s发送一次a,当我们向串口发送数据时,会马上在串口输出。

int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_USART1_UART_Init();//从此处进入中断处理程序HAL_UART_Receive_IT(&huart1, &receive_char, 1);while (1){float a=4.532;printf("a=%f\n",a);HAL_Delay(3000);}
}//这个就是HAL库对接的中断处理程序
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{//判断是否为usart1if(huart->Instance == USART1){//这里就是真正的中断处理代码//我们这里的处理就是接收到一个字节后原封不动的发回去HAL_UART_Transmit(&huart1, &receive_char, 1,0xFF);//发送字符//等待本次接收完毕,同时开启下一次接收【更新receive_char】//HAL_UART_Receive_IT:开启中断处理流程while(HAL_UART_Receive_IT(&huart1, &receive_char, 1) != HAL_OK);}}

3.处理串口中断的流程

在初始化部分已经将中断连接起来,到时候产生中断则直接进入【HAL_UART_RxCpltCallback】这个函数

5.案例1:基于串口的命令shell实现

命令shell:发送一个命令返回一个回应

1.协议自定义

(1)指令集:指令1:add    指令2:sub
(2)指令结束符:';'【定义普通指令中不可能出现的】
(3)指令中遇到回车和空格、Tab等特殊字符怎么办

2.实现思路分析

1.定义一个缓冲区,存储接到的数据

2.定义一个索引值

值存储再buf中的第几个字节

3.代码编写

/* USER CODE BEGIN 4 */
//这个就是HAL库对接的中断处理程序
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{//判断是否为usart1if(huart->Instance == USART1){//将receive_char的数值存放再buf中rev_buf[tindex]=receive_char;//暂存tindex++;//指向下一个while(HAL_UART_Receive_IT(&huart1, &receive_char, 1) != HAL_OK);}}

4.main函数编写

1)判断指令

2)buf和index要记得清空

6.串口实验

1.串口接收数据过程

2.串口发送数据过程

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

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

相关文章

ai剪辑矩阵系统源码+无人直播系统源码技术开发

开发AI剪辑矩阵系统和无人直播系统源码&#xff0c;需要以下步骤&#xff1a; 1. 市场调研&#xff1a;了解市场需求和竞品情况&#xff0c;明确系统的功能和特点。 2. 系统设计&#xff1a;设计系统的整体架构和功能模块&#xff0c;包括视频剪辑、直播推流、实时互动、数据分…

【LeetCode刷题-滑动窗口】-- 795.区间子数组个数

795.区间子数组个数 class Solution {public int numSubarrayBoundedMax(int[] nums, int left, int right) {return lessEqualsThan(nums,right) - lessEqualsThan(nums,left - 1);}private int lessEqualsThan(int[] nums,int k){int len nums.length;int res 0,left 0,ri…

基于Genio 700 (MT8390)芯片的AR智能眼镜方案

AR眼镜是一种具有前所未有发展机遇的设备&#xff0c;无论是显示效果、体积还是功能都有明显的提升。AR技术因其智能、实时、三维、多重交互和开放世界的特点备受关注。 AR眼镜集成了AR技术、语音识别、智能控制等多项高科技功能&#xff0c;可以帮助用户实现更加便捷、高效、个…

一种基于NB‑IOT的粮库挡粮门异动监测装置

一种基于NB‑IOT的粮库挡粮门异动监测装置,包括若干个NB‑IOT开门监测装置、物联网后台管理系统、NB‑IOT低功耗广域网络和用户访问终端;各个NB‑IOT开门监测装置通过NB‑IOT低功耗广域网络与物联网后台管理系统连接,物联网后台管理系统与用户访问终端连接。 我国以往粮食收储…

将 ONLYOFFICE 文档编辑器与 Node.js 应用集成

我们来了解下&#xff0c;如何将 ONLYOFFICE 文档编辑器与您的 Web 应用集成。 许多 Web 应用都可以从文档编辑功能中获益。但是要从头开始创建这个功能&#xff0c;需要花费大量时间和精力。幸运的是&#xff0c;您可以使用 ONLYOFFICE——这是一款开源办公套件&#xff0c;可…

一文总结MySQL的指令是如何工作的

当你输入一条MySQL指令时候有没有想过会发生什么&#xff1f; 建立连接 首先你得先连到数据库上才行&#xff0c;这又分为长连接和短链接&#xff0c;短链接就是你查询一次就断开连接&#xff0c;长连接是你可以多次查询直到主动断开连接&#xff08;也可能被杀死进程&#x…

C语言——冒泡排序

一、冒泡排序是什么 冒泡排序&#xff1a; 冒泡排序(Bubble Sort)&#xff0c;又被称为气泡排序或泡沫排序。升序时&#xff1a;它会遍历若干次需要排序的数列&#xff0c;每次遍历时&#xff0c;它都会从前往后依次的比较相邻两个数的大小&#xff1b;如果前者比后者大&#x…

三十二、W5100S/W5500+RP2040树莓派Pico<UPnP示例>

文章目录 1 前言2 简介2 .1 什么是UPnP&#xff1f;2.2 UPnP的优点2.3 UPnP数据交互原理2.4 UPnP应用场景 3 WIZnet以太网芯片4 UPnP示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 随着智能家居、物联网等…

centos虚拟机无法接受消息(防火墙)

1.利用wireshark抓包&#xff0c; 发现发送信息后&#xff0c; 虚拟机返回 :host administratively prohibited 2.发现是centos虚拟机未关闭防火墙 &#xff08;关闭后可正常接收消息&#xff09;

rabbitMQ的Topic模式的生产者与消费者使用案例

topic模式 RoutingKey 按照英文单词点号多拼接规则填充。其中消费者匹配规则时候 * 代表一个单词&#xff0c;#表示多个单词 消费者C1的RoutingKey 规则按照*.orange.* 匹配 绑定队列Q1 package com.esint.rabbitmq.work05;import com.esint.rabbitmq.RabbitMQUtils; import …

AI机器学习实战 | 使用 Python 和 scikit-learn 库进行情感分析

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…

OpenCV C++ 图像处理实战 ——《OCR字符识别》

OpenCV C++ 图像处理实战 ——《OCR字符识别》 一、结果演示二、tesseract库配置2.1下载编译三、OCR字符识别3.1 文本检测方式3.1.1 RIL_BLOCK3.1.2 RIL_PARA3.1.3 RIL_TEXTLINE3.1.4 RIL_WORD3.1.5 RIL_SYMBOL3.2 英文文本检测3.3 中英文本检测四、源码测试图像下载总结一、结…

Springboot+vue的学生成绩管理系统(有报告),Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的学生成绩管理系统&#xff08;有报告&#xff09;&#xff0c;Javaee项目&#xff0c;springboot vue前后端分离项目。 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家…

开源与闭源:驾驭大模型未来的关键决断

在数字化的时代洪流中&#xff0c;开源与闭源的选择不断成为技术界的重要分水岭。随着特斯拉CEO埃隆马斯克的言论及其决策&#xff0c;公开支持开源&#xff0c;并糅合商业理念与技术革新&#xff0c;使得这场辩论再次成为公众关注的焦点。那么&#xff0c;在这场关乎技术发展脉…

Adversarial Attacks on Neural Networks for Graph Data

Adversarial Attacks on Neural Networks for Graph Data----《针对图数据的神经网络的对抗攻击》 论文提出了两个问题&#xff1a; 1、属性图的深度学习模型容易受攻击吗&#xff1f; 2、他们的结果可靠吗&#xff1f; 回答这两个问题需要考虑到GNN的特性&#xff1a; ①关…

物联网赋能:WIFI HaLow在无线连接中的优势

在探讨无线网络连接时&#xff0c;我们不难发现&#xff0c;WIFI已经成为我们日常生活中不可或缺的一部分&#xff0c;承载了半数以上的互联网流量&#xff0c;并在家庭、学校、娱乐场所等各种场合广泛应用。然而&#xff0c;尽管WIFI4、WIFI5和WIFI6等协议无处不在&#xff0c…

Go ZIP压缩文件读写操作

创建zip文件 golang提供了archive/zip包来处理zip压缩文件&#xff0c;下面通过一个简单的示例来展示golang如何创建zip压缩文件&#xff1a; func createZip(filename string) {// 缓存压缩文件内容buf : new(bytes.Buffer)// 创建zipwriter : zip.NewWriter(buf)defer writ…

【网络安全】伪装IP网络攻击的识别方法

随着互联网的普及和数字化进程的加速&#xff0c;网络攻击事件屡见不鲜。其中&#xff0c;伪装IP的网络攻击是一种较为常见的攻击方式。为了保护网络安全&#xff0c;我们需要了解如何识别和防范这种攻击。 一、伪装IP网络攻击的概念 伪装IP网络攻击是指攻击者通过篡改、伪造I…

C/C++ 运用VMI接口查询系统信息

Windows Management Instrumentation&#xff08;WMI&#xff09;是一种用于管理和监视Windows操作系统的框架。它为开发人员、系统管理员和自动化工具提供了一种标准的接口&#xff0c;通过这个接口&#xff0c;可以获取有关计算机系统硬件、操作系统和应用程序的信息&#xf…

SDL音视频渲染

01-SDL简介 官网&#xff1a;https://www.libsdl.org/ 文档&#xff1a;http://wiki.libsdl.org/Introduction SDL&#xff08;Simple DirectMedia Layer&#xff09;是一套开放源代码的跨平台多媒体开发库&#xff0c;使用C语言写成。SDL提供了数种控制图像、声音、输出入的函…