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)

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI绘画入门:探索数字艺术新世界(1/10)

引言:AI 绘画的兴起与现状 在科技飞速发展的当下,AI 绘画如同一场艺术领域的风暴,正以惊人的速度席卷而来,彻底改变着我们对艺术创作的认知。近年来,AI 绘画相关的话题屡屡登上热搜,从社交媒体上各种 AI 生…

多线程杂谈:惊群现象、CAS、安全的单例

引言 本文是一篇杂谈,帮助大家了解多线程可能会出现的面试题。 目录 引言 惊群现象 结合条件变量 CAS原子操作(cmp & swap) 线程控制:两个线程交替打印奇偶数 智能指针线程安全 单例模式线程安全 最简单的单例&…

Ubuntu -- 几行命令使用Ollama部署本地AI大模型, 仅调用api, 快速测试api效果

需求 需要在本地快速部署一个大模型, 然后使用 局域网 的其他电脑进行 api调用为了快速测试, 大模型选择了 qwen2:0.5B 进行快速测试 开始 下载安装 ollama curl -fsSL https://ollama.com/install.sh | sh验证安装 ollama --version下载安装模型并运行 ollama run qwen2:…

无降智o1 pro——一次特别的ChatGPT专业模式探索

这段时间和朋友们交流 ChatGPT 的使用心得,大家都提到一个很“神秘”的服务:它基于 O1 Pro 模型,能够在对话里一直保持相对高水平的理解和回复,不会突然变得“降智”。同时,整体使用还做了免折腾的网络设置——简单一点…

1. 基于图像的三维重建

1. 基于图像的三维重建 核心概念三维重建中深度图、点云的区别?深度图点云总结 深度图到点云还需要什么步骤?1. **获取相机内参**2. **生成相应的像素坐标**3. **计算三维坐标**4. **构建点云**5. **处理颜色信息(可选)**6. **去除…

国内有哪些著名的CRM系统提供商?

嘿,你有没有想过,在这个信息爆炸的时代里,企业怎么才能更好地管理客户关系呢?答案就是使用高效的CRM系统。今天我就来给大家聊聊那些在国际上非常有名的CRM系统提供商吧。 悟空CRM 首先不得不提的就是悟空CRM了!这可…

QTableWidget的简单使用

1.最简单的表格示例&#xff1a; ui->tableWidget->setRowCount(2);// 设置行数ui->tableWidget->setColumnCount(3);// 设置列数&#xff0c;一定要放在设置行表头之前QStringList rowHeaderList;// 行表头rowHeaderList << QStringLiteral("姓名"…

Jenkins-Pipeline简述

一. 什么是Jenkins pipeline&#xff1a; pipeline在jenkins中是一套插件&#xff0c;主要功能在于&#xff0c;将原本独立运行于单个或者多个节点的任务连接起来&#xff0c;实现单个任务难以完成的复杂发布流程。Pipeline的实现方式是一套Groovy DSL&#xff0c;任何发布流程…

Hadoop美食推荐系统 爬虫1.8w+数据 协同过滤余弦函数推荐美食 Springboot Vue Element-UI前后端分离

Hadoop美食推荐系统 爬虫1.8w数据 协同过滤余弦函数推荐美食 Springboot Vue Element-UI前后端分离 【Hadoop项目】 1. data.csv上传到hadoop集群环境 2. data.csv数据清洗 3.MapReducer数据汇总处理, 将Reducer的结果数据保存到本地Mysql数据库中 4. SpringbootEchartsMySQL 显…

两份PDF文档,如何比对差异,快速定位不同之处?

PDF文档比对是通过专门的工具或软件&#xff0c;自动检测两个PDF文件之间的差异&#xff0c;并以可视化的方式展示出来。这些差异可能包括文本内容的修改、图像的变化、表格数据的调整、格式的改变等。比对工具通常会标记出新增、删除或修改的部分&#xff0c;帮助用户快速定位…

苍穹外卖项目总结(二)

本篇对苍穹外卖后半部分进行介绍&#xff0c;重点是redis缓存的使用以及微信小程序客户端开发。 目录 一、菜品管理 1.1新增菜品 1.2菜品的分页查询 1.3删除菜品 1.4修改菜品 1.5设置营业状态 二、微信小程序客户端的开发 三、Redis的基本使用 常用命令&#xff1a; 缓…

MyBatisPlus简介及入门案例

一、简介 官网&#xff1a;https://baomidou.com/introduce/ 1.简介 MyBatisPlus只做增强&#xff0c;不做改变&#xff0c;为简化开发、提高效率而生 2.特性 (1)无侵入 只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑 (2)损耗小 启动…

欧拉(Euler 22.03)安装ProxySQL

下载离线安装包 proxysql-2.0.8-1-centos7.x86_64.rpm 链接: https://pan.baidu.com/s/1R-SJiVUEu24oNnPFlm9wRw 提取码: sa2w离线安装proxysql yum localinstall -y proxysql-2.0.8-1-centos7.x86_64.rpm 启动proxysql并检查状态 systemctl start proxysql 启动proxysql syste…

电子应用设计方案96:智能AI充电器系统设计

智能 AI 充电器系统设计 一、引言 智能 AI 充电器系统旨在为各种电子设备提供高效、安全、智能的充电解决方案&#xff0c;通过融合人工智能技术&#xff0c;实现自适应充电、优化充电效率和保护电池寿命。 二、系统概述 1. 系统目标 - 自适应识别不同设备的充电需求&#xf…

TongESB7.1.0.0如何使用dockercompose运行镜像(by lqw)

文章目录 安装准备安装 安装准备 1.安装好docker和dockercompose&#xff1a; docker、docker-compose安装教程&#xff0c;很详细 2.上传好安装相关文件 安装 使用以下命令导入管理端镜像和运行时镜像 docker load -i tongesb_manage_7100.tar docker load -i tongesb_se…

Python 模拟真人鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

微软Win10 RP 19045.5435(KB5050081)预览版发布!

系统之家1月20日最新报道&#xff0c;微软面向Release Preview频道的Windows Insider项目成员&#xff0c;发布了适用于Windows10 22H2版本的KB5050081更新&#xff0c;更新后系统版本号将升至19045.5435。本次更新增加了对GB18030-2022标准的支持&#xff0c;同时新版日历将为…

【VRChat · 改模】Unity工程导入人物模型;并添加着色器教程;

一、Unity工程导入人物模型 1.创建一个新的工程文件&#xff08;使用 VRChat 官方的开发工具 VCC&#xff09; 不添加着色器的时候&#xff0c;模型是粉色的 2.导入人物模型 在工程文件的 Assets 目录下&#xff0c;创建一个新的目录&#xff0c;可以起名为你的模型的名字 …

Django简介与虚拟环境安装Django

目录 1.Django简介 1.1 Django 的核心特点 1.2 Django 的核心组件 1.3 Django 的应用场景 1.4 总结 2.基础环境建立 2.1 创建虚拟环境 2.1.1 使用 virtualenv 创建虚拟环境 2.1.2 使用 venv 创建虚拟环境 2.2 激活虚拟环境 2.2.1 在 Windows 上 2.2.2 在 macOS 或 …

使用 ChatGPT 生成和改进你的论文

文章目录 零、前言一、操作引导二、 生成段落或文章片段三、重写段落四、扩展内容五、生成大纲内容六、提高清晰度和精准度七、解决特定的写作挑战八、感受 零、前言 我是虚竹哥&#xff0c;目标是带十万人玩转ChatGPT。 ChatGPT 是一个非常有用的工具&#xff0c;可以帮助你…