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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80666.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI无法解决的Bug系列(一)跨时区日期过滤问题

跨时区开发中,React Native如何处理新西兰的日期过滤问题 有些Bug,不是你写错代码,而是现实太魔幻。 比如我最近给新西兰客户开发一个React Native应用,功能非常朴素:用户选一个日期范围,系统返回该范围内…

基于天猫 API 的高效商品详情页实时数据接入方法解析

一、引言 在电商大数据分析、竞品监控及智能选品等场景中,实时获取天猫商品详情页数据是关键需求。本文将详细解析通过天猫开放平台 API 高效接入商品详情数据的技术方案,涵盖接口申请、数据获取逻辑及代码实现,帮助开发者快速构建实时数据采…

系分论文《论遗产系统演化》

系统分析师论文范文系列 摘要 2022年6月,某金融机构启动核心业务系统的技术升级项目,旨在对其运行超过十年的遗留系统进行演化改造。该系统承担着账户管理、支付结算等关键业务功能,但其技术架构陈旧、扩展性不足,难以适应数字化转型与业务快速增长的需求。作为系统分析师,…

Spark Core基础与源码剖析全景手册

Spark Core基础与源码剖析全景手册 Spark作为大数据领域的明星计算引擎,其核心原理、源码实现与调优方法一直是面试和实战中的高频考点。本文将系统梳理Spark Core与Hadoop生态的关系、经典案例、聚合与分区优化、算子底层原理、集群架构和源码剖析,结合…

人工智能赋能产业升级:AI在智能制造、智慧城市等领域的应用实践

人工智能赋能产业升级:AI在智能制造、智慧城市等领域的应用实践 近年来,人工智能(AI)技术的快速发展为各行各业带来了深刻的变革。无论是制造业、城市管理,还是交通、医疗等领域,AI技术都展现出了强大的应用…

React Native打包报错: Task :react-native-picker:verifyReleaseResources FAILE

RN打包报错: Task :react-native-picker:verifyReleaseResources FAILED Execution failed for task :react-native-picker:verifyReleaseResources. 解决方法: 修改文件react-native-picker中的版本信息。 路径:node_modules/react-native-p…

虚拟网络编辑器

vmnet1 仅主机模式 hostonly 功能:虚拟机只能和宿主机通过vmnet1通信,不可连接其他网络(包括互联网) vmnet8 地址转换模式 NAT 功能:虚拟机可以和宿主通过vmnet8通信,并且可以连接其他网络,但是…

docker环境和dockerfile制作

docker 一、环境和安装 1、 docker安装 使用 root 权限登录 CentOS。确保 yum 包更新到最新sudo yum update卸载旧版本yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux …

[luogu12542] [APIO2025] 排列游戏 - 交互 - 博弈 - 分类讨论 - 构造

传送门:https://www.luogu.com.cn/problem/P12542 题目大意:给定一个长为 n n n 的排列和一张 m m m 个点 e e e 条边的简单连通图。每次你可以在图上每个点设置一个 0 ∼ n − 1 0\sim n-1 0∼n−1、两两不同的权值发给交互库,交互库会…

智能体agent概述

智能体概述 智能体是一个能够感知环境并在环境中自主行动以实现特定目标的系统。它具有以下几个关键特征: 自主性 - 智能体可以在没有直接人为干预的情况下运作,能够自行决策和行动。 响应性 - 能够感知环境并对环境变化做出及时响应。 主动性 - 不仅…

2:OpenCV—加载显示图像

加载和显示图像 从文件和显示加载图像 在本节中&#xff0c;我将向您展示如何使用 OpenCV 库函数从文件加载图像并在窗口中显示图像。 首先&#xff0c;打开C IDE并创建一个新项目。然后&#xff0c;必须为 OpenCV 配置新项目。 #include <iostream> #include <ope…

python训练 60天挑战-day31

知识点回顾 规范的文件命名规范的文件夹管理机器学习项目的拆分编码格式和类型注解 昨天我们已经介绍了如何在不同的文件中&#xff0c;导入其他目录的文件&#xff0c;核心在于了解导入方式和python解释器检索目录的方式。 搞清楚了这些&#xff0c;那我们就可以来看看&#x…

构建自动收集并总结互联网热门话题的网站

构建自动收集并总结互联网热门话题的网站的具体方案&#xff1a; 一、系统架构设计 数据采集层 • 使用Python的Scrapy或BeautifulSoup抓取新闻网站/社交媒体API # 示例&#xff1a;微博热点爬虫 import requests def fetch_weibo_hot():url "https://weibo.com/ajax/st…

pycharm无需科学上网工具下载插件的解决方案

以下是两种无需科学上网即可下载 PyCharm 插件的解决思路&#xff1a; 方法 1&#xff1a;设置 PyCharm 代理 打开 PyCharm选择菜单&#xff1a;File → Settings → Appearance & Behavior → System Settings → HTTP Proxy在代理设置中进行如下配置&#xff1a; 代理地…

机器学习自然语言处理

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;词向量&#xff08;Word Embedding&#xff09;是将人类语言转化为计算机可理解形式的关键技术。它通过数学空间中的向量表示&#xff0c;捕捉词语的语义和语法信息&#xff0c;有效解决了传统离散表示的 “维数灾难…

如何自学FPGA设计?

众所周知&#xff0c;FPGA设计自学难度不小&#xff0c;更不存在速成的捷径。这里简单说一下学习的规划&#xff0c;希望能给入门者提供一些方向。 学会相应的知识 不论是科班毕业还是理工科专业出身&#xff0c;想要入行FPGA开发&#xff0c;基础知识必须扎实。尤其是在高校…

南航无人机大规模户外环境视觉导航框架!SM-CERL:基于语义地图与认知逃逸强化学习的无人机户外视觉导航

作者&#xff1a; Shijin Zhao, Fuhui Zhou, Qihui Wu单位&#xff1a;南京航空航天大学电子信息工程学院论文标题&#xff1a; UAV Visual Navigation in the Large-Scale Outdoor Environment: A Semantic Map-Based Cognitive Escape Reinforcement Learning Method论文链接…

Linux-进程间通信

1.进程间通信介绍 1.1通信目的 数据传输&#xff1a;⼀个进程需要将它的数据发送给另⼀个进程 资源共享&#xff1a;多个进程之间共享同样的资源。 通知事件&#xff1a;⼀个进程需要向另⼀个或⼀组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发⽣了某种事…

精益数据分析(69/126):最小可行化产品(MVP)的设计、验证与数据驱动迭代

精益数据分析&#xff08;69/126&#xff09;&#xff1a;最小可行化产品&#xff08;MVP&#xff09;的设计、验证与数据驱动迭代 在创业旅程中&#xff0c;从需求洞察到产品落地的关键一跃是打造最小可行化产品&#xff08;MVP&#xff09;。今天&#xff0c;我们结合《精益…

从JavaScript快速上手Python:关键差异与核心技巧

引言 如果你是JavaScript开发者&#xff0c;可能会对Python的简洁语法和丰富的生态感兴趣。但两种语言的设计哲学和实现细节存在显著差异。本文将通过对比JS与Python的核心概念&#xff0c;帮助你快速过渡&#xff0c;避免“踩坑”。 一、语法差异&#xff1a;告别大括号&#…