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

USART_串口通讯轮询案例(HAL库实现)

引言

       前面讲述的串口通讯案例是使用寄存器方式实现的,有利于深入理解串口通讯底层原理,但其开发效率较低;对此,我们这里再讲基于HAL库实现的串口通讯轮询案例,实现高效开发。当然,本次案例需求仍然和前面寄存器实现的案例一样,故这里就不再赘述相关需求以及电路设计,如果不清楚可参考下面链接跳转查看:USART_串口通讯轮询案例(一)(寄存器实现)-CSDN博客https://blog.csdn.net/2301_79475128/article/details/145222170?spm=1001.2014.3001.5501


一、案例需求描述

二、硬件电路设计

       由于本次案例和前面寄存器实现的案例相同,故这里不再赘述,可直接点击上面链接跳转查看,感谢支持!


三、软件设计

       话不多说,我们本次就基于HAL库来二次实现一下串口通讯轮询方式下的案例。首先我们必然是进入STM32CubeMX软件创建好工程并进行相应配置。

3.1 STM32CubeMX配置

首先,我们进入STM32CubeMX,开始创建工程

3.1.1 创建工程

       单击【ACCESS TO MCU SELECTOR】,然后选择自己使用的芯片类型双击它即可创建新的工程。

3.1.2 工程配置

        接下来,我们对其中相关部分进行配置,首先最基本的配置即【System Core】中【SYS】和【RCC】时钟等的配置,本次还涉及到收发数据使用的GPIO口,也会在其中进行配置。

       所以,单击【System Core】,选择【SYS】,配置调试器Debug串行单线【serial wire】,这样我们STLink下载器才能使用。

          然后,选择【RCC】,配置时钟,先是外部时钟,全部修改为晶振或者石英振荡器【Crystal/Ceramic Reasonator】即可

然后配置内部时钟,此时直接继续单击【Clock Configuration】,做如下配置即可

       接着,我们需要配置串口涉及到的GPIO,正常情况我们应该是去图形化芯片上设置对应引脚进行配置,但是由于串口通讯模块对应一个数据连接通讯的部分,在STM32CubeMX中有相应的选项可以直接进行配置,所以我们不必直接去配GPIO,可以直接在【Connectivity】中进行所有串口的相关配置。

          然后就可以开始配置串口了,首先我们目前只是使用串口异步功能,所以【Mode】一栏选择异步【Asynachronous】即可,然后下面的硬件流控【Hardware Flow control】不开启,即默认【Disable】就可以。 

        紧接着,我们看向下方,会发现有五个选项,分别是参数配置【Parameter Settings】(串口自身基本参数)、使用常量【User Constants】NVIC设置【NVIC Settings】(和中断相关)、DMA设置【DMA Settings】(DMA相关)、GPIO设置【GPIO Settings】(GPIO相关)。当前我们因为只是最简单的异步收发,只使用了TX和RX,所以只涉及两个GPIO口以及串口的一些参数设置。因此这里我们只要看看参数配置和GPIO设置就好了

单击进入参数设置【Parameter Settings】,可以看见HAL库默认给我们配置的一些参数

        显然,以及包含了我们前面使用寄存器配置串口的内容,这意味着后面自动生成的代码就已经帮我们基本做好了串口的初始化,而这里只需要我们图形化选择一下即可,很显然简单了很多。关于该部分的配置就按照其默认的配(如上图所示)即可。

       然后,我们单击进入GPIO设置【GPIO Settings】,如下图,看看发现以及给我们自动配置好了GPIO的东西,仔细检查一下,就和我们前面寄存器配置GPIO的模式是一样的,即PA9 TX端配置为复用功能的推挽输出模式、PA10 RX端配置成浮空输入模式即可

        最后,我们再进入【Project Manager】【Project】设置一下该工程的名字、路径以及工具链,然后进入【Code Generator】勾选些选项即可。

最后,我们点击【GENERATOR CODE】生成代码,如果在keil中打开工程即可

3.1.3 Keil中配置

        在keil中打开工程后,进入【魔法棒】,然后进入【Debug】,点击进入【Settings】,接着进入【Flash Download】,勾选【Reset and Run】;然后进入【Pack】,取消勾选【Enable】,最后不要忘记🆗保存了。

最后就可以退出keil了。然后进入vscode开始看看代码。

3.2 代码补充

        配置都做好了以后,我们就来看看代码,进入vscode,然后将刚才创建的工程导入进来,然后看看主要代码,首先是GPIO文件中的

       可以发现,这里主要是时钟配置,因为我们HAL库对GPIO的配置主要都放在USART文件中了

然后我们看看USART文件

       显然,这里就看见GPIO口的配置了,同时我们会发现,上面它定义了一个【huart1】变量,我们ctrl+单击这个前面的类型看看这是啥

        显然,这是一个结构体定义,然后看看其中的内容,会发现这实际上都是定义的和串口有关的东西,也就是说,huat1一个串口相关功能的结构体定义。因此下图这一部分全是关于串口的参数配置

       看完这俩以后,我们发现,当时寄存器编写的代码主要就是串口初始化的内容,然而这里HAL库做的时候代码以及全部自动生成了,意味着我们只需要去写一下发送接收的逻辑,同时HAL库也为我们提供了接收和发送数据的相关函数,直接调用即可。

       那么现在,我们来编写一下发送数据的测试逻辑,直接来个发送或者接收字符串吧,这样可以的话说发送单字符也肯定可以了。

        由于我们这里直接调用相应函数即可,这里就直接展示一下对应函数的使用了,main.c中如下图

一句发送,一句延时即可,我们借助这个简单逻辑测试一下,直接编译烧录看现象

显然,没有问题,测试成功。

       然后我们继续测试接收数据功能,实现一个“先接受一个字符串,然后发送”的逻辑,main.c代码如下,先创建两个变量用于存放字符串

然后,while循环中写接收并发送代码,这里和我们前面接收发送点区别:

       多了一个判断,因为这里HAL库中的发送是无脑直接拿到数据就发的,我们现在在循环中,没有发之前给的buffer,虽然我们没写入数据,但是其初始化是0,所以此时接收到的就是0,即发送就会直接把“\0”全部发出来。而为了避免这种情况,我们对接收函数做一个判断,因为其是有返回值的,就是为了避免接收有问题,当它确实正确接收到数据后,就会返回HAL_OK,所以我们这里判断它是否等于这个,等于即说明接收到我们发的了,这样我们再把数据发出来就好了。

然后我们测试一下,编译烧录看效果

显然,我们发送10个字符,他就能正确接收到。说明测试没问题

        当然了,我们发现我们调用接收函数传入的参数需要我们给出接收字符长度,这意味着我们只能接收定长的字符串,如果我们发送任意长的字符串的话,则会产生不符合需求的现象。

        因此,我们要怎么接收变长数据呢?实际上HAL库也提供了发送变长数据的函数,只不过名称稍微有些变化,我们想,之前寄存器实现边长数据的接收时多利用了一个检测空闲帧的位IDLE,所以在HAL库中关于变长数据的接收函数名上就带了IDLE,即如下图

        上图所示函数的描述就是我们用来接收变长数据的函数了。可以发现这里参数的变化就在于之前我们要传入的字符长度这里变成了两个参数,即一个是我们接收字符的总长度Size、另一个是指针表示,显然就是表示我们接收到的字符实际的长度*RxLen

那么·,我们现在就来对此测试一下,代码如下,就是把接收函数换了一个

我们编译烧录看看效果

显然,这里我们成功接收并发送了变长数据,说明本次测试成功了!

       这样,我们本次轮询方式的HAL库实现就完毕了,主要就是做了定长数据的发送或接收以及变长数据的接收和发送

        其中,关于一些异常情况我们这里没有展示,当然大家可以自己去试试看,当定长数据的接收与发送时,如果电脑给芯片发了不是规定长度的字符会出现什么情况。


3.3 相关函数介绍

       本次我们调用了几个HAL库提供的库函数,这里展示一下官方提供的详细的函数说明,只不过是英文的,可以当作锻炼自己翻译能力,或者如果实在看不懂也可以去用翻译软件翻译一下。

3.3.1 发送数据函数 HAL_UART_Transmit

/*** @brief  Sends an amount of data in blocking mode.* @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),*         the sent data is handled as a set of u16. In this case, Size must indicate the number*         of u16 provided through pData.* @param  huart Pointer to a UART_HandleTypeDef structure that contains*               the configuration information for the specified UART module.* @param  pData Pointer to data buffer (u8 or u16 data elements).* @param  Size  Amount of data elements (u8 or u16) to be sent* @param  Timeout Timeout duration* @retval HAL status*/
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout);/*** @brief  HAL Status structures definition*/
typedef enum
{HAL_OK       = 0x00U,HAL_ERROR    = 0x01U,HAL_BUSY     = 0x02U,HAL_TIMEOUT  = 0x03U
} HAL_StatusTypeDef;

3.3.2 接收定长数据函数 HAL_UART_Receive

/*** @brief  Receives an amount of data in blocking mode.* @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),*         the received data is handled as a set of u16. In this case, Size must indicate the number*         of u16 available through pData.* @param  huart Pointer to a UART_HandleTypeDef structure that contains*               the configuration information for the specified UART module.* @param  pData Pointer to data buffer (u8 or u16 data elements).* @param  Size  Amount of data elements (u8 or u16) to be received.* @param  Timeout Timeout duration* @retval HAL status*/
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);/*** @brief  HAL Status structures definition*/
typedef enum
{HAL_OK       = 0x00U,HAL_ERROR    = 0x01U,HAL_BUSY     = 0x02U,HAL_TIMEOUT  = 0x03U
} HAL_StatusTypeDef;

3.3.3 接收变长数据函数 HAL_UARTEx_ReceiveToIdle

/*** @brief Receive an amount of data in blocking mode till either the expected number of data is received or an IDLE event occurs.* @note   HAL_OK is returned if reception is completed (expected number of data has been received)*         or if reception is stopped after IDLE event (less than the expected number of data has been received)*         In this case, RxLen output parameter indicates number of data available in reception buffer.* @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),*         the received data is handled as a set of uint16_t. In this case, Size must indicate the number*         of uint16_t available through pData.* @param huart   UART handle.* @param pData   Pointer to data buffer (uint8_t or uint16_t data elements).* @param Size    Amount of data elements (uint8_t or uint16_t) to be received.* @param RxLen   Number of data elements finally received (could be lower than Size, in case reception ends on IDLE event)* @param Timeout Timeout duration expressed in ms (covers the whole reception sequence).* @retval HAL status*/
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint16_t *RxLen, uint32_t Timeout)

以上便是本次文章的所有内容,欢迎各位朋友在评论区讨论,本人也是一名初学小白,愿大家共同努力,一起进步吧!

鉴于笔者能力有限,难免出现一些纰漏和不足,望大家在评论区批评指正,谢谢!

相关文章:

USART_串口通讯轮询案例(HAL库实现)

引言 前面讲述的串口通讯案例是使用寄存器方式实现的,有利于深入理解串口通讯底层原理,但其开发效率较低;对此,我们这里再讲基于HAL库实现的串口通讯轮询案例,实现高效开发。当然,本次案例需求仍然和前面寄…...

【前端】CSS学习笔记(2)

目录 CSS3新特性圆角阴影动画keyframes 创建动画animation 执行动画timing-function 时间函数direction 播放方向过渡动画(transition) 媒体查询设置meta标签媒体查询语法 雪碧图字体图标 CSS3新特性 圆角 使用CSS3border-radius属性,你可以…...

【esp32小程序】小程序篇02——连接git

一、创建仓库 进入gitee官网,登录(如果没有gitee账号的就自行注册一下)。 点击号-->新建仓库 填写好必填信息,然后点击“创建” 二、微信开发者工具配置 在微信开发者工具打开我们的项目。按下面的步骤依次点击 三、验证 点…...

echarts柱状图象形图,支持横向滑动

展示效果 代码 let xData [2020,2021,2022,2023, 2024, 2025, 2026]; let yData [267,2667,2467,2667, 3234, 4436,666]; option {grid: {left: 5%,right: 5%,top: 15%,bottom: 5%,containLabel: true},// 滚动条dataZoom: [{show: true,type: inside,zoomLock: true,throt…...

YOLO系列代码

Test-Time Augmentation TTA (Test Time Augmentation)是指在test过程中进行数据增强。其思想非常简单,就是在评测阶段,给每个输入进行多种数据增广变换,将一个输入变成多个输入,然后再merge起来一起输出,形成一种ensemble的效果,可以用来提点。参考:​​​​​​​​​…...

HTML根元素<html>的语言属性lang:<html lang=“en“>

诸神缄默不语-个人CSDN博文目录 在编写HTML页面时&#xff0c;通常会看到<html lang"en">这行代码&#xff0c;特别是在网页的开头部分&#xff0c;就在<!DOCTYPE html>后面。许多开发者可能对这个属性的含义不太了解&#xff0c;它到底有什么作用&…...

opencv在图片上添加中文汉字(c++以及python)

opencv在图片上添加中文汉字&#xff08;c以及python&#xff09;_c opencv绘制中文 知乎-CSDN博客 环境&#xff1a; ubuntu18.04 desktopopencv 3.4.15 opencv是不支持中文的。 这里C代码是采用替换原图的像素点来实现的&#xff0c;实现之前我们先了解一下汉字点阵字库。…...

Perplexity AI 周六向 TikTok 母公司字节跳动递交了一项提案

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

Java连接TDengine和MySQL双数据源

git文件地址&#xff1a;项目首页 - SpringBoot连接TDengine和MySQL双数据源:SpringBoot连接TDengine和MySQL双数据源 - GitCode 1、yml配置 spring:datasource:druid:mysql:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/testusername: roo…...

Web3 游戏周报(1.13 - 1.19)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【1.13–1.19】Web3 游戏行业动态 索尼区块解决方案实验室 (Sony BSL) 宣布其以太坊 L2 区块链 Soneium 主网上线。Hyve Labs 融资 275 万美元&#xff0c;推动 Web3 游戏基础设…...

[深度学习]机器学习和深度学习

机器学习和深度学习 文章目录 机器学习和深度学习人工智能与机器学习和深度学习的关系侠义的机器学习深度学习的概念常见的神经网络的输入形式想要的输出(任务类别)深度学习的流程 线性函数与多层神经元 人工智能与机器学习和深度学习的关系 所谓人工智能就是&#xff0c;让计算…...

区块链技术

区块链是一个信息技术领域的术语&#xff0c;它代表了去中心化、安全性高、透明度强的分布式账本技术。以下是对区块链的详细介绍&#xff1a; 一、定义与基本原理 区块链&#xff08;Blockchain&#xff09;是指通过去中心化和去信任的方式集体维护一个可靠数据库的技术方案…...

vim函数定义跳转相关设置

修改下vim的一些ctags相关快捷键&#xff0c;个人用着顺手点。 小结如下&#xff1a; normal模式下的gk&#xff0c;用来打开一个预览窗口预览函数定义&#xff08;需要ctags生成好tags文件&#xff09;。normal模式下的gd&#xff0c;修改映射为ctrl]&#xff0c;即跳转到函…...

如何使用Python爬虫获取微店商品详情:代码示例与实践指南

在电商领域&#xff0c;获取商品详情数据对于商家和开发者来说至关重要。微店作为国内知名的电商平台&#xff0c;提供了丰富的商品数据接口&#xff0c;方便开发者通过API调用获取商品详情。本文将详细介绍如何使用Python爬虫获取微店商品详情&#xff0c;并提供具体的代码示例…...

Autosar CP RTE规范解读之不同 BSW 接口的通知与软件组件激活机制:标准化接口与 AUTOSAR 接口的实现方式

在汽车电子系统开发中&#xff0c;特别是在遵循 AUTOSAR 架构的系统中&#xff0c;基本软件&#xff08;BSW&#xff09;模块之间的通信和信息通知机制至关重要&#xff0c;它直接影响着系统的性能、可靠性以及各个软件组件之间的协同工作能力。本文根据不同类型的 BSW 接口&am…...

基于STM32的智能门锁安防系统(开源)

目录 项目演示 项目概述 硬件组成&#xff1a; 功能实现 1. 开锁模式 1.1 按键密码开锁 1.2 门禁卡开锁 1.3 指纹开锁 2. 功能备注 3. 硬件模块工作流程 3.1 步进电机控制 3.2 蜂鸣器提示 3.3 OLED显示 3.4 指纹与卡片管理 项目源代码分析 1. 主程序流程 (main…...

搭建Hadoop源代码阅读环境

个人博客地址:搭建Hadoop源代码阅读环境 | 一张假钞的真实世界 环境 Mac OS X EI Capitan 10.11.6java version “1.7.0_80”git version 2.7.4 (Apple Git-66)Apache Maven 3.3.9下载源代码 从Git上下载最新源代码: git clone git://git.apache.org/hadoop-common.git 构…...

【25】Word:林涵-科普文章❗

目录 题目​ NO1.2.3 NO4.5.6 NO7.8 NO9.10 NO11.12 不连续选择&#xff1a;按住ctrl按键&#xff0c;不连续选择连续选择&#xff1a;按住shift按键&#xff0c;选择第一个&#xff0c;选择最后一个。中间部分全部被选择 题目 NO1.2.3 布局→纸张方向&#xff1a;横向…...

Spring Boot接收参数的19种方式

Spring Boot是一个强大的框架&#xff0c;允许开发人员通过多种方式接收和处理参数。无论是HTTP请求参数、路径变量&#xff0c;还是请求体中的数据&#xff0c;Spring Boot都能提供灵活的处理方式。本文将介绍19种不同的方式来接收参数。 1. 查询参数&#xff08;Query Param…...

云IDE:开启软件开发的未来篇章

敖行客一直致力于将整个研发协作流程线上化&#xff0c;从而打破物理环境依赖&#xff0c;让研发组织模式更加灵活、自由且高效&#xff0c;今天就来聊聊AT Work&#xff08;一站式研发协作平台&#xff09;的重要组成部分-云IDE。 在科技领域&#xff0c;历史常常是未来的风向…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...