嵌入式学习笔记 - STM32 U(S)ART 模块HAL 库函数总结

一 串口发送方式:

①轮训方式发送,也就是主动发送,这个容易理解,使用如下函数:

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

②中断方式发送,使用如下函数

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

过程如下:

首先使能发送中断__HAL_UART_ENABLE_IT(huart, UART_IT_TXE); 如果发送数据寄存器为空(第一次发送前为空),则进入USARTx_IRQHandler()中断向量入口,这个中断向量里面会调用总的串口中断处理函数HAL_UART_IRQHandler(&huart1);

里面有发送中断处理分支部分UART_Transmit_IT(huart),连续发送想要发送的多个字节下图红线部分所示,每调用一次发送一个字节数据,字节发送结束后发送寄存器变为空时再次进入此中断,每发一次huart->TxXferCount减一次,减为0时,失能发送中断,打开发送完成中断,如下图黄色色部分所示

然后再次回到USARTx_IRQHandler,调用 发送完成处理分支UART_EndTransmit_IT(huart);

UART_EndTransmit_IT函数会调用发送完成回调函数HAL_UART_TxCpltCallback(huart);

用户可以自行定义此函数进行相应处理

③ DMA 方式发送:

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

二 串口接收方式:

1)轮训方式接收,也就是主动去检查,这个容易理解,使用如下函数

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

2)DMA方式接收

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

3)中断方式接收,有两种方式,这里过程比较多比较难理解详细讲述:

不使用HAL库函数,直接寄存器方式,如下图,直接在中断向量表入口里面通过判断接收标志位RXNE,直接读寄存器DR,这样每一个收到一个字节会进一次中断

使用HAL库函数的回调函数,注意这里有两种接收方式以及相应的两种回调函数:

① 标准回调函数(接收完成回调函数): HAL_UART_RxCpltCallback()

接收到启动时设置的字节数(启动接收时需要设置接收数据长度)后的回调函数

a) 首先通过HAL_UART_Receive_IT(&huart1,(uint8_t *)RxBuff,BUFFSIZE)启动,这个启动函数要在初始化时首次启动,并且要在接收完定长数据后回调函数中再次启动,如下图

里面有开启中断接收数据的条件

以及条件赋值语句,这是选择进入标准回调函数的条件,

b) 发生中断时(接收到一个字节时)中断向量里面会调用总的串口中断处理函数HAL_UART_IRQHandler(&huart1);此函数会调用 UART_Receive_IT(huart);

此函数里面会对数据进行接收保存,如下,从此函数可以看出,不开启上面的a)步骤的条件,UART_Receive_IT是不会读接收寄存器的是数据的,如下图,所以想要使用HAL库回调函数接收数据,必须在初始化时通过HAL_UARTEx_ReceiveToIdle_IT或者HAL_UART_Receive_IT()函数开启接收状态,这是HAL库函数决定的。

c)此函数最终还会调用定长数据接收回调函数HAL_UART_RxCpltCallback(huart); 如下图

用户可以在回调函数中对数据进行想要的处理。

② 接收完成或者空闲回调函数 HAL_UARTEx_RxEventCallback()

接收完成或者空闲回调函数。当接收到预先设置好的字节数或者接收空闲(IDLE中断)时会回调这个函数

a) 首先通过HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t *)RxBuff,BUFFSIZE);开启接收状态如下图

里面有开启进入空闲回调函数的条件如下图

以及开启中断接收数据的条件,如下图

b) 发生中断时,串口中断向量入口会调用总处理函数HAL_UART_IRQHandler(&huart1)

此函数会调用函数UART_Receive_IT进行数据读取,从此函数可以发现如果不开启上面的a)步骤的条件,UART_Receive_IT是不会读接收寄存器的是数据的,如下图,所以想要使用HAL库回调函数接收数据,必须在初始化时通过HAL_UARTEx_ReceiveToIdle_IT或者HAL_UART_Receive_IT()函数开启接收状态,这是HAL库函数决定的。

c)以及最终调用完成或者空闲回调函数HAL_UARTEx_RxEventCallback(huart, nb_rx_data);

首先第一个情况下UART_Receive_IT里面在发送完成条件下,同标准回调函数一样,也调用了此回调函数

另外注意黄线所示语句, huart->ReceptionType = HAL_UART_RECEPTION_STANDARD;如果这是一个发送满一个RxBuffer量程的情况,就赋值接收模式为标准模式,就不会进入下面这个情况进行空闲模式分析与调用。

第二个情况:

首先有个条件,就是在第a)步骤中提及的条件,启动了HAL_UARTEx_ReceiveToIdle_IT空闲接收状态,并且前面没有接收满一个量程,上面紫色字体所述,如下图

其次是接收未满一个RxBuffer量程的条件,圆圈处代表总线空闲,接收未达到RxBuffer 满量程,进行此函数调用

两个回调函数的使用总结如下:

比如定义接收缓冲区大小为RxBuffer[10],也就是函数HAL_UART_Receive_IT(&huart1,(uint8_t *)RxBuff,BUFFSIZE)或者HAL_UARTEx_ReceiveToIdle_IT(&huart1,(uint8_t *)RxBuff,BUFFSIZE);中的BUFFERSIZE=10,调用机制如下图

相关推荐
崇山峻岭之间2 分钟前
Matlab学习记录30
开发语言·学习·matlab
朔北之忘 Clancy17 分钟前
2020 年 6 月青少年软编等考 C 语言一级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解
claider1 小时前
Vim User Manual 阅读笔记 User_03.txt move around
笔记·编辑器·vim
saoys1 小时前
Opencv 学习笔记:一文掌握四种经典图像滤波(均值 / 高斯 / 中值 / 双边)
笔记·opencv·学习
●VON1 小时前
可信 AI 认证:从技术承诺到制度信任
人工智能·学习·安全·制造·von
淬炼之火1 小时前
笔记:Cross Modal Fusion-Mamba
图像处理·笔记·计算机视觉·多模态·特征融合
逑之2 小时前
C语言笔记16:文件操作
c语言·笔记·单片机
一瞬祈望2 小时前
⭐ 深度学习入门体系(第 11 篇): 卷积神经网络的卷积核是如何学习到特征的?
深度学习·学习·cnn
wdfk_prog2 小时前
[Linux]学习笔记系列 -- 底层CPU与体系结构宏
linux·笔记·学习
逑之2 小时前
C语言笔记15:动态内存管理
c语言·网络·笔记