HAL库USART中断接收的相关问题
文章目录
- 一、使用中断的步骤
- 二、相关函数分析
- 1、HAL_UART_IRQHandler
- 2、UART_Receive_IT
- 3、HAL_UART_Receive_IT
- 4、UART_Start_Receive_IT
- 5、总结
- 三、HAL库使用心得
一、使用中断的步骤
1、配置GPIO
2、配置USART1
3、设置UART1中断优先级(不开启手动中断,中断由HAL库给好的函数开启)
4、设置USART1中断服务函数(调用HAL给好的中断服务函数)
5、设置回调函数(HAL定义了一个弱函数,需要用户自己重定义)
6、开启USART1接收中断
二、相关函数分析
1、HAL_UART_IRQHandler
在中断服务函数USART1_IRQHandler中调用,进行USART中断的处理。
void USART1_IRQHandler(void)
{HAL_UART_IRQHandler(&huart1);
}
查看函数源码
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{uint32_t isrflags = READ_REG(huart->Instance->SR); //#define READ_REG(REG) ((REG))uint32_t cr1its = READ_REG(huart->Instance->CR1);uint32_t cr3its = READ_REG(huart->Instance->CR3);uint32_t errorflags = 0x00U;uint32_t dmarequest = 0x00U;/* If no error occurs */errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));//USART_SR_PE 32位,PE位为1,其余为0,是一个掩码 #define USART_SR_PE USART_SR_PE_Msk // isrflags 时SR的值,与这几位的掩码与,若这些位无置位则结果位0.表示错误位都没有置为,无错误发生if (errorflags == RESET)// == 0 无错误{/* UART in mode Receiver -------------------------------------------------*/if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){//接收数据寄存器非空 且 接收中断使能UART_Receive_IT(huart);//中断接收函数return;}}
//错误发生时/* If some errors occur */if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET)|| ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET))){/* UART parity error interrupt occurred ----------------------------------*/if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)){huart->ErrorCode |= HAL_UART_ERROR_PE;}/* UART noise error interrupt occurred -----------------------------------*/if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)){huart->ErrorCode |= HAL_UART_ERROR_NE;}/* UART frame error interrupt occurred -----------------------------------*/if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)){huart->ErrorCode |= HAL_UART_ERROR_FE;}/* UART Over-Run interrupt occurred --------------------------------------*/if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET)|| ((cr3its & USART_CR3_EIE) != RESET))){huart->ErrorCode |= HAL_UART_ERROR_ORE;}/* Call UART Error Call back function if need be --------------------------*/if (huart->ErrorCode != HAL_UART_ERROR_NONE){/* UART in mode Receiver -----------------------------------------------*/if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){UART_Receive_IT(huart);}/* If Overrun error occurs, or if any error occurs in DMA mode reception,consider error as blocking */dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest){/* Blocking error : transfer is abortedSet the UART state ready to be able to start again the process,Disable Rx Interrupts, and disable Rx DMA request, if ongoing */UART_EndRxTransfer(huart);/* Disable the UART DMA Rx request if enabled */if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)){ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);/* Abort the UART DMA Rx channel */if (huart->hdmarx != NULL){/* Set the UART DMA Abort callback :will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK){/* Call Directly XferAbortCallback function in case of error */huart->hdmarx->XferAbortCallback(huart->hdmarx);}}else{/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered error callback*/huart->ErrorCallback(huart);
#else/*Call legacy weak error callback*/HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}}else{/* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered error callback*/huart->ErrorCallback(huart);
#else/*Call legacy weak error callback*/HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}}else{/* Non Blocking error : transfer could go on.Error is notified to user through user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered error callback*/huart->ErrorCallback(huart);
#else/*Call legacy weak error callback*/HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */huart->ErrorCode = HAL_UART_ERROR_NONE;}}return;} /* End if some error occurs *//* Check current reception Mode :If Reception till IDLE event has been selected : */if ((huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE)&& ((isrflags & USART_SR_IDLE) != 0U)&& ((cr1its & USART_SR_IDLE) != 0U)){__HAL_UART_CLEAR_IDLEFLAG(huart);/* Check if DMA mode is enabled in UART */if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)){/* DMA mode enabled *//* Check received length : If all expected data are received, do nothing,(DMA cplt callback will be called).Otherwise, if at least one data has already been received, IDLE event is to be notified to user */uint16_t nb_remaining_rx_data = (uint16_t) __HAL_DMA_GET_COUNTER(huart->hdmarx);if ((nb_remaining_rx_data > 0U)&& (nb_remaining_rx_data < huart->RxXferSize)){/* Reception is not complete */huart->RxXferCount = nb_remaining_rx_data;/* In Normal mode, end DMA xfer and HAL UART Rx process*/if (huart->hdmarx->Init.Mode != DMA_CIRCULAR){/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);/* Disable the DMA transfer for the receiver request by resetting the DMAR bitin the UART CR3 register */ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);/* At end of Rx process, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Last bytes received, so no need as the abort is immediate */(void)HAL_DMA_Abort(huart->hdmarx);}/* Initialize type of RxEvent that correspond to RxEvent callback execution;In this case, Rx Event type is Idle Event */huart->RxEventType = HAL_UART_RXEVENT_IDLE;#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx Event callback*/huart->RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#else/*Call legacy weak Rx Event callback*/HAL_UARTEx_RxEventCallback(huart, (huart->RxXferSize - huart->RxXferCount));
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}return;}else{/* DMA mode not enabled *//* Check received length : If all expected data are received, do nothing.Otherwise, if at least one data has already been received, IDLE event is to be notified to user */uint16_t nb_rx_data = huart->RxXferSize - huart->RxXferCount;if ((huart->RxXferCount > 0U)&& (nb_rx_data > 0U)){/* Disable the UART Parity Error Interrupt and RXNE interrupts */ATOMIC_CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ATOMIC_CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);/* Rx process is completed, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Initialize type of RxEvent that correspond to RxEvent callback execution;In this case, Rx Event type is Idle Event */huart->RxEventType = HAL_UART_RXEVENT_IDLE;#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx complete callback*/huart->RxEventCallback(huart, nb_rx_data);
#else/*Call legacy weak Rx Event callback*/HAL_UARTEx_RxEventCallback(huart, nb_rx_data);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}return;}}/* UART in mode Transmitter ------------------------------------------------*/if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)){UART_Transmit_IT(huart);return;}/* UART in mode Transmitter end --------------------------------------------*/if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)){UART_EndTransmit_IT(huart);return;}
}
2、UART_Receive_IT
中断接收函数,被HAL_UART_IRQHandler 调用
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{uint8_t *pdata8bits;uint16_t *pdata16bits;/* Check that a Rx process is ongoing */if (huart->RxState == HAL_UART_STATE_BUSY_RX)//判断接收过程是否任然在进行{if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)){//设置为9位数据而且无校验时的处理pdata8bits = NULL;pdata16bits = (uint16_t *) huart->pRxBuffPtr;*pdata16bits = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);huart->pRxBuffPtr += 2U;}else{pdata8bits = (uint8_t *) huart->pRxBuffPtr;//pdata16bits = NULL;if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE))){//设置为8位数据时无校验或9位数据位时的处理*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);//从数据寄存器接收8位数据}else{*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);//从数据寄存器接收7位数据}huart->pRxBuffPtr += 1U;//buff指针加一}if (--huart->RxXferCount == 0U)//此时已经接收了最后一位数据 huart->RxXferCount = 1;{//关闭所有中断,设置usart1 的句柄的各个标志位/* Disable the UART Data Register not empty Interrupt */__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);/* Disable the UART Parity Error Interrupt */__HAL_UART_DISABLE_IT(huart, UART_IT_PE);/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);/* Rx process is completed, restore huart->RxState to Ready */huart->RxState = HAL_UART_STATE_READY;/* Initialize type of RxEvent to Transfer Complete */huart->RxEventType = HAL_UART_RXEVENT_TC;/* Check current reception Mode :If Reception till IDLE event has been selected : */if (huart->ReceptionType == HAL_UART_RECEPTION_TOIDLE){//开启了空闲中断,关闭空闲中断/* Set reception type to Standard */huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;/* Disable IDLE interrupt */ATOMIC_CLEAR_BIT(huart->Instance->CR1, USART_CR1_IDLEIE);/* Check if IDLE flag is set */if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE)){/* Clear IDLE flag in ISR */__HAL_UART_CLEAR_IDLEFLAG(huart);}
//接收完成,且开启了空闲中断时调用此函数
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx Event callback*/huart->RxEventCallback(huart, huart->RxXferSize);
#else/*Call legacy weak Rx Event callback*/HAL_UARTEx_RxEventCallback(huart, huart->RxXferSize);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}else{/* Standard reception API called *///接收完成,没有开启空闲中断时选择处理的回调函数
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)/*Call registered Rx complete callback*/huart->RxCpltCallback(huart);
#else/*Call legacy weak Rx complete callback*/HAL_UART_RxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */}return HAL_OK;}return HAL_OK;}else{return HAL_BUSY;}
}
3、HAL_UART_Receive_IT
判断USART句柄的接收状态,调用UART_Start_Receive_IT 开启中断。
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{/* Check that a Rx process is not already ongoing */if (huart->RxState == HAL_UART_STATE_READY)//判断usart状态{if ((pData == NULL) || (Size == 0U))//判断参数是否有效{return HAL_ERROR;}/* Set Reception type to Standard reception */huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;//设置接收状态return (UART_Start_Receive_IT(huart, pData, Size));//调用接收中断开启函数}else{return HAL_BUSY;}
}
4、UART_Start_Receive_IT
HAL_StatusTypeDef UART_Start_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{huart->pRxBuffPtr = pData;//缓冲区指针初始化huart->RxXferSize = Size;//缓冲区大小初始化huart->RxXferCount = Size;//接收数据总大小初始化 会在接收时减小huart->ErrorCode = HAL_UART_ERROR_NONE;//错误码设置huart->RxState = HAL_UART_STATE_BUSY_RX;//接收状态设置if (huart->Init.Parity != UART_PARITY_NONE){/* Enable the UART Parity Error Interrupt */__HAL_UART_ENABLE_IT(huart, UART_IT_PE);}//开启错误中断和接收中断/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);/* Enable the UART Data Register not empty Interrupt */__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);return HAL_OK;
}
5、总结
在使用标准库时需要我们先初始化GPIO再初始化USART,然后设置中断优先级并开启中断。在HAL库中,只需要我们初始化GPIO和USART并设置中断优先级,中断的开启和数据的接收都在HAL中封装好了函数,并使用回调函数的方式在接收完成后对数据进行处理。需要注意的是,USART的中断在HAL_UART_Receive_IT中调用UART_Start_Receive_IT开启相关中断,在ISR函数中只需调用HAL_UART_IRQHander函数。每次接收完成后相关的中断都会关闭,需要再次调用HAL_UART_Receive_IT函数开启中断,这也是刚开始用HAL库时常常疑惑的地方,为什么要在初始化时调用一次HAL_UART_Receive_IT函数,在接收完成后的处理函数中要调用HAL_UART_Receive_IT?
当然我们也可以自己调用相关的宏开启中断在ISR中写自己的处理函数,但是这样就不能够调用HAL库提供的函数接收数据了,因为在HAL库中,将外设抽象为句柄,在其中有许多的标志位,我们一旦自己自己调用中断操作后面又使用HAL库的API就会因为外设句柄中的标志位与实际不符而返回错误状态,导致程序卡死。
三、HAL库使用心得
相关文章:
HAL库USART中断接收的相关问题
文章目录 一、使用中断的步骤二、相关函数分析1、HAL_UART_IRQHandler2、UART_Receive_IT3、HAL_UART_Receive_IT4、UART_Start_Receive_IT5、总结 三、HAL库使用心得 一、使用中断的步骤 1、配置GPIO 2、配置USART1 3、设置UART1中断优先级(不开启手动中断&#x…...
@Transational事务注解底层原理以及什么场景事务会失效
Transactional的底层是如何实现的 底层是通过动态代理实现的。Spring Boot 在运行时会生成一个代理对象,该代理对象被注解的方法调用,并在方法调用前后进行事务管理,事务管理包括开启事务,提交事务或回滚事务等操作。 1开启事务 …...

Linux扩容磁盘
启动 fdisk sudo fdisk /dev/sda输入p命令查询分区列表 输入d命令删除所有分区 需要一个一个删 输入n命令创建新分区 40G可以不用输入,直接回车使用默认 输入w命令保存操作 查看分区情况 sudo fdisk -l会发现sda1不是启动分区(Boot列不是号&a…...
全面解析鸿蒙(HarmonyOS)开发:从入门到实战,构建万物互联新时代
文章目录 引言 一、鸿蒙操作系统概述二、鸿蒙开发环境搭建三、鸿蒙核心开发技术1. **ArkUI框架**2. **分布式能力开发**3. **原子化服务与元服务** 四、实战案例:构建分布式音乐播放器五、鸿蒙开发工具与调试技巧六、鸿蒙生态与未来展望结语 引言 随着万物互联时代…...

Uniapp 原生组件层级过高问题及解决方案
文章目录 一、引言🏅二、问题描述📌三、问题原因❓四、解决方案💯4.1 使用 cover-view 和 cover-image4.2 使用 subNVue 子窗体4.3 动态隐藏原生组件4.4 使用 v-if 或 v-show 控制组件显示4.5 使用 position: fixed 布局 五、总结Ἰ…...
Android adb测试常用命令大全
目录 一、查看最上层成activity名字: 二、查看Activity的任务栈: 三、获取安装包信息 四、性能相关 1、显示CPU信息 : 2、查看CPU使用信息 3、内存信息(meminfo package_name or pid 使用程序的包名或者进程id显示内存信息) 4、电量信…...

linux的基础入门2
linux的root用户 无论是Windows、MacOS、Linux均采用多用户的管理模式进行权限管理。 在Linux系统中,拥有最大权限的账户名为:root(超级管理员) 而在前期,我们一直使用的账户是普通的用户 普通用户的权限,一般在其HOME目录内是不受限的 一旦出了HOME目录…...

19.4.8 数据库综合运用
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 需要北风数据库的请留言自己的信箱。 本节中将通过实例综合展示对数据表的查询、增加、修改和删除。 【例 19.16】【项目…...
JAVA中的抽象学习
一、Java SE 中的抽象概念 在 Java 中,抽象(Abstraction)是面向对象编程的重要特性之一。抽象的核心思想是“只关注重要的特性,而忽略不重要的细节”。抽象通常通过抽象类和接口来实现,它帮助开发者将复杂的系统隐藏在…...
在 Go 中实现事件溯源:构建高效且可扩展的系统
事件溯源(Event Sourcing)是一种强大的架构模式,它通过记录系统状态的变化(事件)来重建系统的历史状态。这种模式特别适合需要高可扩展性、可追溯性和解耦的系统。在 Go 语言中,事件溯源可以通过一些简单的…...
加解密 | AES加、解密学习
加解密 | AES加、解密学习 你的代码实现了一个简单的AES(高级加密标准)加密和解密的测试程序。以下是对代码的分析和一些改进建议: 代码功能 初始化数据和密钥: 定义了一个16字节的输入数据 input_data。定义了一个16字节的AES…...

【学术投稿-2025年计算机视觉研究进展与应用国际学术会议 (ACVRA 2025)】CSS样式解析:行内、内部与外部样式的区别与优先级分析
简介 2025年计算机视觉研究进展与应用(ACVRA 2025)将于2025年2月28-3月2日在中国广州召开,会议将汇聚世界各地的顶尖学者、研究人员和行业专家,聚焦计算机视觉领域的最新研究动态与应用成就。本次会议将探讨前沿技术,…...
MongoDB 基本操作
一、数据库操作 1. 切换或创建数据库 使用use命令切换到指定数据库,若该数据库不存在,在首次插入数据时会自动创建。 use myDatabase 2. 查看所有数据库 使用show dbs命令查看 MongoDB 实例中的所有数据库。 show dbs 3. 删除当前数据库 使用db.…...
Eclipse JSP/Servlet 深入解析
Eclipse JSP/Servlet 深入解析 引言 随着互联网的快速发展,Java Web开发技术逐渐成为企业级应用开发的主流。在Java Web开发中,JSP(JavaServer Pages)和Servlet是两个核心组件,它们共同构成了Java Web应用程序的基础。本文将深入解析Eclipse平台下的JSP/Servlet技术,帮…...

Hyperledger caliper 性能测试
前言:Hyperledger caliper 的本质是使用node对被测试网络进行压力测试,因此需要nodejs。本次使用 Hyperledger caliper 0.5 对 fabric 1.4.6进行压测 准备条件:nodejs 16 (略 linux下 解压环境变量即可) # 创建工作…...

Record-Mode 备案免关站插件,让 WordPress 备案不影响 SEO 和收录
专为 WordPress 网站设计的实用工具,旨在帮助网站在备案期间无需关闭即可正常收录所有页面的信息,利于SEO。 功能特性 免关站展示:开启插件后,非管理员用户访问网站时,会看到以半透明遮罩层或不透明全屏遮罩样式呈现的…...

【Java 面试 八股文】Redis篇
Redis 1. 什么是缓存穿透?怎么解决?2. 你能介绍一下布隆过滤器吗?3. 什么是缓存击穿?怎么解决?4. 什么是缓存雪崩?怎么解决?5. redis做为缓存,mysql的数据如何与redis进行同步呢&…...

介绍几款免费的显示器辅助工具!
今天为大家介绍几款实用的显示器辅助软件,它们可以帮助你轻松切换显示源调节、显示器亮度,甚至优化显示效果,让你的屏幕使用体验更加便捷和舒适。 Monitor Brightness Adjuster-多屏幕亮度调节工具 如果你需要同时使用多个显示器࿰…...

django配置跨域
1、第一种 from django.views.decorators.csrf import csrf_exemptcsrf_exempt第二种 安装 pip install django-cors-headers在配置文件settings.py进入 INSTALLED_APPS [..."corsheaders", # 添加 ]MIDDLEWARE [corsheaders.middleware.CorsMiddleware, # 添加…...

web前端第三次作业
题目 本期作业 WEB第三次作业 请使用JS实一个网页中登录窗口的显示/隐藏,页面中拖动移动,并且添加了边界判断的网页效 代码图片 效果展示 代码 <!DOCTYPE html> <html lang"zh"> <head> <meta charset"UTF-8&qu…...

Cell-o1:强化学习训练LLM解决单细胞推理问题
细胞类型注释是分析scRNA-seq数据异质性的关键任务。尽管最近的基础模型实现了这一过程的自动化,但它们通常独立注释细胞,未考虑批次水平的细胞背景或提供解释性推理。相比之下,人类专家常基于领域知识为不同细胞簇注释不同的细胞类型。为模拟…...

QUIC——UDP实现可靠性传输
首先我们要知道TCP存在什么样的痛点问题 TCP的升级很困难TCP建立连接的延迟网络迁移需要重新建立连接TCP存在队头阻塞问题 QUIC就是为了解决以上的问题而诞生了, 下面我会介绍QUIC的一些特性和原理 QUIC对比TCP优势: 握手建连更快 QUIC内部包含了TLS, 它在自己的帧会携带TL…...
Python 函数全攻略:函数基础
函数(Functions)基础 什么是函数? 一个命名的代码块,代指一大堆代码。 定义: def function_name(): (使用def关键字,英文括号,冒号,缩进代码块)。 执行/调用: function…...
若依添加添加监听容器配置(删除键,键过期)
1、配置Redis的键触发事件 # 基础配置 bind 0.0.0.0 # 允许所有IP连接 protected-mode no # 关闭保护模式(生产环境建议结合密码使用) port 6379 # 默认端口 daemonize no …...

多模态大语言模型arxiv论文略读(109)
Math-PUMA: Progressive Upward Multimodal Alignment to Enhance Mathematical Reasoning ➡️ 论文标题:Math-PUMA: Progressive Upward Multimodal Alignment to Enhance Mathematical Reasoning ➡️ 论文作者:Wenwen Zhuang, Xin Huang, Xiantao Z…...

实战二:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
使用Python和Scikit-Learn实现机器学习模型调优
在机器学习项目中,模型的性能往往取决于多个因素,其中模型的超参数(hyperparameters)起着关键作用。超参数是模型在训练之前需要设置的参数,例如决策树的深度、KNN的邻居数等。合理地选择超参数可以显著提升模型的性能…...

【vue】Uniapp 打包Android 文件选择上传问题详解~
需求 uniapp兼容android app,pc,h5的文件选择并上传功能。 需要支持拍照和相册选择,以及选择其他类型文件上传~ 实践过程和问题 开始使用uni-file-picker组件 以为很顺利,android模拟器测试…… 忽略了平台兼容性提示~&#…...

变幻莫测:CoreData 中 Transformable 类型面面俱到(一)
概述 各位似秃似不秃小码农们都知道,在苹果众多开发平台中 CoreData 无疑是那个最简洁、拥有“官方认证”且最具兼容性的数据库框架。使用它可以让我们非常方便的搭建出 App 所需要的持久存储体系。 不过,大家是否知道在 CoreData 中还存在一个 Transfo…...

鸿蒙仓颉语言开发实战教程:购物车页面
大家上午好,仓颉语言商城应用的开发进程已经过半,不知道大家通过这一系列的教程对仓颉开发是否有了进一步的了解。今天要分享的购物车页面: 看到这个页面,我们首先要对它简单的分析一下。这个页面一共分为三部分,分别是…...