嵌入式学习笔记 - 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 满量程,进行此函数调用

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

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

相关推荐
Rabitebla6 分钟前
【Linux 底层原理】进程(十):进程等待详解---从僵尸进程到 wait、waitpid 与 status
linux·c++·笔记·学习·visual studio
小lu飞1 小时前
2026小红书小工具怎么制作:纯前端 ZIP 打包、沙箱限制与笔记挂载流程
前端·笔记·ai·ai编程
无心水5 小时前
24、系统架构师论文写作专题 核心考点与学习笔记
笔记·学习·系统架构·架构师·安全架构·软考架构师·软考系统架构设计师
蒸蒸yyyyzwd5 小时前
邓明 Agent 系统面试-意图识别学习笔记
笔记·学习
Zhao-Jichao8 小时前
AI Prompting for Everyone 课程笔记 - P21 总结 Conclusion
人工智能·笔记
欢欢李8 小时前
【LTE L3 笔记 05】LTE同步信号
笔记·无线通信·物理层·lte·空口协议
La Pulga10 小时前
【FreeRTOS源码学习笔记】空闲任务与阻塞延时
笔记·mcu·学习·嵌入式·freertos·实时操作系统
蒸蒸yyyyzwd10 小时前
秋招学习笔记 day106
笔记·学习
小李不想当小白11 小时前
WDG看门狗(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
欢欢李12 小时前
【LTE L3 笔记 04】LTE帧结构
笔记·无线通信·物理层·lte·空口协议