HAL_UART_IRQHandler(UART_HandleTypeDef *huart)分析

2024-06-04 19:20

本文主要是介绍HAL_UART_IRQHandler(UART_HandleTypeDef *huart)分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

//接收没错误:执行UART_Receive_IT(huart)
//接收有错误:执行UART_Receive_IT(huart)、HAL_UART_ErrorCallback(huart)

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{uint32_t isrflags   = READ_REG(huart->Instance->SR);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));if (errorflags == RESET){/* UART in mode Receiver -------------------------------------------------*/if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)){UART_Receive_IT(huart);		//#1 接收没错误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) && ((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);	//#2 接收有错误}/* 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)){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);		//#3 接收有错误
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */huart->ErrorCode = HAL_UART_ERROR_NONE;}}return;} /* End if some error occurs *//* 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;}
}

//#1 接收没错误、#2 接收有错误,接收数据量达到设定值会自动关闭接收中断
//HAL_UART_Receive_IT(&huart1,Tx_Buff,1); //设定接收量为1

static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{uint16_t *tmp;/* Check that a Rx process is ongoing */if (huart->RxState == HAL_UART_STATE_BUSY_RX){if (huart->Init.WordLength == UART_WORDLENGTH_9B){tmp = (uint16_t *) huart->pRxBuffPtr;if (huart->Init.Parity == UART_PARITY_NONE){*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);huart->pRxBuffPtr += 2U;}else{*tmp = (uint16_t)(huart->Instance->DR & (uint16_t)0x00FF);huart->pRxBuffPtr += 1U;}}else{if (huart->Init.Parity == UART_PARITY_NONE){*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);}else{*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);}}if (--huart->RxXferCount == 0U){/* 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;#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);			//#4 接收回调
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */return HAL_OK;}return HAL_OK;}else{return HAL_BUSY;}
}

//#3 接收有错误回调

__weak void HAL_UART_ErrorCallback(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_ErrorCallback could be implemented in the user file*/
}

//#4 接收回调

__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*/
}

这篇关于HAL_UART_IRQHandler(UART_HandleTypeDef *huart)分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1030890

相关文章

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

Nginx内置变量应用场景分析

《Nginx内置变量应用场景分析》Nginx内置变量速查表,涵盖请求URI、客户端信息、服务器信息、文件路径、响应与性能等类别,这篇文章给大家介绍Nginx内置变量应用场景分析,感兴趣的朋友跟随小编一... 目录1. Nginx 内置变量速查表2. 核心变量详解与应用场景3. 实际应用举例4. 注意事项Ng

Java多种文件复制方式以及效率对比分析

《Java多种文件复制方式以及效率对比分析》本文总结了Java复制文件的多种方式,包括传统的字节流、字符流、NIO系列、第三方包中的FileUtils等,并提供了不同方式的效率比较,同时,还介绍了遍历... 目录1 背景2 概述3 遍历3.1listFiles()3.2list()3.3org.codeha

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe