STM32G474xx HAL 用户手册
stm32g4xx_hal_uart.c
跳转到本文档。
00001 /**
00002   ******************************************************************************
00003   * @file    stm32g4xx_hal_uart.c
00004   * @author  MCD 应用团队
00005   * @brief   UART HAL 模块驱动程序。
00006   *          本文件提供固件函数,用于管理通用异步收发器(UART)外设的以下功能:
00007   *           + 初始化和反初始化函数
00008   *           + IO 操作函数
00009   *           + 外设控制函数
00010   *
00011   *
00012   ******************************************************************************
00013   * @attention
00014   *
00015   * 版权所有 (c) 2019 STMicroelectronics。
00016   * 保留所有权利。
00017   *
00018   * 本软件根据可在本软件组件根目录的 LICENSE 文件中找到的条款进行许可。
00019   * 如果没有随附的 LICENSE 文件,则按“原样”提供。
00020   *
00021   ******************************************************************************
00022   @verbatim
00023  ===============================================================================
00024                         ##### 如何使用本驱动程序 #####
00025  ===============================================================================
00026   [..]
00027      UART HAL 驱动程序使用方法如下:
00028 
00029      (#) 声明一个 UART_HandleTypeDef 句柄结构(例如 UART_HandleTypeDef huart)。
00030      (#) 通过实现 HAL_UART_MspInit() API 初始化 UART 低层资源:
00031          (++) 启用 USARTx 接口时钟。
00032          (++) UART 引脚配置:
00033              (+++) 启用 UART GPIO 的时钟。
00034              (+++) 将这些 UART 引脚配置为复用功能上拉。
00035          (++) 如果需要使用中断过程(HAL_UART_Transmit_IT() 和 HAL_UART_Receive_IT() API),则配置 NVIC:
00036              (+++) 配置 USARTx 中断优先级。
00037              (+++) 启用 NVIC USART IRQ 句柄。
00038          (++) UART 中断处理:
00039                -@@-  特定的 UART 中断(发送完成中断、RXNE 中断、RX/TX FIFO 相关中断和错误中断)
00040                  通过宏 __HAL_UART_ENABLE_IT() 和 __HAL_UART_DISABLE_IT() 在发送和接收过程中进行管理。
00041          (++) 如果需要使用 DMA 过程(HAL_UART_Transmit_DMA() 和 HAL_UART_Receive_DMA() API),则配置 DMA:
00042              (+++) 为 Tx/Rx 通道声明一个 DMA 句柄结构。
00043              (+++) 启用 DMAx 接口时钟。
00044              (+++) 使用所需的 Tx/Rx 参数配置声明的 DMA 句柄结构。
00045              (+++) 配置 DMA Tx/Rx 通道。
00046              (+++) 将初始化后的 DMA 句柄与 UART DMA Tx/Rx 句柄关联。
00047              (+++) 配置优先级并启用 NVIC,用于 DMA Tx/Rx 通道的传输完成中断。
00048 
00049      (#) 在 huart 句柄的 Init 结构中编程波特率、字长、停止位、奇偶校验、预分频器值、硬件流控制和模式(接收器/发送器)。
00050 
00051      (#) 如果需要,在 huart 句柄的 AdvancedInit 结构中编程 UART 高级功能(TX/RX 引脚交换、自动波特率检测等)。
00052 
00053      (#) 对于 UART 异步模式,通过调用 HAL_UART_Init() API 初始化 UART 寄存器。
00054 
00055      (#) 对于 UART 半双工模式,通过调用 HAL_HalfDuplex_Init() API 初始化 UART 寄存器。
00056 
00057      (#) 对于 UART LIN(本地互连网络)模式,通过调用 HAL_LIN_Init() API 初始化 UART 寄存器。
00058 
00059      (#) 对于 UART 多处理器模式,通过调用 HAL_MultiProcessor_Init() API 初始化 UART 寄存器。
00060 
00061      (#) 对于 UART RS485 驱动器使能模式,通过调用 HAL_RS485Ex_Init() API 初始化 UART 寄存器。
00062 
00063      [..]
00064      (@) 这些 API(HAL_UART_Init()、HAL_HalfDuplex_Init()、HAL_LIN_Init()、HAL_MultiProcessor_Init()、
00065          也通过调用定制的 HAL_UART_MspInit() API 来配置低层硬件 GPIO、时钟、CORTEX 等。
00066 
00067      ##### 回调注册 #####
00068      ==================================
00069 
00070      [..]
00071      编译定义 USE_HAL_UART_REGISTER_CALLBACKS 设置为 1 时,允许用户动态配置驱动程序回调。
00072 
00073      [..]
00074      使用函数 HAL_UART_RegisterCallback() 注册用户回调。
00075      函数 HAL_UART_RegisterCallback() 允许注册以下回调:
00076      (+) TxHalfCpltCallback        : 发送半完成回调。
00077      (+) TxCpltCallback            : 发送完成回调。
00078      (+) RxHalfCpltCallback        : 接收半完成回调。
00079      (+) RxCpltCallback            : 接收完成回调。
00080      (+) ErrorCallback             : 错误回调。
00081      (+) AbortCpltCallback         : 中止完成回调。
00082      (+) AbortTransmitCpltCallback : 中止发送完成回调。
00083      (+) AbortReceiveCpltCallback  : 中止接收完成回调。
00084      (+) WakeupCallback            : 唤醒回调。
00085      (+) RxFifoFullCallback        : 接收 FIFO 满回调。
00086      (+) TxFifoEmptyCallback       : 发送 FIFO 空回调。
00087      (+) MspInitCallback           : UART MspInit。
00088      (+) MspDeInitCallback         : UART MspDeInit。
00089      此函数接受 HAL 外设句柄、回调 ID 和指向用户回调函数的指针作为参数。
00090 
00091      [..]
00092      使用函数 HAL_UART_UnRegisterCallback() 将回调重置为默认弱函数。
00093      HAL_UART_UnRegisterCallback() 接受 HAL 外设句柄和回调 ID 作为参数。
00094      此函数允许重置以下回调:
00095      (+) TxHalfCpltCallback        : 发送半完成回调。
00096      (+) TxCpltCallback            : 发送完成回调。
00097      (+) RxHalfCpltCallback        : 接收半完成回调。
00098      (+) RxCpltCallback            : 接收完成回调。
00099      (+) ErrorCallback             : 错误回调。
00100      (+) AbortCpltCallback         : 中止完成回调。
00101      (+) AbortTransmitCpltCallback : 中止发送完成回调。
00102      (+) AbortReceiveCpltCallback  : 中止接收完成回调。
00103      (+) WakeupCallback            : 唤醒回调。
00104      (+) RxFifoFullCallback        : 接收 FIFO 满回调。
00105      (+) TxFifoEmptyCallback       : 发送 FIFO 空回调。
00106      (+) MspInitCallback           : UART MspInit。
00107      (+) MspDeInitCallback         : UART MspDeInit。
00108 
00109      [..]
00110      对于特定的回调 RxEventCallback,使用专用的注册/重置函数:
00111      分别为 HAL_UART_RegisterRxEventCallback()、HAL_UART_UnRegisterRxEventCallback()。
00112 
00113      [..]
00114      默认情况下,在 HAL_UART_Init() 之后且状态为 HAL_UART_STATE_RESET 时,
00115      所有回调都设置为相应的弱函数:
00116      例如 HAL_UART_TxCpltCallback()、HAL_UART_RxHalfCpltCallback()。
00117      对于 MspInit 和 MspDeInit 函数,当这些回调为空(未提前注册)时,
00118      它们分别在 HAL_UART_Init() 和 HAL_UART_DeInit() 中重置为旧的弱函数。
00119      否则,如果 MspInit 或 MspDeInit 不为空,则 HAL_UART_Init() 和 HAL_UART_DeInit()
00120      保留并使用用户 MspInit/MspDeInit 回调(提前注册的)。
00121 
00122      [..]
00123      回调只能在 HAL_UART_STATE_READY 状态下注册/注销。
00124      MspInit/MspDeInit 例外,可以在 HAL_UART_STATE_READY 或 HAL_UART_STATE_RESET 状态下注册/注销,
00125      因此注册的(用户)MspInit/DeInit 回调可以在 Init/DeInit 期间使用。
00126      在这种情况下,首先使用 HAL_UART_RegisterCallback() 注册 MspInit/MspDeInit 用户回调,
00127      然后再调用 HAL_UART_DeInit() 或 HAL_UART_Init() 函数。
00128 
00129      [..]
00130      当编译定义 USE_HAL_UART_REGISTER_CALLBACKS 设置为 0 或未定义时,
00131      回调注册功能不可用,并使用弱回调。
00132 
00133 
00134   @endverbatim
00135   ******************************************************************************
00136   */
00137 
00138 /* Includes ------------------------------------------------------------------*/
00139 #include "stm32g4xx_hal.h"
00140 
00141 /** @addtogroup STM32G4xx_HAL_Driver
00142   * @{
00143   */
00144 
00145 /** @defgroup UART UART
00146   * @brief HAL UART 模块驱动程序
00147   * @{
00148   */
00149 
00150 #ifdef HAL_UART_MODULE_ENABLED
00151 
00152 /* Private typedef -----------------------------------------------------------*/
00153 /* Private define ------------------------------------------------------------*/
00154 /** @defgroup UART_Private_Constants UART 私有常量
00155   * @{
00156   */
00157 #define USART_CR1_FIELDS  ((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | \
00158                                       USART_CR1_OVER8 | USART_CR1_FIFOEN)) /*!< 由 UART_SetConfig API 设置的 UART 或 USART CR1 参数字段 */
00159 
00160 #define USART_CR3_FIELDS  ((uint32_t)(USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT | USART_CR3_TXFTCFG | \
00161                                       USART_CR3_RXFTCFG)) /*!< 由 UART_SetConfig API 设置的 UART 或 USART CR3 参数字段 */
00162 
00163 #define LPUART_BRR_MIN  0x00000300U  /* LPUART BRR 最小允许值 */
00164 #define LPUART_BRR_MAX  0x000FFFFFU  /* LPUART BRR 最大允许值 */
00165 
00166 #define UART_BRR_MIN    0x10U        /* UART BRR 最小允许值 */
00167 #define UART_BRR_MAX    0x0000FFFFU  /* UART BRR 最大允许值 */
00168 /**
00169   * @}
00170   */
00171 
00172 /* Private macros ------------------------------------------------------------*/
00173 /* Private function prototypes -----------------------------------------------*/
00174 /** @addtogroup UART_Private_Functions
00175   * @{
00176   */
00177 static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
00178 static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
00179 static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00180 static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00181 static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
00182 static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
00183 static void UART_DMAError(DMA_HandleTypeDef *hdma);
00184 static void