当前位置: 首页 > news >正文

单片机-STM32部分:10、串口UART

飞书文档https://x509p6c8to.feishu.cn/wiki/W7ZGwKJCeiGjqmkvTpJcjT2HnNf

串口说明

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

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

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

RS485电平:两线压差+2~+6V表示1,-2 ~-6V表示0(差分信号)

STM32F103RC系列芯片中,有五个串口

3个USART,2个UART
USART:通用同步和异步收发器
UART:通用异步收发器
当进行异步通信时,这两者是没有区别的。区别在于USART比UART多了同步通信功能。

IO口说明:

点击图片可查看完整电子表格

TX:发送数据输出引脚。
RX:接收数据输入引脚。
如果发送设备发送太快,接收设备来不及处理,可以通过流控来控制传输的速度。
SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式,用于时钟同步
nRTS是请求发送,是输出脚,就是告诉别人,我当前能不能接收,用于硬件流控
nCTS是清除发送,是输入脚,用于接收别人nRTS的信号,用于硬件流控

硬件流控说明,例如:
接收端可以接收数据时,会设置nRTS输出低电平,此时发送端读取到低电平,开始发送数据。
接收端处理不过来时,设置nRTS为高电平,此时发送端读取到高电平,停止发送数据。

创建工程,设置SWD,设置时钟。

配置USART1为异步通信方式,不需要硬件流控制。

Asynchronous(异步通讯)主要使用
Synchronous(同步通讯,同步通讯相比于异步通讯多了个时钟CLK输出)
Single Wire (Half-Duplex)(单线(半双工)通讯)
Multiprocessor Communication(多处理器通信)
SmartCard、IrDA、LIN 智能卡、IrDA、LIN,这些是其他的一些协议,这些协议与串口非常相似,所以STM32对USART加了些改动,可兼容这些协议。IrDA用于红外通信的,一边红外发光管,另一边红外接收管,靠闪烁红外光通信,与遥控器的红外不同。LIN是局域网的通信协议,具体可以查看芯片手册。

关于硬件流控制,比如A设备有个TX向B设备RX发送数据,A设备发的太快导致B处理不过来,如果没有硬件流控制,B就只能抛弃新数据或者覆盖原数据了,如果有硬件流控制,在硬件电路上会多出一根线,如果B没准备好接收就置于高电平,准备好了就置低电平,A只会在B准备好的时候发送数据。
硬件流控制需要多使用两个IO,所以大部分情况都不使用,直接用软件做数据处理。

然后设置波特率为115200bps 数据长度8bit 没有校验位 1位停止位。

串口中,每个字节都装载在一个数据帧(10或11位)里,每个数据帧都由起始位数据位停止位,数据位有8个代表一个字节的8位。参数如下
波特率:串口通信的速率。波特率本来的意思是每秒传输码元的个数,单位是码元/s,或者直接叫波特(Baud),还有个速率叫比特率,每秒传输的比特数,单位是bit/s,或者是bps。在二进制调制下,一个码元就是一个bit,此时波特率等于比特率,单片机的串口通信基本都是二进制调制(高电平表示1,低电平表示0,一位就是1bit),所以串口的波特率经常会和比特率混用。
起始位:标志一个数据帧的开始,固定为低电平。空闲状态为高电平,起始位产生下降沿,来告诉设备要开始发送数据了
数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行
校验位:用于数据验证,根据数据位计算得来。这里串口用的是奇偶校验的数据验证方法,可以判断数据传输是否出错,如果出错可选择丢弃或者重传。可选择三种方式,无校验、奇校验、偶校验。奇校验,包括校验位在内的9个数据位会出现奇数个1,根据8位数据情况奇校验位补0或1,保证1的个数位奇数,接收方接收数据时,会验证数据位和校验位,检出率不高比如有两位同时出错,只校验奇偶特性是检验不出的。偶校验同理,只能保证一定检出率,所以一般不需要校验位,如果要更高检出率可以在软件层使用CRC校验
停止位:用于数据帧间隔,固定为高电平。也是为下一个起始位做准备(切换到高电平空闲状态)

波特率9600代表1s发送9600bit,也就是1bit发送需要100us左右
 

这时,软件会自动选择PA9与PA10做为串口的发送与接收引脚。

这时,我们可以生成工程

main.c
MX_USART1_UART_Init();usart.c
void MX_USART1_UART_Init(void)
{huart1.Instance = USART1;huart1.Init.BaudRate = 115200;huart1.Init.WordLength = UART_WORDLENGTH_8B;huart1.Init.StopBits = UART_STOPBITS_1;huart1.Init.Parity = UART_PARITY_NONE;huart1.Init.Mode = UART_MODE_TX_RX;huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart1.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart1) != HAL_OK){Error_Handler();}
}

那如何实现串口发送或接收数据呢?

stm32f1xx_hal_uart.h
HAL_UART_Transmit();                    串口轮询模式发送,使用超时管理机制。 
HAL_UART_Receive();                     串口轮询模式接收,使用超时管理机制。
HAL_UART_Transmit_IT();                 串口中断模式发送, 
HAL_UART_Receive_IT();                  串口中断模式接收
HAL_UART_Transmit_DMA();                串口DMA模式发送 
HAL_UART_Receive_DMA();                 串口DMA模式接收

HAL_UART_TxHalfCpltCallback();          发送过半,通过中断处理函数调用。
HAL_UART_TxCpltCallback();              发送完成后,通过中断处理函数调用。
HAL_UART_RxHalfCpltCallback();          接收过半,通过中断处理函数调用。
HAL_UART_RxCpltCallback();              接收完成后,通过中断处理函数调用。
HAL_UART_ErrorCallback();               传输过程中出现错误时,通过中断处理函数调用。

第一种是上面用到的轮询的模式。
CPU会不断查询串口是否传输完成,如传输超过则返回超时错误。轮询方式会占用CPU处理时间,效率较低,在实时性要求较高的产品中不宜使用。
第二种就是中断控制方式。
当I/O操作完成时,输入输出设备控制器通过中断请求线向处理器发出中断信号,处理器收到中断信号之后,转到中断处理程序,对数据传送工作进行相应的处理。
第三种就是直接内存存取技术(DMA)方式。
所谓直接传送,先发送到DMA,即在内存与IO设备间传送一个数据块的过程中,不需要CPU的任何中间干涉,只需要CPU在过程开始时向设备发出“传送块数据”的命令,然后通过中断来得知过程是否结束和下次操作是否准备就绪。
整个过程只产生两次中断,第一次是进入DMAx_Streamy_IRQHandler;第二次进入USARTx_IRQHandler。

 

有多种方式,我们先来了解第一种,阻塞轮询模式

HAL_UART_Transmit (UART_HandleTypeDef *huart, const uint8 t *pData, uint16 t Size, uint32 t Timeout)
这个函数是一个阻塞函数,即当调用此函数时,程序会一直等待数据发送完成或超时后才会继续执行后面的代码。
第一个参数是UART句柄,比如要使用USART1,参数就设置为USART1的句柄地址&huart1
第二个参数是需要发送的数据。
第三个参数是需要发送数据的大小。
第四个参数是发送超时时间,单位是毫秒,如果超过设置的时间,则函数返回HAL_TIMEOUT,如果设置为HAL_MAX_DELAY,处理器就会一直等到数据发送完成再执行下一条语句。


HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
第一个参数是要使用的串口句柄地址,比如要使用USART1,参数就设置为USART1的句柄地址&huart1
第二个参数是接受数据的缓冲区首地址
第三个参数是接受的数据长度,这里可以直接用sizeof()函数获取接受缓冲区的长度
第四个参数是超时时间,单位是ms,如果超过设置的时间,则函数返回HAL_TIMEOUT,如果设置为HAL_MAX_DELAY,处理器就会一直等到接收到设置好的数据数量再执行下一条语句。

现在,我们先实现发送功能,在main.c中添加发送代码

  while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */uint8_t txbuf[]="Hello,world!";HAL_UART_Transmit(&huart1,txbuf,sizeof(txbuf),1000);HAL_Delay(500);                                                       }/* USER CODE END 3 */
  1. 编译烧录至板卡,然后接好串口线连接到电脑。
  2. 打开串口调试助手,选择COM口,例如下方是COM5,根据自己电脑设备管理器的COM选择,插拔USB线,会显示新COM,如果提示COM口有叹号,则需要自行搜索CH340驱动安装。

串口调试助手软件:自行安装即可:参考飞书文档

  • 然后设置波特率115200 8 N 1,即可看到间隔500ms打印信息。

参考工程:

如果烧录完没打印,可以重启或复位下

  /* USER CODE BEGIN 2 */uint8_t rxbuf[12];/* USER CODE END 2 */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(HAL_UART_Receive(&huart1,rxbuf,sizeof(rxbuf),1000) == HAL_OK){HAL_UART_Transmit(&huart1,rxbuf,sizeof(rxbuf),1000);}}/* USER CODE END 3 */

编译烧录至板卡,然后接好串口线连接到电脑,打开串口调试助手,设置波特率115200 8 N 1,发送ASCII码“Hello world”,

为什么“Hello world”是11个字符,我们需要接收rxbuf[12]是12个字节呢?

因为串口助手工具,会自动加上换行符,点击右侧的发送后,我们可以看到TX是12个字节。

串口中断方式

我们可以看到,上方的方式都是阻塞式发送,轮询接收的,简单的产品这样设计没有问题,但是做一些复杂的,对实时性有要求的产品时,就满足不了了,所以我们可以用到串口中断的功能,在CUBEMX中使能中断。

阻塞方式就好比你要拿快递,就一遍遍都前台询问快递到没到,在这期间你不能干别的,
中断方式是你告诉前台快递到了给你打电话,在这期间你是可以腾出身子来干别的事情。

生成工程后,可以在stm32f1xx_it.c中看到生成了中断相关函数

/*** @brief This function handles USART1 global interrupt.*/
void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&huart1);
}void HAL_UART_IRQHandler(UART_HandleTypeDef *huart){xxxxUART_Receive_IT(huart);xxxx
}static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart){xxxxHAL_UART_RxCpltCallback(huart);xxxx
}
最终找到需要重写的虚函数
/*** @brief  Rx Transfer completed callbacks.* @param  huart  Pointer to a UART_HandleTypeDef structure that contains*                the configuration information for the specified UART module.* @retval None*/
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{/* Prevent unused argument(s) compilation warning */UNUSED(huart);/* NOTE: This function should not be modified, when the callback is needed,the HAL_UART_RxCpltCallback could be implemented in the user file*/
}

然后在

  main.c/* USER CODE BEGIN 0 */uint8_t rxbuf[10];uint8_t ackbuf[] = "ack pack";/* USER CODE END 0 *//* USER CODE BEGIN 2 */HAL_UART_Receive_IT(&huart1,rxbuf,sizeof(rxbuf));/* USER CODE END 2 *//* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){       if(huart == &huart1)   //判断中断是否来自于串口1{HAL_UART_Transmit_IT(&huart1,ackbuf,sizeof(ackbuf));  //通过中断的方式发送应答数据出去HAL_UART_Receive_IT(&huart1,rxbuf,sizeof(rxbuf));   //开始接收下一轮数据}
}

下载完成,点击复位。打开串口助手,连接到相应的端口,设置波特率为115200,从串口助手向单片机发送10个字节的数据,单片机将会把发过去的数据在返回给串口助手。必须发够10个字节以上的数据,才能够触发中断。

参考工程:

如果烧录完没打印,可以重启或复位下

串口中断+DMA方式

这时候,如果我们在开发产品过程中,需要频繁收发数据,且通信波特率较高时,如果采用中断方式,每收发一个字节的数据,CPU都会被打断,造成CPU无法处理其他事务。 因此在批量数据传输,通信波特率较高时,建议采用DMA方式

串口中断每收发一个字节数据,CPU都会被打断
 

CPU只需要设置开始传输和处理传输结束的中断
 

DMA,全称Direct Memory Access,即直接存储器访问。

DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。

我们知道CPU无时不刻的在处理着大量的事务,但有些事情却没有那么重要,比方说数据的复制和存储数据,如果我们把这部分的CPU资源拿出来,让CPU去处理其他的复杂计算事务,是不是能够更好的利用CPU的资源呢?

所以串口收发数据量大时可借助DMA,减轻CPU负担。即在内存与IO设备间传送一个数据块的过程中,不需要CPU的任何中间干涉,只需要CPU在过程开始时向设备发出“传送块数据”的命令,然后通过中断来得知过程是否结束和下次操作是否准备就绪。
整个过程只产生两次中断,第一次是进入DMAx_Streamy_IRQHandler;第二次进入USARTx_IRQHandler。

前文说过中断方式就好比你告诉前台,等快递到了给你打电话,让你亲自来取,假设你正在做着一些重要的事情,正好来了电话让你取快递,这样一来就会耽误事。
这怎么办呢?
雇个保姆不就好了吗,DMA就好比这个保姆,你告诉她在哪里取快递,她就会等快递到了之后自己帮你把快递拿回家。

STM32F103RC有12个独立的可配置的通道(请求):DMA1有7个通道,DMA2有5个通道

每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过 软件来配置。

这里,我们切换CUBEMX的USART1中,设置DMA,点击Add,把USART1_TX USART1_RX都添加进来。

注意,RX和TX下方的DMA Request Settings都需要设置为一样。

Channel:通道
例如USART1_RX会对应着上面表格的DMA1的通道5

Direction:方向
因为RX是接收接口,接收来自外设的数据,所以方向是Peripheral To Memory(外设到内存),TX相反

Priority: 优先级,当存在多个DMA传输时才需要根据具体业务设置,默认选择Low即可
最高优先级 Very Hight
高优先级 Hight
中等优先级 Medium
低优先级;Low

Mode:模式
Normal:正常模式
当一次DMA数据传输完后,停止DMA传送 ,下次传输则需要重新开启DMA传输
Circular: 循环模式
传输完成后又重新开始继续传输,不断循环永不停止
根据不同场景选择灵活不同模式:
例如:
正常模式:一次性传输固定长度的数据,例如发送一次性消息、接收固定长度的数据包等。
循环模式:需要连续不断地发送或接收数据的场景,如连续的传感器数据采集等。
通讯类场景,一般TX使用正常模式,RX使用正常/循环模式,如果TX使用循环模式,需要注意数据同步问题,处理不好会导致新旧数据一起发送,而采集数据,使用循环模式就可以大大降低CPU的压力。

Increment Address:地址递增器
左侧Peripheral表示外设地址寄存器
功能:设置传输数据的时候外设地址是不变还是递增。如果设置为递增,那么下一次传输的时候地址加Data Width个字节
右侧Memory表示内存地址寄存器
功能:设置传输数据时候内存地址是否递增。如果设置为递增,那么下一次传输的时候地址加Data Width个字节,
例如:
串口发送数据是将数据不断存进固定外设地址的发送数据寄存器,所以外设的地址是不递增。
而内存储器存储的是要发送或接收数据,地址指针要递增,保证数据依次被发出或不被覆盖保存。

Data Width 数据宽度
一般的串口都是8位,因此使用默认的DMA配置即可,也就是指针自增为Byte

这里有个需要注意的地方,就是函数调用顺序

MX_DMA_Init()函数需要在其他初始化前调用,特别是在这个串口初始化前,不然会发送使用DMA发送会发送失败,在如下图位置配置调用顺序,必须先配置时钟再配置外设,MX_DMA_Init()里面有DMA时钟初始化

设置完成上面步骤,生成工程后,我们会发现DMA初始化在USART1之前,如果不进行这步设置,可能会出现发送失败的情况哦。

  /* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();

然后,我们可以使用DMA方式实现串口发送

main.cwhile (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */uint8_t txbuf[]="Hello,world!";HAL_UART_Transmit_DMA(&huart1,txbuf,sizeof(txbuf));HAL_Delay(500);                                                       }/* USER CODE END 3 */

也可以使用DMA方式实现串口收发

如果需要实时处理串口的数据,则需要打开串口全局中断。

UART一旦开启DMA之后,DMA通道全局中断都是强制开启的,DMA传输完整数据后,会触发HAL_UART_RxCpltCallbackHAL_UART_TxCpltCallback中断产生。

  main.c/* USER CODE BEGIN 0 */uint8_t rxbuf[10];uint8_t ackbuf[] = "ack pack";/* USER CODE BEGIN 2 *///初始化DMA串口接收需要在串口初始化前?HAL_UART_Receive_DMA(&huart1,rxbuf,sizeof(rxbuf));/* USER CODE END 2 *//* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){       if(huart == &huart1)   //判断中断是否来自于串口1{HAL_UART_Transmit_DMA(&huart1,ackbuf,sizeof(ackbuf));  //通过中断的方式发送应答数据出去//如果接收使用循环模式,则不用重新开启HAL_UART_Receive_DMA(&huart1,rxbuf,sizeof(rxbuf));   //开始接收下一轮数据}
}

参考工程:参考飞书文档

使用USART+DMA接收中断不定长数据

可以使用STM32 IDLE空闲中断实现,IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断

main.c
/* USER CODE BEGIN 0 */
extern DMA_HandleTypeDef hdma_usart1_rx;
#define BUFFER_SIZE  100 
uint8_t rxbuf[BUFFER_SIZE];/* USER CODE BEGIN 2 */
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1,rxbuf,sizeof(rxbuf));/* USER CODE BEGIN 4 */
void UART_IDLEHandler(){if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) == SET) //如果串口处于空闲状态{__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_IDLE);//清空空闲状态标志HAL_UART_DMAStop(&huart1); //关闭DMA传输//计算接收到的数据长度 ,已接收长度=需要接收总长度-剩余待接收长度uint8_t rlen = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);//发送数据到上位机,当然,这里可以把数据复制到其它位置进行处理             HAL_UART_Transmit_DMA(&huart1,rxbuf,rlen);//重新打开DMA接收HAL_UART_Receive_DMA(&huart1,rxbuf,sizeof(rxbuf));               }
}main.h
/* USER CODE BEGIN EFP */
void UART_IDLEHandler(void);
/* USER CODE END EFP */stm32f1xx_it.c
/*** @brief This function handles USART1 global interrupt.*/
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 */UART_IDLEHandler();/* USER CODE END USART1_IRQn 1 */
}

参考工程:参考飞书文档

端口复用

当然,USART1是支持复用功能的,可以重映像到其它IO上,如果我们在进行硬件设计时,发现PA9、PA10走线不好走,或者需要作为其它用途,我们可以把USART1映射到PB6 PB7,如何知道是否支持重映像,可以查看手册8.3章节。


 

可以在右侧的芯片图中找到PB6,设置为USART1_TX,PB7,设置为USART1_RX

串口重定向

在单片机中使用printf打印

使用HAL_UART_Transmit发送字符串很不方便,可以重定向printf()函数使printf通过串口打印字符串

使用串口重定向,必须勾选MicroLIB
MicroLib 是一个高度优化的库,适用于用 C 编写的基于 ARM 的嵌入式应用程序。
与 ARM 编译器工具链中包含的标准 C 库相比,MicroLib 提供了许多嵌入式系统所需的显着代码大小优势。

main.c
/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes *//* USER CODE BEGIN 4 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);return ch;
}

相关文章:

单片机-STM32部分:10、串口UART

飞书文档https://x509p6c8to.feishu.cn/wiki/W7ZGwKJCeiGjqmkvTpJcjT2HnNf 串口说明 电平标准是数据1和数据0的表达方式&#xff0c;是传输线缆中人为规定的电压与数据的对应关系&#xff0c;串口常用的电平标准有如下三种&#xff1a; TTL电平&#xff1a;3.3V或5V表示1&am…...

STM32外设-串口UART

STM32外设-串口UART 一&#xff0c;串口简介二&#xff0c;串口基础概念1&#xff0c;什么是同步和异步/UART与USART对比2&#xff0c;串行与并行3&#xff0c;波特率 (Baud Rate)4&#xff0c;数据帧 (Data Frame)5&#xff0c;TX 和 RX 三&#xff0c;硬件连接1&#xff0c;u…...

《工业计算机硬件技术支持手册》适用于哪些人群?

《工业计算机硬件技术支持手册》于2024年出版&#xff0c;主要讲当前正在应用的最新计算硬件技术。包括计算机各种功能接口、扩展总线、各种国际通行的板型规格等等。书中引用的数据&#xff0c;全部来自国际行业技术规范&#xff0c;书中还融入了作者几十年的工作经验和操作技…...

element-ui时间线样式修改

element-ui时间线样式修改 前两天公司给了一个需求 要求如下图所示 需求是时间在步骤条左边,看了element-ui的文档 发现并没有参数可以设置时间在步骤条的左边 那没办法 只能自己想一想办法了 首先想到的是用样式直接改变 活不多说 直接搞 第一步 选中时间这个元素 发现了这个类…...

动态规划之背包问题:组合优化中的经典NP挑战

背包问题概念&#xff1a; 背包问题是一种经典的组合优化的NP问题&#xff0c;在计算机科学、运筹学等领域有着广泛的应用。 问题可以简单的描述为&#xff1a; 假设有一个容量为C的背包和n个物品&#xff0c;每个物品i都有重量w[i]和价值v[i]。目标是选择一些物品放入背包&…...

JavaScript 基础

JS概念 JS基础概念 JS是一种运行在客户端(浏览器)的编程语言, 实现人机交换结果 作用: 网页特效表单验证数据交互服务端编程(node.js) JS的组成 ECMAScript—javaScript语言基础Web APIs—(DOM: 页面文档对象模型)(BOM: 浏览器对象模型) JS书写 位置 内部: 写到< /body…...

Vibe Coding: 优点与缺点

如果你最近在开发圈子里,你很可能听说过这个新趋势"vibe coding"(氛围编程)。 我只能说我对此感受复杂。以下是原因。 优势 在构建新项目时,靠着氛围编程达到成功感觉很自由!但对于遗留代码来说情况就不同了,尽管也不是不可能。 实时反馈和快速迭代 Cursor(…...

小动物听力评价系统基本原理简析

小动物听力评价系统是用于评估小动物听力功能的专业设备&#xff0c;以下从系统组成、工作原理、评价方法等方面为你介绍&#xff1a; 一 系统组成 声音刺激模块&#xff1a;能产生不同频率、强度和类型的声音信号&#xff0c;如纯音、啭音、短声等&#xff0c;以刺激小动物的听…...

spark缓存-persist

存储级别指定 persist&#xff1a;可以通过传入 StorageLevel 参数来指定不同的持久化级别。常见的持久化级别有&#xff1a; MEMORY_ONLY&#xff1a;将 RDD 以 Java 对象的形式存储在 JVM 的内存中。若内存不足&#xff0c;部分分区将不会被缓存&#xff0c;需要时会重新计算…...

树初步 #1(插排串联 - 辽宁省2024CCPC)

树初步 数的基础内容可以看看树基础 - OI Wiki里面的讲解&#xff0c;对一些操作的基础概念介绍的很清楚&#xff1b; 下面直接来看例题&#xff1a; 插排串联 - 辽宁省CCPC 题目大意 给定一个n1个节点的有根数&#xff1b; 根节点&#xff08;0号&#xff09;是插座&…...

CDGP重点知识梳理(82个)

目 录 考点分布 考试要求 第一章 数据管理-5%...

shell脚本基础详细学习(更新中)

shell简单介绍 Shell不仅仅是充当用户与UNIX或者localhost交互的角色&#xff0c;还可以作为一种程序设计 语言来使用。通过Shell编程&#xff0c;可以实现许多非常实用的功能&#xff0c;提高系统管理的自动化水平。 如果有一系列经常需要使用的命令&#xff0c;把它存储在一…...

记录一下学习kafka的使用以及思路

下面这是kafka的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-kafka</artifactId></dependency> 我在学习的时候直接导入是没有导入成功的&#xff0c;我猜测大概的原因是我本…...

AT9880B北斗单模卫星定位SOC芯片

AT9880B是一款高性能北斗单模卫星导航接收机SOC单芯片&#xff0c;芯片集成射频前端和数字基带、北斗多频卫星信号处理引擎、电源管理功能。芯片支持接收中国北斗二号和北斗三号&#xff0c;支持接收B1I、B1C、B2I、B3I、B2a和 B2b等频点信号。 主要特性&#xff1a; 支持北斗…...

李沐《动手学深度学习》 | 多层感知机

文章目录 感知机模型《深度学习入门》的解释训练感知机损失函数的选择感知机的收敛定理&#xff1a;什么时候能够停下来&#xff0c;是不是真的可以停下来感知机的不足 多层感知模型案例引入隐藏层从线性到非线性单隐藏层-单分类案例多隐藏层 激活函数softmax函数溢出的问题 多…...

vue数据可视化开发常用库

一、常用数据可视化库 1. ECharts 特点&#xff1a;功能强大&#xff0c;支持多种图表类型&#xff0c;社区活跃。适用场景&#xff1a;复杂图表、大数据量、3D 可视化。安装&#xff1a;npm install echarts示例&#xff1a;<template><div ref"chart" c…...

CAN转ModbusTCP网关:破解电池生产线设备协议壁垒,实现全链路智能互联

在电池生产的现代工艺中&#xff0c;自动化和信息化水平的提高是提升产能、保障品质与安全的关键。CAN 协议作为一种广泛应用于汽车、工业控制等领域的串行通信协议&#xff0c;它以其高可靠性和强实时性而受到企业的青睐。而在众多工业通讯协议中&#xff0c;ModbusTCP作为一种…...

更新 / 安装 Nvidia Driver 驱动 - Ubuntu - 2

如果按更新 / 安装 Nvidia Driver 驱动 - Ubuntu-CSDN博客中的步骤操作后问题依旧&#xff0c;则查看过程中的提示信息。 如果发现有“Use sudo apt autoremove to remove them.”&#xff0c;则执行&#xff1a; #sudo apt autoremove #nvidia-smi...

技术分享 | 如何在2k0300(LoongArch架构)处理器上跑通qt开发流程

近期迅为售后团队反馈&#xff0c;许多用户咨询&#xff1a;2K0300处理器采用了LA264处理器核&#xff0c;若要在该处理器上运行Qt程序&#xff0c;由于架构发生了变化&#xff0c;其使用方法是否仍与ARM平台保持一致&#xff1f; 单纯回答‘一致’或‘不一致’缺乏说服力&…...

ubuntu 24.04 error: cannot uninstall blinker 1.7.0, record file not found. hint

最近在打python3.12的镜像&#xff0c;安装browser-gym的核心库&#xff0c;编译一个使用browswer agents的环境&#xff0c;然后出现了下面的问题&#xff1a; error: cannot uninstall blinker 1.7.0, record file not found. hint: the package was installed by debian.系…...

学习记录:DAY28

DispatcherController 功能完善与接口文档编写 前言 没什么动力说废话了。 今天来完善 DispatcherController 的功能&#xff0c;然后写写接口文档。 日程 早上&#xff1a;本来只有早八&#xff0c;但是早上摸鱼了&#xff0c;罪过罪过。下午&#xff1a;把 DispatcherContro…...

C# 的异步任务中, 如何暂停, 继续,停止任务

namespace taskTest {using System;using System.Threading;using System.Threading.Tasks;public class MyService{private Task? workTask;private readonly SemaphoreSlim semaphore new SemaphoreSlim(0, 1); // 初始为 0&#xff0c;Start() 启动时手动放行private read…...

html object标签介绍(用于嵌入外部资源通用标签)(已不推荐使用deprecated,建议使用img、video、audio标签)

文章目录 HTML <object> 标签详解基本语法与核心属性关键属性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同类型的资源1. **嵌入图像**2. **嵌入音频**3. **嵌入视频**4. **嵌入 PDF** 参数传递与回退内容**参数&#xff08;<param>&a…...

专题练习1

优化: 找101-200的质数: 开发验证码: 解密数字 抽奖 优化 彩票...

Uniapp编写微信小程序,使用canvas进行绘图

一、canvas文档&#xff1a; https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial 二、数据绘制&#xff08;单位是像素&#xff09;&#xff1a; 1、绘制文本&#xff1a; 文字的长度超过设置的最大宽度&#xff0c;文字会缩在一起 ① 填充文本&#xf…...

Java高频基础面试题

Java高频基础面试题 Java基础 Java的特点是什么&#xff1f; 面向对象平台无关性&#xff08;“一次编写&#xff0c;到处运行”&#xff09;支持多线程自动内存管理&#xff08;垃圾回收&#xff09;安全性丰富的类库 JDK、JRE和JVM的区别 JDK (Java Development Kit): Java…...

U9C-SQL-采购订单视图

U9C-SQL-采购订单视图 SELECTpo.ID,CONVERT ( VARCHAR ( 10 ), po.CreatedOn, 23 ) AS 签订日期,org.Name AS 甲方,po.DocNo AS 单号,item.Code AS 料号,item.Name AS 品名,item.SPECS AS 规格,item.DescFlexField_PrivateDescSeg1 AS 图号,item.DescFlexField_PrivateDescSeg2…...

HTML字符串转换为React元素实现

HTML字符串安全转换为React元素的实现 一、背景介绍 介绍HTML字符串在Web开发中的常见场景。说明React中直接使用HTML字符串的局限性。提出将HTML字符串转换为React元素的需求。 二、首先必备的两个npm库&#xff1a;html-react-parser和dompurify 导入&#xff1a; pnpm i…...

全局异常未能正确捕获到对应的异常

自定义Validation验证器遇到的问题 抛出的异常没有能被指定的TaskValidException.class方法拦截到。故写这个原因 全局异常拦截只能拦截相同的异常。只能通过解析转入自定义的异常。自定义的异常继承的异常要是一家子的。如TaskValidException和ValidationException。这样就能在…...

LeetCode 解题思路 47(最长回文子串、最长公共子序列)

解题思路&#xff1a; dp 数组的含义&#xff1a; dp[i][j] 是否为回文子串。递推公式&#xff1a; dp[i][j] s.charAt(i) s.charAt(j) && dp[i 1][j - 1]。dp 数组初始化&#xff1a; 单字符 dp[i][i] true&#xff0c;双字符 dp[i][i 1] s.charAt(i) s.charA…...

P11369 [Ynoi2024] 弥留之国的爱丽丝(操作分块,DAG可达性trick)

真的神仙题。感觉学到了很多。 题意&#xff1a; 给你一张 n n n 个结点 m m m 条边的有向图&#xff0c;点编号为 1 , 2 , … , n 1,2,\dots,n 1,2,…,n。每条边的颜色为黑色或白色。一开始所有 m m m 条边都是黑色的。 你需要进行 q q q 次操作&#xff0c;有两种操作…...

NAT穿越

概述 IPSec协商是通过IKE完成--->ISAKMP协议完成--->由UDP封装&#xff0c;源目端口均为500。 NAT--->NAPT&#xff0c;同时转换IP和端口信息。 对端设备会查验收到的数据报文中的源IP和源端口&#xff0c;其中源IP可以设定为NAT转换后的IP&#xff0c;但是源端口无法…...

不黑文化艺术学社首席艺术家孙溟㠭浅析“雪渔派”

孙溟㠭浅析“雪渔派” 何震 字主臣 &#xff0c;长卿&#xff0c;号雪渔&#xff0c;安徽婺源&#xff08;今江西&#xff09;人&#xff0c;是明代著名的篆刻家和书法家&#xff0c;与文彭独树一帜&#xff0c;实现书法与刀法的统一。 云中白鹤 笑谭间气吐霓虹 边款 其篆刻吸…...

【Linux操作系统】第一弹——Linux基础篇

文章目录 &#x1f4a1; 一. Linux的基本常识&#x1fa94; 1.1 linux网络连接三种方式&#x1fa94;1.2 虚拟机的克隆&#x1fa94;1.3 虚拟机的快照&#x1fa94;1.4 虚拟机的迁移和删除&#x1fa94;1.5 vmtools工具 &#x1f4a1;二. Linux的目录结构&#x1fa94;2.1 Linu…...

“ES7+ React/Redux/React-Native snippets“常用快捷前缀

请注意&#xff0c;这是一个常用的列表&#xff0c;不是扩展提供的所有前缀。最完整和最新的列表请参考扩展的官方文档或在 VS Code 中查看扩展的详情页面。 React (通常用于 .js, .jsx, .ts, .tsx): rfce: React Functional Component with Export Defaultrafce: React Arro…...

selenium替代----playwright

安装 好处特点&#xff1a;这个东西不像selenium需要固定版本的驱动 pip config set global.index-url https://mirrors.aliyun.com/pypi/simplepip install --upgrade pippip install playwright playwright installplaywright install ffmpeg (处理音视频的)验证&#x…...

2025年社交APP安全防御指南:抵御DDoS与CC攻击的实战策略

2025年&#xff0c;社交APP的用户规模与业务复杂度持续增长&#xff0c;但随之而来的DDoS与CC攻击也愈发隐蔽和智能化。攻击者通过AI伪造用户行为、劫持物联网设备&#xff0c;甚至利用区块链漏洞发起混合攻击&#xff0c;对平台稳定性与用户数据安全构成严峻挑战。本文将结合最…...

PHP会话技术

第十六章-PHP会话技术 PHP会话技术是构建动态、个性化Web应用的核心机制之一&#xff0c;它通过跟踪用户在网站上的连续操作状态&#xff0c;实现了网页间的数据持久化交互。无论是电商平台的购物车信息保存、社交媒体的用户登录状态维持&#xff0c;还是表单数据的跨页面传递…...

QT聊天项目DAY10

1.封装redis操作类 头文件 #ifndef REDISMANAGE_H #define REDISMANAGE_H#include "Singletion.h" #include "GlobalHead.h"class RedisManage : public Singletion<RedisManage> {friend class Singletion<RedisManage>; public:~RedisMana…...

5.0.5 变换(旋转、缩放、扭曲)

WPF变换可以产生特殊效果,如平移、旋转、扭曲。 变换类 描述TranslateTransform沿着X轴和Y轴平移ScaleTransform 沿着定义的中心点缩放RotateTransform沿着定义的中心点旋转SkewTransform 扭曲元素MatrixTransfrom提供3x3矩阵,用于定义一个自定义变换 1…...

matlab转python

1 matlab2python开源程序 https://blog.csdn.net/qq_43426078/article/details/123384265 2 网址 转换网址&#xff1a;https://app.codeconvert.ai/code-converter?inputLangMatlab&outputLangPython 文件比较网址&#xff1a;https://www.diffchecker.com/text-comp…...

什么是直播美颜SDK?跨平台安卓、iOS美颜SDK开发实战详解

时下&#xff0c;尤其在社交、娱乐、电商等应用场景中&#xff0c;一个流畅且效果自然的美颜功能往往能直接影响用户的留存率和平台的营收。要实现这些效果&#xff0c;美颜SDK是核心工具。那么&#xff0c;什么是直播美颜SDK&#xff1f;它的功能有哪些&#xff1f;如何进行跨…...

大尺寸PCB如何重塑通信与新能源产业格局

在5G通信基站与新能源电站的机房内&#xff0c;一块块面积超过600mm600mm的PCB板正悄然推动着技术革命。作为电子设备的核心载体&#xff0c;大尺寸PCB凭借其高密度集成与复杂工艺&#xff0c;成为通信、能源等领域的“隐形功臣”。以猎板PCB为代表的厂商&#xff0c;凭借宽幅曝…...

JavaSE核心知识点02面向对象编程02-04(包和导入)

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 JavaSE核心知识点02面向对象编程02-04&#…...

【漫话机器学习系列】249.Word2Vec自然语言训练模型

【自然语言处理】用 Word2Vec 将词语映射到向量空间详解 一、背景介绍 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;我们常常需要将文本信息转化为机器能够理解和处理的形式。传统的方法&#xff0c;如 one-hot编码&#xff0c;虽然简单&#xff0c;但存在严重…...

CSS transition过渡属性

transition 是 CSS 中用于创建平滑动画效果的属性&#xff0c;它允许元素在两个状态之间平滑过渡&#xff0c;而不是立即改变。通过定义过渡的属性、持续时间和速度曲线&#xff0c;你可以实现丰富的交互体验&#xff0c;如悬停效果、状态切换动画等。 核心作用 平滑过渡&…...

U9C对接飞书审批流完整过程

U9C虽然很强大&#xff0c;但是移动办公和审批流功能并不好用&#xff0c;为了弥补U9C这种不足&#xff0c;很多的企业在使用U9C的同时再开通钉钉、飞书、企业微信这种OA管理系统&#xff0c;两套系统并行使用&#xff0c;就需要考虑U9C和OA系统数据同步的问题&#xff0c;最简…...

阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化

作者&#xff1a;裘文成&#xff08;翊韬&#xff09; 摘要 随着企业全球化业务的扩展&#xff0c;如何高效、经济且可靠地将分布在海外各地的应用与基础设施日志统一采集至阿里云日志服务 (SLS) 进行分析与监控&#xff0c;已成为关键挑战。 本文聚焦于阿里云高性能日志采集…...

从0开始学习大模型--Day04--大模型的框架以及基本元素

Agent框架与策略分析 计划与执行&#xff08;planning-and-Execute&#xff09; 该框架侧重于先规划一系列的行动&#xff0c;然后执行。这个框架可以使大模型能够先综合考虑任务的多个方面&#xff0c;然后按照计划进行行动&#xff0c;比较适合应用在较复杂的项目管理中或者…...

FPGA实战项目2———多协议通信控制器

1. 多协议通信控制器模块 (multi_protocol_controller) 简要介绍 这是整个设计的顶层模块,承担着整合各个子模块的重要任务,是整个系统的核心枢纽。它负责协调 UART、SPI、I2C 等不同通信协议模块以及 DMA 模块的工作,同时处理不同时钟域之间的信号交互,确保各个模块能够…...