目的
UART(异步串口)是单片机非常常用的一个功能,一般用作设备或模块间通讯的一种方式。通常所说的232或是485通讯从写程序的角度来说就是使用UART进行通讯。(这个地方有些人会混淆,串口更多是一种通讯方式、机制,而TTL、232、485更多的是电气相关特性)
基础说明与初始化
基础说明
STM32系列MCU大多都有多个UART可以使用,每个UART可以设置独立的参数,和其它设备通讯时通讯的双方必须有相同的参数。一般会涉及的参数如下:
-
BaudRate
波特率,通讯速率,当其他参数默认时,每秒可传输字节数约为 BaudRate/10;
-
WordLength
数据位,数据位表示每一个数据包含bit数,一般用8bit,即一个数据为一个字节;
-
StopBits
停止位,停止位用来表示一个数据传输结束;
-
Parity
校验位,校验位用来校验传输的数据是否正确,一般也比较少用,通讯用的协议一般带自己的校验方式;
-
HwFlowCtl
流控制,现在比较少用到;
-
OverSampling
过采样,一般默认就行;
初始化
如果使用STM32CubeMX来初始化UART的话我们一般只要根据需求设置基本参数、中断、DMA即可,如下图所示:
默认情况下STM32CubeMX生成的初始化代码分别位于main和stm32fxxx_hal_msp文件中,其中UART基本参数相关设置代码如下:
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
如果想要在使用过程中更改串口参数可以用上面代码更改,如果想要关闭串口可以使用 HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
函数。
数据接收和发送
UART的数据接收和发送可以分别为轮询、中断、DMA三种方式,同一个串口三种方式不可混用。
轮询方式
轮询方式使用UART只需要设置基本参数就行,不需要开启中断和DMA。轮询模式下收发数据使用下面函数:
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
上面函数使用时分别传入UART对象、数据指针、数据长度、超时时间(默认情况下单位ms)。这两个函数在调用时均会阻塞程序,直至数据传输完成或者超时。所以轮询方式一般不怎么推荐。
中断方式
中断方式使用UART需要设置基本参数和开启中断,不需要启用DMA。中断模式下收发数据需要用到下面函数:
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
上面两个函数分别是接收和发送的操作。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
上面两个函数分别是接收和发送完成时的回调函数,用户需要自行编写回调函数具体的内容。
中断方式收发数据其实是每收发一个字节均会触发一次中断的,只不过HAL库将它处理了,用户一般只在全部完成时进行操作。这种方式会频繁进出中断,在使用时需要注意。
DMA方式
DMA模式下收发数据需要用到下面函数:
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
上面两个函数分别是接收和发送的操作。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
上面两个函数分别是接收和发送完成时的回调函数,用户需要自行编写回调函数具体的内容。
其它说明
UART除了设置、收发数据外还有一些功能,如下图:
- 带有
HAL_UART_Abort
字符的函数是用来取消当前正在进行的传输的相关操作;
- 带有
HAL_UART_DMA
字符的函数是用来控制DMA方式收发数据过程的相关操作;
-
HAL_UART_GetError
和 HAL_UART_GetState
函数分别用来获取UART的错误和状态信息,具体信息参见其宏定义;
- 带有
HalfCpltCallback
字符的函数是传输过半回调函数,用户可以根据需求自行重写函数具体功能;
总结
UART基本使用还是比较简单的。一般实际使用中除了基本的功能使用外还需要编写一些额外的收发逻辑,这块内容会在之后的文章中讲解。
更多内容可以参考官方库文档,比如上面演示中用的F4系列文档《UM1725 User Manual - Description of STM32F4 HAL and LL drivers》。