STM32 USART 函数列表和一些类型定义

本文最后更新于:2021年1月6日 下午

本篇文章是一篇介绍 STM32 USART 相关函数的笔记,下次忘记的时候可以方便查找。

串口寄存器列表

  1. 状态寄存器 (USART_SR)
  2. 数据寄存器 (USART_DR)
  3. 波特率寄存器 (USART_BRR)
  4. 智能卡模式下的保护时间寄存器 (USART_GTPR)

与STM32 USART 相关的函数和一些类型。

函数列表

  • HAL_UART_Abort()
  • HAL_UART_Abort_IT()
  • HAL_UART_AbortCpltCallback()
  • HAL_UART_AbortReceive()
  • HAL_UART_AbortReceive_IT()
  • HAL_UART_AbortReceiveCpltCallback()
  • HAL_UART_AbortTransmit()
  • HAL_UART_AbortTransmit_IT()
  • HAL_UART_AbortTransmitCpltCallback()
  • HAL_UART_DeInit()
  • HAL_UART_DMAPause()
  • HAL_UART_DMAResume()
  • HAL_UART_DMAStop()
  • HAL_UART_ErrorCallback()
  • HAL_UART_GetError()
  • HAL_UART_GetState()
  • HAL_UART_Init()
  • HAL_UART_IRQHandler()
  • HAL_UART_MspDeInit()
  • HAL_UART_Receive()
  • HAL_UART_Receive_DMA()
  • HAL_UART_Receive_IT()
  • HAL_UART_RxCpltCallback()
  • HAL_UART_Transmit()
  • HAL_UART_Transmit_DMA()
  • HAL_UART_Transmit_IT()
  • HAL_UART_TxCpltCallback()
  • HAL_UART_TxHalfCpltCallback()
  • HAL_HalfDuplex_EnableTransmitter()

HAL_UART_Abort(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
{
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

/* Abort the UART DMA Tx stream: use blocking DMA Abort API (no callback) */
if (huart->hdmatx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmatx->XferAbortCallback = NULL;

if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;

return HAL_TIMEOUT;
}
}
}
}

/* 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: use blocking DMA Abort API (no callback) */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = NULL;

if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;

return HAL_TIMEOUT;
}
}
}
}

/* Reset Tx and Rx transfer counters */
huart->TxXferCount = 0x00U;
huart->RxXferCount = 0x00U;

/* Reset ErrorCode */
huart->ErrorCode = HAL_UART_ERROR_NONE;

/* Restore huart->RxState and huart->gState to Ready */
huart->RxState = HAL_UART_STATE_READY;
huart->gState = HAL_UART_STATE_READY;

return HAL_OK;
}

HAL_UART_Abort_IT(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
HAL_StatusTypeDef HAL_UART_Abort_IT(UART_HandleTypeDef *huart)
{
uint32_t AbortCplt = 0x01U;

/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
before any call to DMA Abort functions */
/* DMA Tx Handle is valid */
if (huart->hdmatx != NULL)
{
/* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
Otherwise, set it to NULL */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
}
else
{
huart->hdmatx->XferAbortCallback = NULL;
}
}
/* DMA Rx Handle is valid */
if (huart->hdmarx != NULL)
{
/* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
Otherwise, set it to NULL */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
{
huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
}
else
{
huart->hdmarx->XferAbortCallback = NULL;
}
}

/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
/* Disable DMA Tx at UART level */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

/* Abort the UART DMA Tx stream : use non blocking DMA Abort API (callback) */
if (huart->hdmatx != NULL)
{
/* UART Tx DMA Abort callback has already been initialised :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */

/* Abort DMA TX */
if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
{
huart->hdmatx->XferAbortCallback = NULL;
}
else
{
AbortCplt = 0x00U;
}
}
}

/* 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 : use non blocking DMA Abort API (callback) */
if (huart->hdmarx != NULL)
{
/* UART Rx DMA Abort callback has already been initialised :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */

/* Abort DMA RX */
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
huart->hdmarx->XferAbortCallback = NULL;
AbortCplt = 0x01U;
}
else
{
AbortCplt = 0x00U;
}
}
}

/* if no DMA abort complete callback execution is required => call user Abort Complete callback */
if (AbortCplt == 0x01U)
{
/* Reset Tx and Rx transfer counters */
huart->TxXferCount = 0x00U;
huart->RxXferCount = 0x00U;

/* Reset ErrorCode */
huart->ErrorCode = HAL_UART_ERROR_NONE;

/* Restore huart->gState and huart->RxState to Ready */
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;

/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort complete callback */
huart->AbortCpltCallback(huart);
#else
/* Call legacy weak Abort complete callback */
HAL_UART_AbortCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}

return HAL_OK;
}

HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)

1
__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)

这是 UART 中止完成后调用的回调函数,需要自己根据需求进行实现。

HAL_UART_AbortReceive(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
HAL_StatusTypeDef HAL_UART_AbortReceive(UART_HandleTypeDef *huart)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* 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 : use blocking DMA Abort API (no callback) */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = NULL;

if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;

return HAL_TIMEOUT;
}
}
}
}

/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;

/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;

return HAL_OK;
}

HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* 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 : use blocking DMA Abort API (no callback) */
if (huart->hdmarx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;

/* Abort DMA RX */
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
{
/* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
huart->hdmarx->XferAbortCallback(huart->hdmarx);
}
}
else
{
/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;

/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;

/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Receive Complete Callback */
huart->AbortReceiveCpltCallback(huart);
#else
/* Call legacy weak Abort Receive Complete Callback */
HAL_UART_AbortReceiveCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;

/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;

/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Receive Complete Callback */
huart->AbortReceiveCpltCallback(huart);
#else
/* Call legacy weak Abort Receive Complete Callback */
HAL_UART_AbortReceiveCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}

return HAL_OK;
}

HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
__weak void HAL_UART_AbortReceiveCpltCallback(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_AbortReceiveCpltCallback can be implemented in the user file.
*/
}

HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
HAL_StatusTypeDef HAL_UART_AbortTransmit(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));

/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

/* Abort the UART DMA Tx stream : use blocking DMA Abort API (no callback) */
if (huart->hdmatx != NULL)
{
/* Set the UART DMA Abort callback to Null.
No call back execution at end of DMA abort procedure */
huart->hdmatx->XferAbortCallback = NULL;

if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
{
if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
{
/* Set error code to DMA */
huart->ErrorCode = HAL_UART_ERROR_DMA;

return HAL_TIMEOUT;
}
}
}
}

/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;

/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;

return HAL_OK;
}

HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));

/* Disable the UART DMA Tx request if enabled */
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

/* Abort the UART DMA Tx stream : use blocking DMA Abort API (no callback) */
if (huart->hdmatx != NULL)
{
/* Set the UART DMA Abort callback :
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;

/* Abort DMA TX */
if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
{
/* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
huart->hdmatx->XferAbortCallback(huart->hdmatx);
}
}
else
{
/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;

/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;

/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Transmit Complete Callback */
huart->AbortTransmitCpltCallback(huart);
#else
/* Call legacy weak Abort Transmit Complete Callback */
HAL_UART_AbortTransmitCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
}
else
{
/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;

/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;

/* As no DMA to be aborted, call directly user Abort complete callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
/* Call registered Abort Transmit Complete Callback */
huart->AbortTransmitCpltCallback(huart);
#else
/* Call legacy weak Abort Transmit Complete Callback */
HAL_UART_AbortTransmitCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}

return HAL_OK;
}

HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
__weak void HAL_UART_AbortTransmitCpltCallback(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_AbortTransmitCpltCallback can be implemented in the user file.
*/
}

HAL_UART_DeInit(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
if (huart == NULL)
{
return HAL_ERROR;
}

/* Check the parameters */
assert_param(IS_UART_INSTANCE(huart->Instance));

huart->gState = HAL_UART_STATE_BUSY;

/* Disable the Peripheral */
__HAL_UART_DISABLE(huart);

#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
if (huart->MspDeInitCallback == NULL)
{
huart->MspDeInitCallback = HAL_UART_MspDeInit;
}
/* DeInit the low level hardware */
huart->MspDeInitCallback(huart);
#else
/* DeInit the low level hardware */
HAL_UART_MspDeInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */

huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_RESET;
huart->RxState = HAL_UART_STATE_RESET;

/* Process Unlock */
__HAL_UNLOCK(huart);

return HAL_OK;
}

HAL_UART_DMAPause(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* @brief Pauses the DMA Transfer.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
{
uint32_t dmarequest = 0x00U;

/* Process Locked */
__HAL_LOCK(huart);

dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
{
/* Disable the UART DMA Tx request */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
}

dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
{
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* Disable the UART DMA Rx request */
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
}

/* Process Unlocked */
__HAL_UNLOCK(huart);

return HAL_OK;
}

HAL_UART_DMAResume(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* @brief Resumes the DMA Transfer.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
{
/* Process Locked */
__HAL_LOCK(huart);

if (huart->gState == HAL_UART_STATE_BUSY_TX)
{
/* Enable the UART DMA Tx request */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
}

if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
/* Clear the Overrun flag before resuming the Rx transfer*/
__HAL_UART_CLEAR_OREFLAG(huart);

/* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* Enable the UART DMA Rx request */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
}

/* Process Unlocked */
__HAL_UNLOCK(huart);

return HAL_OK;
}

HAL_UART_DMAStop(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* @brief Stops the DMA Transfer.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
{
uint32_t dmarequest = 0x00U;
/* The Lock is not implemented on this API to allow the user application
to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
*/

/* Stop UART DMA Tx request if ongoing */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);

/* Abort the UART DMA Tx stream */
if (huart->hdmatx != NULL)
{
HAL_DMA_Abort(huart->hdmatx);
}
UART_EndTxTransfer(huart);
}

/* Stop UART DMA Rx request if ongoing */
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
{
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

/* Abort the UART DMA Rx stream */
if (huart->hdmarx != NULL)
{
HAL_DMA_Abort(huart->hdmarx);
}
UART_EndRxTransfer(huart);
}

return HAL_OK;
}

HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @brief UART error 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_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
*/
}

HAL_UART_GetError(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
/**
* @brief Return the UART error code
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART.
* @retval UART Error Code
*/
uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
{
return huart->ErrorCode;
}

HAL_UART_GetState(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @brief Returns the UART state.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL state
*/
HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
{
uint32_t temp1 = 0x00U, temp2 = 0x00U;
temp1 = huart->gState;
temp2 = huart->RxState;

return (HAL_UART_StateTypeDef)(temp1 | temp2);
}

HAL_UART_Init(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* @brief Initializes the UART mode according to the specified parameters in
* the UART_InitTypeDef and create the associated handle.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{
/* Check the UART handle allocation */
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.
Except for STM32F446xx devices, that is available for USART1, USART2, USART3, USART6, UART4 and UART5.
*/
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 */
HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
}

huart->gState = HAL_UART_STATE_BUSY;

/* Disable the peripheral */
__HAL_UART_DISABLE(huart);

/* Set the UART Communication parameters */
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 */
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_READY;
huart->RxState = HAL_UART_STATE_READY;

return HAL_OK;
}

HAL_UART_IRQHandler(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/**
* @brief This function handles UART interrupt request.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
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);
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 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;
}
}

HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */

/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();

/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, USART_TX_Pin|USART_RX_Pin);

/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */

/* USER CODE END USART2_MspDeInit 1 */
}
}

HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* @brief Receives an amount of data in blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @param Timeout Timeout duration
* @retval HAL status
*/
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 */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
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 = HAL_GetTick();

huart->RxXferSize = Size;
huart->RxXferCount = Size;

/* Process Unlocked */
__HAL_UNLOCK(huart);

/* 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 */
huart->RxState = HAL_UART_STATE_READY;

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/**
* @brief Receives an amount of data in DMA mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;

/* Check that a Rx process is not already ongoing */
if (huart->RxState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}

/* Process Locked */
__HAL_LOCK(huart);

huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;

huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;

/* Set the UART DMA transfer complete callback */
huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;

/* Set the UART DMA Half transfer complete callback */
huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;

/* Set the DMA error callback */
huart->hdmarx->XferErrorCallback = UART_DMAError;

/* Set the DMA abort callback */
huart->hdmarx->XferAbortCallback = NULL;

/* Enable the DMA stream */
tmp = (uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR, *(uint32_t *)tmp, Size);

/* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
__HAL_UART_CLEAR_OREFLAG(huart);

/* Process Unlocked */
__HAL_UNLOCK(huart);

/* Enable the UART Parity Error Interrupt */
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);

/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);

/* Enable the DMA transfer for the receiver request by setting the DMAR bit
in the UART CR3 register */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* @brief Receives an amount of data in non blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the received data is handled as a set of u16. In this case, Size must indicate the number
* of u16 available through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be received.
* @retval HAL status
*/
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)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}

/* Process Locked */
__HAL_LOCK(huart);

huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->RxXferCount = Size;

huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->RxState = HAL_UART_STATE_BUSY_RX;

/* Process Unlocked */
__HAL_UNLOCK(huart);

/* 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;
}
else
{
return HAL_BUSY;
}
}

HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @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
*/
}

HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
* @brief Sends an amount of data in blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the sent data is handled as a set of u16. In this case, Size must indicate the number
* of u16 provided through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be sent
* @param Timeout Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint16_t *tmp;
uint32_t tickstart = 0U;

/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}

/* Process Locked */
__HAL_LOCK(huart);

huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;

/* Init tickstart for timeout managment */
tickstart = HAL_GetTick();

huart->TxXferSize = Size;
huart->TxXferCount = Size;

/* Process Unlocked */
__HAL_UNLOCK(huart);

while (huart->TxXferCount > 0U)
{
huart->TxXferCount--;
if (huart->Init.WordLength == UART_WORDLENGTH_9B)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
tmp = (uint16_t *) pData;
huart->Instance->DR = (*tmp & (uint16_t)0x01FF);
if (huart->Init.Parity == UART_PARITY_NONE)
{
pData += 2U;
}
else
{
pData += 1U;
}
}
else
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
huart->Instance->DR = (*pData++ & (uint8_t)0xFF);
}
}

if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}

/* At end of Tx process, restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* @brief Sends an amount of data in DMA mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the sent data is handled as a set of u16. In this case, Size must indicate the number
* of u16 provided through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;

/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}

/* Process Locked */
__HAL_LOCK(huart);

huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;

huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;

/* Set the UART DMA transfer complete callback */
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;

/* Set the UART DMA Half transfer complete callback */
huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;

/* Set the DMA error callback */
huart->hdmatx->XferErrorCallback = UART_DMAError;

/* Set the DMA abort callback */
huart->hdmatx->XferAbortCallback = NULL;

/* Enable the UART transmit DMA stream */
tmp = (uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);

/* Clear the TC flag in the SR register by writing 0 to it */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);

/* Process Unlocked */
__HAL_UNLOCK(huart);

/* Enable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
* @brief Sends an amount of data in non blocking mode.
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
* the sent data is handled as a set of u16. In this case, Size must indicate the number
* of u16 provided through pData.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @param pData Pointer to data buffer (u8 or u16 data elements).
* @param Size Amount of data elements (u8 or u16) to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}

/* Process Locked */
__HAL_LOCK(huart);

huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;

huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;

/* Process Unlocked */
__HAL_UNLOCK(huart);

/* Enable the UART Transmit data register empty Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);

return HAL_OK;
}
else
{
return HAL_BUSY;
}
}

HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @brief Tx 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_TxCpltCallback(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_TxCpltCallback could be implemented in the user file
*/
}

HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @brief Tx Half 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_TxHalfCpltCallback(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_TxHalfCpltCallback could be implemented in the user file
*/
}

HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* @brief Enables the UART transmitter and disables the UART receiver.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
{
uint32_t tmpreg = 0x00U;

/* Process Locked */
__HAL_LOCK(huart);

huart->gState = HAL_UART_STATE_BUSY;

/*-------------------------- USART CR1 Configuration -----------------------*/
tmpreg = huart->Instance->CR1;

/* Clear TE and RE bits */
tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));

/* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
tmpreg |= (uint32_t)USART_CR1_TE;

/* Write to USART CR1 */
WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);

huart->gState = HAL_UART_STATE_READY;

/* Process Unlocked */
__HAL_UNLOCK(huart);

return HAL_OK;
}

宏定义 Define

串口错误代码 (UART Error Code)

1
2
3
4
5
6
7
8
9
#define HAL_UART_ERROR_NONE              0x00000000U   /*!< No error | 没有错误           */
#define HAL_UART_ERROR_PE 0x00000001U /*!< Parity error | 奇偶校验错误 */
#define HAL_UART_ERROR_NE 0x00000002U /*!< Noise error | 噪声错误标志 */
#define HAL_UART_ERROR_FE 0x00000004U /*!< Frame error | 帧错误 */
#define HAL_UART_ERROR_ORE 0x00000008U /*!< Overrun error | 溢出错误 */
#define HAL_UART_ERROR_DMA 0x00000010U /*!< DMA transfer error | DMA传输错误 */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
#define HAL_UART_ERROR_INVALID_CALLBACK 0x00000020U /*!< Invalid Callback error */
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */

串口使能与禁能

  1. __HAL_UART_DISABLE
  2. __HAL_UART_DISABLE_IT
  3. __HAL_UART_ENABLE
  4. __HAL_UART_ENABLE_IT
1
2
3
4
5
6
7
8
9
#define __HAL_UART_DISABLE(__HANDLE__)              ((__HANDLE__)->Instance->CR1 &=  ~USART_CR1_UE)
#define __HAL_UART_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= USART_CR1_UE)
#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
((__HANDLE__)->Instance->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))

#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__HANDLE__)->Instance->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
(((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__HANDLE__)->Instance->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
((__HANDLE__)->Instance->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))

刷新串口数据寄存器

1
#define __HAL_UART_FLUSH_DRREGISTER(__HANDLE__) ((__HANDLE__)->Instance->DR)

获取 串口状态标志

状态寄存器 (USART_SR)
SR: 是英文 State Register 的缩写

1
2
#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR & (__FLAG__)) == (__FLAG__))

__HAL_UART_GET_FLAG(HANDLE, FLAG)

返回值为:TrueFalse

清除标志

  1. __HAL_UART_CLEAR_FEFLAG
  2. __HAL_UART_CLEAR_IDLEFLAG
  3. __HAL_UART_CLEAR_NEFLAG
  4. __HAL_UART_CLEAR_OREFLAG
  5. __HAL_UART_CLEAR_PEFLAG
  6. __HAL_UART_CLEAR_FLAG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
#define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
#define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)
#define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)

#define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \
do{ \
__IO uint32_t tmpreg = 0x00U; \
tmpreg = (__HANDLE__)->Instance->SR; \
tmpreg = (__HANDLE__)->Instance->DR; \
UNUSED(tmpreg); \
} while(0U)

#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__))

模块选择

1
#define HAL_UART_MODULE_ENABLED

检查指定的UART中断源是否启用。

1
2
#define __HAL_UART_GET_IT_SOURCE(__HANDLE__, __IT__) (((((__IT__) >> 28U) == UART_CR1_REG_INDEX)? (__HANDLE__)->Instance->CR1:(((((uint32_t)(__IT__)) >> 28U) == UART_CR2_REG_INDEX)? \
(__HANDLE__)->Instance->CR2 : (__HANDLE__)->Instance->CR3)) & (((uint32_t)(__IT__)) & UART_IT_MASK))

返回值:TrueFalse

枚举

HAL_UART_StateTypeDef

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef enum
{
HAL_UART_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized
Value is allowed for gState and RxState */
HAL_UART_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use
Value is allowed for gState and RxState */
HAL_UART_STATE_BUSY = 0x24U, /*!< an internal process is ongoing
Value is allowed for gState only */
HAL_UART_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing
Value is allowed for gState only */
HAL_UART_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing
Value is allowed for RxState only */
HAL_UART_STATE_BUSY_TX_RX = 0x23U, /*!< Data Transmission and Reception process is ongoing
Not to be used for neither gState nor RxState.
Value is result of combination (Or) between gState and RxState values */
HAL_UART_STATE_TIMEOUT = 0xA0U, /*!< Timeout state
Value is allowed for gState only */
HAL_UART_STATE_ERROR = 0xE0U /*!< Error
Value is allowed for gState only */
} HAL_UART_StateTypeDef;

HAL_LockTypeDef

1
2
3
4
5
typedef enum 
{
HAL_UNLOCKED = 0x00U,
HAL_LOCKED = 0x01U
} HAL_LockTypeDef;

结构体

UART_HandleTypeDef

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance; /*!< UART registers base address */

UART_InitTypeDef Init; /*!< UART communication parameters */

uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */

uint16_t TxXferSize; /*!< UART Tx Transfer size */

__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */

uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */

uint16_t RxXferSize; /*!< UART Rx Transfer size */

__IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */

DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */

DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */

HAL_LockTypeDef Lock; /*!< Locking object */

__IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
and also related to Tx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */

__IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */

__IO uint32_t ErrorCode; /*!< UART Error code */

#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
void (* TxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Half Complete Callback */
void (* TxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Tx Complete Callback */
void (* RxHalfCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Half Complete Callback */
void (* RxCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Rx Complete Callback */
void (* ErrorCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Error Callback */
void (* AbortCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Complete Callback */
void (* AbortTransmitCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Transmit Complete Callback */
void (* AbortReceiveCpltCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Abort Receive Complete Callback */
void (* WakeupCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Wakeup Callback */

void (* MspInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp Init callback */
void (* MspDeInitCallback)(struct __UART_HandleTypeDef *huart); /*!< UART Msp DeInit callback */
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */

} UART_HandleTypeDef;

USART_TypeDef

1
2
3
4
5
6
7
8
9
10
typedef struct
{
__IO uint32_t SR; /*!< USART Status register, Address offset: 0x00 */
__IO uint32_t DR; /*!< USART Data register, Address offset: 0x04 */
__IO uint32_t BRR; /*!< USART Baud rate register, Address offset: 0x08 */
__IO uint32_t CR1; /*!< USART Control register 1, Address offset: 0x0C */
__IO uint32_t CR2; /*!< USART Control register 2, Address offset: 0x10 */
__IO uint32_t CR3; /*!< USART Control register 3, Address offset: 0x14 */
__IO uint32_t GTPR; /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;

UART_InitTypeDef

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
typedef struct
{
uint32_t BaudRate; /*!< This member configures the UART communication baud rate.
The baud rate is computed using the following formula:
- IntegerDivider = ((PCLKx) / (8 * (OVR8+1) * (huart->Init.BaudRate)))
- FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 8 * (OVR8+1)) + 0.5
Where OVR8 is the "oversampling by 8 mode" configuration bit in the CR1 register. */

uint32_t WordLength; /*!< Specifies the number of data bits transmitted or received in a frame.
This parameter can be a value of @ref UART_Word_Length */

uint32_t StopBits; /*!< Specifies the number of stop bits transmitted.
This parameter can be a value of @ref UART_Stop_Bits */

uint32_t Parity; /*!< Specifies the parity mode.
This parameter can be a value of @ref UART_Parity
@note When parity is enabled, the computed parity is inserted
at the MSB position of the transmitted data (9th bit when
the word length is set to 9 data bits; 8th bit when the
word length is set to 8 data bits). */

uint32_t Mode; /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
This parameter can be a value of @ref UART_Mode */

uint32_t HwFlowCtl; /*!< Specifies whether the hardware flow control mode is enabled or disabled.
This parameter can be a value of @ref UART_Hardware_Flow_Control */

uint32_t OverSampling; /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
This parameter can be a value of @ref UART_Over_Sampling */
} UART_InitTypeDef;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
typedef struct __DMA_HandleTypeDef
{
DMA_Stream_TypeDef *Instance; /*!< Register base address */

DMA_InitTypeDef Init; /*!< DMA communication parameters */

HAL_LockTypeDef Lock; /*!< DMA locking object */

__IO HAL_DMA_StateTypeDef State; /*!< DMA transfer state */

void *Parent; /*!< Parent object state */

void (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete callback */

void (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback */

void (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer complete Memory1 callback */

void (* XferM1HalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer Half complete Memory1 callback */

void (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer error callback */

void (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA transfer Abort callback */

__IO uint32_t ErrorCode; /*!< DMA Error code */

uint32_t StreamBaseAddress; /*!< DMA Stream Base Address */

uint32_t StreamIndex; /*!< DMA Stream Index */

}DMA_HandleTypeDef;