初始化 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) { /* Check the UART handle allocation 检查UART句柄分配*/ if (huart == NULL) { return HAL_ERROR; } /* Check the parameters 检查参数*/ if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE) { /* The hardware flow control is available only for USART1, USART2, USART3 and USART6 硬件流控制仅适用于USART1, USART2, USART3和USART*/ assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance)); assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl)); } else { assert_param(IS_UART_INSTANCE(huart->Instance)); } assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength)); assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling)); if (huart->gState == HAL_UART_STATE_RESET) { /* Allocate lock resource and initialize it 分配锁资源并初始化 */ huart->Lock = HAL_UNLOCKED; #if (USE_HAL_UART_REGISTER_CALLBACKS == 1) UART_InitCallbacksToDefault(huart); if (huart->MspInitCallback == NULL) { huart->MspInitCallback = HAL_UART_MspInit; } /* Init the low level hardware */ huart->MspInitCallback(huart); #else /* Init the low level hardware : GPIO, CLOCK 初始化底层硬件:GPIO, CLOCK 注意:此时会调用HAL_UART_MspInit*/ HAL_UART_MspInit(huart); #endif /* (USE_HAL_UART_REGISTER_CALLBACKS) (使用hart寄存器回调)*/ } huart->gState = HAL_UART_STATE_BUSY; /* Disable the peripheral 禁用外设*/ __HAL_UART_DISABLE(huart); /* Set the UART Communication parameters 设置UART通信参数*/ UART_SetConfig(huart); /* In asynchronous mode, the following bits must be kept cleared: - LINEN and CLKEN bits in the USART_CR2 register, - SCEN, HDSEL and IREN bits in the USART_CR3 register.*/ CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN)); CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN)); /* Enable the peripheral 启用外设*/ __HAL_UART_ENABLE(huart); /* Initialize the UART state 初始化UART状态*/ huart->ErrorCode = HAL_UART_ERROR_NONE; huart->gState = HAL_UART_STATE_READY; huart->RxState = HAL_UART_STATE_READY; return HAL_OK; }
HAL_UART_MspInit(huart); 会自动调用
__weak void HAL_UART_MspInit(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_MspInit could be implemented in the user file 这个函数不应该被修改,当需要回调时,HAL_UART_MspInit可以在用户文件中实现 */ }
接收 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
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 检查Rx进程是否准备 */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U)) //接收为空,或者容量为0
{
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用于超时管理 */
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)
{
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 在Rx进程结束时,将hart ->RxState恢复为Ready*/
huart->RxState = HAL_UART_STATE_READY;
/* Process Unlocked 过程解锁*/
__HAL_UNLOCK(huart);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
四个返回值
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
注 huart->RxXferSize = Size; RxXferSize 记录需要接收的数据量
huart->RxXferCount = Size; RxXferCount 剩余需要接收的数据量
发送 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
接收中断 HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
{
if (husart->State == HAL_USART_STATE_READY)
{
if ((pRxData == NULL) || (Size == 0))
{
return HAL_ERROR;
}
/* Process Locked 进程被锁 */
__HAL_LOCK(husart);
husart->pRxBuffPtr = pRxData;
husart->RxXferSize = Size;
husart->RxXferCount = Size;
husart->ErrorCode = HAL_USART_ERROR_NONE;
husart->State = HAL_USART_STATE_BUSY_RX;
/* Process Unlocked */
__HAL_UNLOCK(husart);
//中断开启
/* Enable the USART Parity Error and Data Register not empty Interrupts 启用USART奇偶校验错误和数据寄存器不空中断 */
SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
/* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) 使能USART错误中断:(帧错误、噪声错误、溢出错误)*/
SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
/* Send dummy byte in order to generate the clock for the slave to send data 发送虚拟字节,以便为从机发送数据生成时钟*/
husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
注意: HAL_UART_Transmit 会自动开启中断
中断处理 void HAL_UART_IRQHandler(UART_HandleTypeDef *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 ------------------------------------------------- UART in mode接收方*/
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
{
UART_Receive_IT(huart);//进入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) && ((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 aborted
Set 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 stream */
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 */
/* 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;
}
}
正常则进入 UART_Receive_IT(huart);//进入UART_Receive_IT(huart)函数,然后关闭中断使能,最终进入/*Call legacy weak Rx complete callback*/
HAL_UART_RxCpltCallback(huart);
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
{
uint16_t *tmp;
/* Check that a Rx process is ongoing 检查Rx进程是否正在进行*/
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 禁用UART数据寄存器不空中断*/
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
/* Disable the UART Parity Error Interrupt 禁用UART奇偶校验错误中断*/
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) 禁用UART错误中断:(帧错误、噪声错误、溢出错误) */
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
/* Rx process is completed, restore huart->RxState to Ready Rx进程完成,将“hart ->RxState”恢复为“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);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
return HAL_OK;
}
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}