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

【【STM32-29正点原子版本串口发送传输实验】

STM32-29正点原子版本串口发送传输实验

通过串口接收或发送一个字符
例程目的

开发板上我们接入的是实现异步通信的UART接口
在这里插入图片描述
USB转串口原理图
我们一步步分析
在这里插入图片描述
在这里插入图片描述
PA9是串口1 的发送引脚
PA10是串口1 的接受引脚
在这里插入图片描述
在这里插入图片描述
。因为我们现在只是用到异步收发器功能,所以我们现在只需要 stm32fxx_hal_uart.c 文件(及其头文件)的驱动代码,stm32f1xx_hal_usart.c 是通用同步异步收发器,暂时没有用到,可以暂时不看。用到一个外设第一个函数就应该是其初始化函数。
在这里插入图片描述
首先我们需要做的第一步是
无论干什么事情 第一步就是先把用到的东西初始化了

HAL_UART_Init 函数

要使用一个外设首先要对它进行初始化,所以先看串口的初始化函数,其声明如下:HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);
这是范式例中给出的指示
我们现在直接先看正点原子讲述的介绍
它先设定了
UART_HandleTypeDef g_uartl_handle
意思就是 我们上来UART这个句柄结构体的类型下的一个名字叫g_uartl_handle
就像是int a 懂?
这里的UART_HandleTypeDef 来自于我们一开始设定的HAL_UART_Init(UART_HandleTypeDef *huart);

这只是初步的设计和占用
然后接下来我们是第一个涉及到的
用了定义新的类型
在这里插入图片描述
这是对于串口1进行初始化 我们这时候脑子迅速过一下想不对啊 这和我们上面的这个不对啊
先暂时放下这个问题
然后我们先看内部的继续
第一个是
g_uart1_handle.Instance = USART1 ;
在这里插入图片描述
我们更加抓住的重点是结构体中的两项 Instance 和 Init

(在这里我必须吐槽一声 你写东西能不能按照规矩去写 ,说的就是你 能不能写成 USART_TypeDef* Instance 就像是 int* a 整个指针类型代表了a的地址 )
而这个Init 所指代的InitTypeDef 又是一整个结构体 所以我们在上面使用的时候会有Init.BaudRate 这种用法
在这里插入图片描述
所以我们写下来
就是第一个Instance 代表的是寄存器基地址 我们写入都是USART1 其实我们在这之前就偷偷的写好了USART1 对于 整个寄存器的define 对于HAL库的所有便捷使用其实在暗中早就define 好了寄存器的位置
接下来按照要求想法写好
1)BaudRate:波特率设置。一般设置为 2400、9600、19200、115200。
2)WordLength:数据帧字长,可选 8 位或 9 位。这里我们设置为 8 位字长数据格式。
3)StopBits:停止位设置,可选 0.5 个、1 个、1.5 个和 2 个停止位,一般我们选择 1 个停止位。
4)Parity:奇偶校验控制选择,我们设定为无奇偶校验位。
5)Mode:UART 模式选择,可以设置为只收模式,只发模式,或者收发模式。这里我们设置为全双工收发模式。
6)HwFlowCtl:硬件流控制选择,我们设置为无硬件流控制。
7)OverSampling:过采样选择,选择 8 倍过采样或者 16 过采样,一般选择 16 过采样。
然后下面是
HAL_UART_Init(&g_uart1_handle)
就是把上面的那个结构体 取地址放进来 因为是(类似int* ) 类型的摆明了就是一个地址

这就相当于把HAL全部初始化完了
我们在前面的示例中只给出了一个句柄有什么嘛,这个句柄的g_什么什么的,还是我们自己define 的 ,我们首先总命名叫usart_init 然后先define 一个句柄类型的名字 ,我们把句柄下,需要自己设置的初始化的内容填上去。 接下来在最后我们浅浅的写上HAL_UART_Init 这东西到底初始化什么,那你别管了,那是HAL库的事情了 ,我们所传递给他一个蕴含句柄信息的地址就可以了。有些人会在这里问,既然你说HAL库都定义好了,为什么我不直接写这句话,我想说 ,那你傻啊,他怎么知道你要初始化什么串口,初始化成什么状态嘛。
照这么写就好了
在这里插入图片描述
接下来第二步
串口MSP回调函数
我们现在好奇为什么会这样,不是已经初始化过了嘛,你怎么又在搞这种初始化,但是此言差矣,因为我们上面的初始化的是我们的UART串口,我们回调函数的意义有没有忘记,但是每经历一次串口的初始化,我们都会调用一次MspInit 那么我们必须明白我们串口的顺序?何时调用 ,其实这部分很明显可以写进上一个UART的初始化。但是为了层次化的带吗叙述我们分开写,并且可以在此处顺便配置完GPIO的设计。
HAL_UART_MspInit (传入的还是我们上面所提供的整个新定义句柄结构的基地址)
void HAL_UART_MspInit(地址)
因为串口初始化完成之后,我们内部会自行调用
在这里插入图片描述
因为要配置GPIO了所以先确定一个
GPIO_InitTypeDef类型下的gpio_init_struct
然后判断完所使用的确实是串口1 我们开始接下来的使用
1.使能USART1和对应IO时钟
2.初始化IO
3.使能USART1中断,设置优先级
在这里插入图片描述
我们到这里做一个小型的总结 先第一步 初始化想要用的串口,配置了一大堆。
第二步到这里 ,反正串口初始化会自动调用这个Mspinit 我们把串口选择 选择完之后并且PA9 PA10 一并的GPIO设置一下 (其实我觉得私下里可以分开,但是算了写在一起也行吧)
下面叙述的是GPIO串口的配置
PA9 PA10 推挽复用 上拉 高速
在这里插入图片描述
其实这里的写法是和之前的是一模一样的,我们观察之前GPIO的显示就能看出来了
(其实所有的初始化都是一样,无论是串口还是GPIO 都是先设定所需要的内容,然后使用HAL库最惯用的初始化操作)
在这里插入图片描述
P9 P10 一个连接的输入一个是输出 毕竟是不同的嘛
在这里插入图片描述

3.接下来是开启串口异步接收中断

因为我们的任务是通过串口接收或发送一个字符。就是因为我们整个任务会用到中断,来一个信息,我难道不应该打断我目前的所作所为,然后处理事件嘛,所以说这个中断使能,和设置是必须的。最后因为我们用到串口中断,所以还需要中断相关的配置。HAL_NVIC_EnableIRQ 函数使
能串口 1 复用通道。HAL_NVIC_SetPriority 函数配置串口中断的抢占优先级以及响应优先级。
串口初始化由上述两个函数完成。
在这里插入图片描述
HAL_Init() 函数设置的分组为2,抢占优先级和响应优先级都在0~3之间 各位都是2位所以是0到3 嘿嘿

4.配置一下串口异步接收中断

在这里插入图片描述
函数描述:用于开启以中断的方式接收指定字节。数据接收在中断处理函数里面实现。⚫ 函数形参:形参 1 是 UART_HandleTypeDef 结构体指针类型的串口句柄。形参 2 是要接收的数据地址。形参 3 是要接收的数据大小,以字节为单位。
HAL_UART_Receive_IT()
在这里插入图片描述

5.第五个步骤

编写中断服务函数
使用的是HAL_UART_IRQHandler 函数是 HAL 库中断处理公共函数
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);
形参 1 是 UART_HandleTypeDef 结构体指针类型的串口句柄。

我们来看带一般会调用HAL库内部的中断共用处理函数
HAL_UART_IRQHandler
调用了这个函数之后会清除中断标志位并开始调用callback函数
所以我们在这个部分之后重新添加一个使能中断的函数
在这里插入图片描述

6.接下来我们所需要做的是串口数据接收完成回调函数

重新定义一下callback函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
其实最开始先确定一下该函数整个操作用到的是串口几确认正确无误再开始后续的实现
按照实现方法需要定义两个一个是串口接收数据缓冲区 一个是数据标志

相关文章:

【【STM32-29正点原子版本串口发送传输实验】

STM32-29正点原子版本串口发送传输实验 通过串口接收或发送一个字符 例程目的 开发板上我们接入的是实现异步通信的UART接口 USB转串口原理图 我们一步步分析 PA9是串口1 的发送引脚 PA10是串口1 的接受引脚 。因为我们现在只是用到异步收发器功能,所以我们现…...

【面试题精讲】什么是websocket?如何与前端通信?

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 系列文章地址 什么是WebSocket? WebSocket是一种在Web应用程序中实现双向通信的协议。它允许在客户端和服务器之间建立持久…...

unity tolua热更新框架教程(2)

Lua启动流程 增加脚本luamain,继承luaclient 建立第一个场景GameMain,在对象GameMain挂载脚本LuaMain,启动场景 看到打印,lua被成功加载 lua入口及调用堆栈 这里会执行main.lua文件的main函数 C#接口导出 在此处配置C#导出的代码 …...

【0904作业】QT 完成登陆界面跳转到聊天室+完成学生管理系统的查找和删除功能

一、完成登陆界面跳转到聊天室 1> 项目结构 2> 源码 ① .pro ②main #include "mywnd.h" #include"chatCli.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MyWnd w;w.show();Form f;QObject::co…...

ceph源码阅读 buffer

ceph::buffer是ceph非常底层的实现&#xff0c;负责管理ceph的内存。ceph::buffer的设计较为复杂&#xff0c;但本身没有任何内容&#xff0c;主要包含buffer::list、buffer::ptr、buffer::hash。这三个类都定义在src/include/buffer.h和src/common/http://buffer.cc中。 buffe…...

基本介绍——数据挖掘

1.数据挖掘的定义 数据挖掘是采用数学的、统计的、人工智能和神经网络等领域的科学方法&#xff0c;如记忆推理、聚类分析、关联分析、决策树、神经网络、基因算法等技术&#xff0c;从大量数据中挖掘出隐含的、先前未知的、对决策有潜在价值的关系、模式和趋势&#xff0c;并…...

Navicat连接postgresql时出现‘datlastsysoid does not exist‘报错

当使用 Navicat 连接 PostgreSQL 数据库时出现 ‘datlastsysoid does not exist’ 的错误报错&#xff0c;这可能是由于 Navicat 版本与 PostgreSQL 版本不兼容所致。 这是因为在较新的 PostgreSQL 版本中移除了 ‘datlastsysoid’ 列&#xff0c;但可能较旧版本的 Navicat 尚…...

冯诺依曼体系结构/什么是OS?

一、体系结构图 示意图 控制器可以控制其它4个硬件&#xff0c;四个硬件直接可以进行数据传输。 5大硬件 但是这些个体需要用“线”连接。 为什么要有存储器&#xff1f; 如果没有&#xff0c;实际速度则为输入、输出设备的速度。 加上后&#xff0c;变为内存的速度。&#…...

SD卡/TF卡简记

文章目录 MicroSD卡与SD卡关系与区别对比NM卡、XQD卡、CFexpress卡SD规格标识FAQ拍摄1080p或2k视频需要什么速度的sd卡&#xff1f;拍摄4k视频需要什么速度的sd卡&#xff1f;拍摄8k视频需要什么速度的sd卡&#xff1f; MicroSD卡与SD卡关系与区别 MicroSD卡原名为Trans-flash…...

Dockerfile COPY的奇怪行为:自动解包一级目录

记录一下今天遇到的坑&#xff1a;Dockerfile 这两天在部署项目的时候&#xff0c;新加进去了一个驱动&#xff0c;需要将2个文件夹以及1个文件COPY进镜像&#xff0c;大刀阔斧一个Dockerfile就写完了&#xff0c;结果COPY进去的文件有问题&#xff0c;Dockerfile的内容如下&am…...

【每日一题Day311】LC1761一个图中连通三元组的最小度数 | 枚举

一个图中连通三元组的最小度数【LC1761】 给你一个无向图&#xff0c;整数 n 表示图中节点的数目&#xff0c;edges 数组表示图中的边&#xff0c;其中 edges[i] [ui, vi] &#xff0c;表示 ui 和 vi 之间有一条无向边。 一个 连通三元组 指的是 三个 节点组成的集合且这三个点…...

前端日期减一天的笑话

vue日期减一天 给大家讲一个真实的笑话。最近做的一个项目&#xff0c;要统计不同年月日期的关联交易数量&#xff0c;由于和银行内数据对接取得数据都是T-1的&#xff0c;所以在首页根据日期统计一些交易数据量时默认是统计昨日的数据量。所以当时和前端约定好的让前端的妹子做…...

高效能,一键批量剪辑,AI智剪让创作更轻松

在今天的数字化时代&#xff0c;视频制作已经成为各种行业和领域的必备技能。然而&#xff0c;视频剪辑过程往往繁琐且耗时&#xff0c;大大降低了我们的工作效率。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;我们有了新的解决方案——AI智剪软件。 AI智剪软件&am…...

手写Mybatis:第15章-返回Insert操作自增索引值

文章目录 一、目标&#xff1a;Insert自增索引值二、设计&#xff1a;Insert自增索引值三、实现&#xff1a;Insert自增索引值3.1 工程结构3.2 Insert自增索引值类图3.3 修改执行器3.3.1 修改执行器接口3.3.2 抽象执行器基类 3.4 键值生成器3.4.1 键值生成器接口3.4.2 不用键值…...

【数据结构】动态数组(vector)的基本操作,包括插入、删除、扩容、输出、释放内存等。以下是代码的解释和注释:

这段C代码实现了一个动态数组&#xff08;vector&#xff09;的基本操作&#xff0c;包括插入、删除、扩容、输出、释放内存等。以下是代码的解释和注释&#xff1a; // 引入标准输入输出库和标准库函数&#xff0c;用于后续的内存分配和打印输出等操作 #include <stdio.…...

[unity]三角形顶点顺序

序 详见官方文档&#xff1a;Unity - Manual: Mesh data (unity3d.com) Topology&#xff1a;拓扑结构 翻译&#xff1a; 拓扑描述网格具有的面类型。 网格的拓扑定义了索引缓冲区的结构&#xff0c;索引缓冲区又描述了顶点位置如何组合成面。每种类型的拓扑都使用索引数组中…...

【python爬虫】14.Scrapy框架讲解

文章目录 前言Scrapy是什么Scrapy的结构Scrapy的工作原理 Scrapy的用法明确目标与分析过程代码实现——创建项目代码实现——编辑爬虫代码实现——定义数据代码实操——设置代码实操——运行 复习 前言 前两关&#xff0c;我们学习了能提升爬虫速度的进阶知识——协程&#xf…...

功率放大器主要作用是什么呢

功率放大器是一种电子设备&#xff0c;主要作用是将输入信号的功率增加到更高的水平&#xff0c;以便能够驱动高功率负载。在许多应用中&#xff0c;信号源产生的信号往往具有较低的功率&#xff0c;无法直接满足一些要求较高的设备或系统的需求。而功率放大器则可以增强信号的…...

SpringBoot ApplicationEvent详解

ApplicationStartingEvent 阶段 LoggingApplicationListener#onApplicationStartingEvent 初始化日志工厂,LoggingSystemFactory接口&#xff0c;可以通过spring.factories进行定制 可以通过System.setProperty("org.springframework.boot.logging.LoggingSystem",&q…...

WebSocket 报java.io.IOException: 远程主机强迫关闭了一个现有的连接。

在客户端强制关闭时&#xff0c;或者窗口强制关闭时&#xff0c;后端session没有关闭。 有时还会报&#xff1a;java.io.EOFException: 这个异常 前端心跳没有收到信息&#xff0c;还在心跳。 CloseReason close new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, &…...

语法错误秒级定位,Perplexity查询调试实战手册,一线SRE团队内部流出!

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Perplexity语法查询功能概览 Perplexity 是一款面向开发者与数据分析师设计的轻量级语法感知型查询工具&#xff0c;其核心能力在于对结构化与半结构化文本&#xff08;如 SQL、JSON Schema、YAML 配置…...

手把手教你定制专属标注工具:基于Python3+Tkinter打造你的实体关系标注器

从零构建领域专用标注工具&#xff1a;Python3Tkinter实战指南 在自然语言处理项目中&#xff0c;高质量标注数据是模型效果的基石。当面对法律条文、医疗报告等专业领域时&#xff0c;通用标注工具往往难以满足特定实体关系和输出格式需求。本文将带你深入开发一个完全可控的实…...

Google I/O 2026 推出 Antigravity SDK:本地构建 AI Agent,灵活定制功能

Antigravity SDK 登场当开发者需要将 AI 能力嵌入自有应用时&#xff0c;常见做法是通过 API 调用远程 Agent 服务&#xff0c;但这种方式存在延迟高、定制性差、依赖网络等问题。据悉&#xff0c;Google 在 I/O 2026 大会上给出了另一种解法 ---- Antigravity SDK&#xff0c;…...

基于遗传算法的VRPTW问题求解:从元胞数组编码到多约束优化

1. 遗传算法与VRPTW问题初探 第一次接触带时间窗的车辆路径问题&#xff08;VRPTW&#xff09;时&#xff0c;我被它复杂的约束条件弄得头晕眼花。想象一下你是一家物流公司的调度员&#xff0c;手上有7辆载重不同的货车&#xff0c;需要给16个客户送货。每个客户都有特定的需求…...

Lawnicons入门教程:从下载安装到启用主题化图标的完整流程

Lawnicons入门教程&#xff1a;从下载安装到启用主题化图标的完整流程 【免费下载链接】lawnicons Monochrome outlined brand icons for Android launchers. 项目地址: https://gitcode.com/gh_mirrors/la/lawnicons Lawnicons是一款由Lawnchair团队开发并由社区支持的…...

OpenClaw 架构详解:AI Agent 的编排与执行骨架

核心定位&#xff1a;OpenClaw 自动化运行时&#xff08;Automation Runtime&#xff09;&#xff0c;一个给 AI 套上安全、可控、可审计缰绳的框架。 它不追求 AI 的"惊喜"&#xff0c;而是追求可预测性、可审计性和零故障。 文章目录一、设计哲学&#xff1a;网关…...

终极指南:如何在Windows 11上轻松安装Android应用?APK Installer完整教程

终极指南&#xff1a;如何在Windows 11上轻松安装Android应用&#xff1f;APK Installer完整教程 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经想在Window…...

终极LevelDB GUI管理工具:LevelUI完整使用指南

终极LevelDB GUI管理工具&#xff1a;LevelUI完整使用指南 【免费下载链接】levelui A GUI for LevelDB management based on atom-shell. 项目地址: https://gitcode.com/gh_mirrors/le/levelui LevelDB作为高性能键值存储数据库&#xff0c;在Node.js生态中应用广泛&a…...

首次使用Taotoken从注册到发出第一个API请求的全流程指南

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 首次使用Taotoken从注册到发出第一个API请求的全流程指南 对于初次接触大模型API的开发者来说&#xff0c;从注册平台到成功发出第…...

Nginx、Tengine、OpenRestry的http和tcp后端健康检查【20260520-005篇】

文章目录 ✅ 一、核心能力概览(按产品维度) ✅ 二、HTTP 健康检查配置示例(三者对比) ▪️ Nginx(被动式,基础可靠) ▪️ Tengine(主动式,开箱即用) ▪️ OpenResty(Lua 主动式,高度可控) ✅ 三、TCP 健康检查配置示例 ▪️ Tengine(最简洁) ▪️ OpenResty(TC…...