当前位置: 首页 > news >正文

嵌入式学习笔记 - 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,调用机制如下图

http://www.xdnf.cn/news/520759.html

相关文章:

  • 开启健康生活的多元养生之道
  • Prism使用消息总线打开窗体的案例(中介者模式)
  • GBS 8.0服装裁剪计划软件在线试用
  • SAPROv5.7
  • Muduo网络库大总结
  • 大语言模型 vs NLTK/SpaCy:NLP工具的代际跃迁与互补之道
  • LORA 微调 - LoRA 介绍与 LoRA 微调指南
  • 最长公共子序列(LCS)
  • 网络编程套接字(二)
  • 17 C 语言数据类型转换与数据溢出回绕详解:隐式转换、显式转换、VS Code 警告配置、溢出回绕机制
  • 并发编程(4)
  • 中山市东区信息学竞赛2025 题目解析
  • CMake调试与详细输出选项解析
  • 基于区块链技术的智能汽车诊断与性能分析
  • 运行vscode编辑器源码
  • 课外活动:再次理解页面实例化PO对象的魔法方法__getattr__
  • 【免杀】C2免杀技术(五)动态API
  • C2S-Scale方法解读
  • [Android] 青木扫描全能文档3.0,支持自动扫描功能
  • 机器学习入门之朴素叶贝斯和决策树分类(四)
  • 【VMware】开启「共享文件夹」
  • 计算机系统的工作原理
  • 2.2.5
  • 进程间通信--信号量【Linux操作系统】
  • leetcode解题思路分析(一百六十四)1418 - 1424 题
  • [论文品鉴] DeepSeek V3 最新论文 之 MHA、MQA、GQA、MLA
  • 进程状态并详解S和D状态
  • C++学习:六个月从基础到就业——C++17:结构化绑定
  • 什么是dom?作用是什么
  • 产品周围的几面墙