目录
1 串口查询模式
HAL_UART_Transmit
/**
* @brief 以阻塞模式发送一定量的数据。
* @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,发送的数据被处理为一组u16。在这种情况下,Size必须表示通过pData提供的u16的数量。
* @param huart 指向UART_HandleTypeDef结构的指针,该结构包含指定UART模块的配置信息。
* @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
* @param Size 要发送的数据元素的数量(u8或u16)。
* @param Timeout 超时时间,单位是ms。
* @retval HAL状态
*/
Definition at line 1135 of file stm32f4xx_hal_uart.c.
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
const uint8_t *pdata8bits;
const uint16_t *pdata16bits;
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 management */
tickstart = HAL_GetTick();
huart->TxXferSize = Size;
huart->TxXferCount = Size;
/* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (const uint16_t *) pData;
}
else
{
pdata8bits = pData;
pdata16bits = NULL;
}
/* Process Unlocked */
__HAL_UNLOCK(huart);
while (huart->TxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
{
huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
pdata16bits++;
}
else
{
huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
pdata8bits++;
}
huart->TxXferCount--;
}
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_Receive
/**
* @brief 在阻塞模式下接收一定量的数据。
* @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,接收的数据被处理为一组u16。在这种情况下,Size必须通过pData表示可用的u16的数量。
* @param huart 指向 UART_HandleTypeDef 结构的指针,该结构包含指定 UART 模块的配置信息。
* @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
* @param Size 要接收的数据元素的数量(u8或u16)。
* @param Timeout 超时时间
* @retval HAL 状态
*/
Definition at line 1223 of file stm32f4xx_hal_uart.c.
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
uint8_t *pdata8bits;
uint16_t *pdata16bits;
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;
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
/* Init tickstart for timeout management */
tickstart = HAL_GetTick();
huart->RxXferSize = Size;
huart->RxXferCount = Size;
/* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
{
pdata8bits = NULL;
pdata16bits = (uint16_t *) pData;
}
else
{
pdata8bits = pData;
pdata16bits = NULL;
}
/* Process Unlocked */
__HAL_UNLOCK(huart);
/* Check the remain data to be received */
while (huart->RxXferCount > 0U)
{
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
{
return HAL_TIMEOUT;
}
if (pdata8bits == NULL)
{
*pdata16bits = (uint16_t)(huart->Instance->DR & 0x01FF);
pdata16bits++;
}
else
{
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) || ((huart->Init.WordLength == UART_WORDLENGTH_8B) && (huart->Init.Parity == UART_PARITY_NONE)))
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
}
else
{
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
pdata8bits++;
}
huart->RxXferCount--;
}
/* At end of Rx process, restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
eg:
char str[12] = "Hello World\n"; char recv_buf[12] = {0};
HAL_UART_Transmit(&huart1, (uint8_t*)str, 12, 0xFFFF); //接收12个字节的数据,不超时 if(HAL_OK == HAL_UART_Receive(&huart1, (uint8_t*)recv_buf, 12, 0xFFFF)) { //将接收到的数据发送 HAL_UART_Transmit(&huart1, (uint8_t*)recv_buf, 12, 0xFFFF); }
&huart1:串口句柄地址;
(uint8_t*):
1字节 uint8_t
2字节 uint16_t
4字节 uint32_t
8字节 uint64_t0xFFFF:不超时。
2 串口中断模式
HAL_UART_Transmit_IT
/**
* @brief 以非阻塞模式发送一定量的数据。
* @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,发送的数据被处理为一组u16。在这种情况下,Size必须表示通过pData提供的u16的数量。
* @param huart 指向UART_HandleTypeDef结构的指针,该结构包含
* 指定UART模块的配置信息。
* @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
* @param Size 要发送的数据元素的数量(u8或u16)。
* @retval HAL状态
*/
Definition at line 1314 of file stm32f4xx_hal_uart.c.
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, const 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_Receive_IT
/**
* @brief 在非阻塞模式下接收一定量的数据。
* @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1 - M0 = 01)时,接收的数据被处理为一组u16。在这种情况下,Size必须通过pData表示可用的u16的数量。
* @param huart 指向UART_HandleTypeDef结构的指针,该结构包含
* 指定UART模块的配置信息。
* @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
* @param Size 要接收的数据元素的数量(u8或u16)。
* @retval HAL状态
*/
Definition at line 1359 of file stm32f4xx_hal_uart.c.
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);
/* Set Reception type to Standard reception */
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
return (UART_Start_Receive_IT(huart, pData, Size));
}
else
{
return HAL_BUSY;
}
}
HAL_UART_RxCpltCallback
/**
* @brief Rx 转移完成的回调。
* @param huart 指向UART_HandleTypeDef结构的指针,其中包含指定UART模块的配置信息。
* @retval 无
*/
Definition at line 2618 of file stm32f4xx_hal_uart.c.
__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
*/
}
eg:
/* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ uint8_t hello[] = "USART1 is ready...\n"; uint8_t recv_buf[13] = {0}; /* USER CODE END 0 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* 判断是哪个串口触发的中断 */ if(huart ->Instance == USART1) { //将接收到的数据发送 HAL_UART_Transmit_IT(huart, (uint8_t*)recv_buf, 13); //重新使能串口接收中断 HAL_UART_Receive_IT(huart, (uint8_t*)recv_buf, 13); } }
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ //使能串口中断接收 HAL_UART_Receive_IT(&huart1, (uint8_t*)recv_buf, 13); //发送提示信息 HAL_UART_Transmit_IT(&huart1, (uint8_t*)hello, sizeof(hello)); /* USER CODE END 2 */ while (1) { } }
3 串口DMA模式
HAL_UART_Transmit_DMA
/**
* @brief 以DMA模式发送一定量的数据。
* @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1-M0 = 01)时,发送的数据被处理为一组u16。在这种情况下,Size必须表示通过pData提供的u16的数量。
* @param huart 指向UART_HandleTypeDef结构的指针,该结构包含指定UART模块的配置信息。
* @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
* @param Size 要发送的数据元素的数量(u8或u16)。
* @retval HAL状态
*/
Definition at line 1394 of file stm32f4xx_hal_uart.c.
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size)
{
const 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 = (const uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(const 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 */
ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
eg:
/* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ uint8_t dat[] = "Hello, I am koko.\n"; /* USER CODE END 0 */
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Transmit_DMA(&huart1, (uint8_t*)dat, sizeof(dat)); /* USER CODE END 2 */ while (1) { } }
HAL_UART_Receive_DMA
/**
* @brief 在DMA模式下接收一定量的数据。
* @注 当UART奇偶校验未启用(PCE = 0),且字长被配置为9位(M1-M0 = 01)时,接收的数据被处理为一组u16。在这种情况下,Size必须通过pData表示可用的u16的数量。
* @param huart 指向 UART_HandleTypeDef 结构的指针,该结构包含指定 UART 模块的配置信息。
* @param pData 指向数据缓冲区的指针(u8或u16数据元素)。
* @param Size 要接收的数据元素的数量(u8或u16)。
* @注意 当UART奇偶校验被启用时(PCE = 1),接收的数据包含奇偶校验位。
* @retval HAL 状态
*/
Definition at line 1462 of file stm32f4xx_hal_uart.c.
HAL_StatusTypeDef HAL_UART_Receive_DMA(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);
/* Set Reception type to Standard reception */
huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;
return (UART_Start_Receive_DMA(huart, pData, Size));
}
else
{
return HAL_BUSY;
}
}
eg:
/* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ uint8_t dat[] = "Hello, I am koko.\n"; uint8_t recv_buf[13] = {0}; //串口接收缓冲区 /* USER CODE END 0 */
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Transmit(&huart1, (uint8_t*)dat, sizeof(dat), 0xFFFF); HAL_UART_Receive_DMA(&huart1, recv_buf, 13); //使能DMA接收 /* USER CODE END 2 */ while (1) { } }
/* USER CODE BEGIN 4 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { //将接收到的数据再发送 HAL_UART_Transmit(&huart1,recv_buf,13, 0xFFFF); } /* USER CODE END 4 */