STM32---串口通信USART

目录

一、串口通信协议        

二、USART模块介绍

(1)移位寄存器

(2)控制电路

(3)波特率

(4)C语言接口

三、串口的引脚初始化

(1)引脚分布表

(2)重映射表

(3)GPIO配置表

(4)C语言接口使用

四、标志位的使用

(1)读写标志位

(2)错误标志位

五、发送数据代码

六、接收数据代码


一、串口通信协议        

        在学习网络通信的时候,我们曾认识到两台主机想要进行通信,必须要有协议的存在,否则对方根本不知道你说了啥,因为在网络中没有信息的概念,只有二进制电平信号。如果不规定协议,对方的操作系统就不知道如何解析该二进制信号。于是演变出来OSI的7层模型,每一层都相当于一层协议,对数据包进行封装,从而让对方的同层协议可以解析提取真正想要的数据。

        那么我们STM32单片机自然也可以认为属于网络协议中的物理层协议。因为他并没有经过交换机路由器等设备,仅仅只是把两台主机直连,所以他并不可能在数据链路层、或者网络层。但是也有人认为他属于数据链路层,以为他有数据帧封装,尽管这个封装十分简单。而且他没有mac地址其实是因为他没有负责的连接环境,但是本质上他这个简单的协议是可以做到传输mac地址的。其实这种理解也是有道理的,因为规定上物理层没有任何协议存在,是单纯的数据流传输。

        真实的物理连接图:

        正是因为它属于物理层协议,那么可以预见的是他的协议必然很简单。我们来看看他的协议格式:

        它的协议格式非常简单,由一位低电平起始位+7-8位数据位+(一位校验位)+一位高电平停止位组成。

        其中这里的数据位为7-8位是可以选择的,不过我们一般都是要传递一个字节,所以一般情况下只会选择8位数据位,至于校验位,如果你的精确度要求高可以选择,通常来说并无较大差异。

二、USART模块介绍

        在结构图中可以看到UART有三个,APB1和APB2线上都存在。可以根据你对时钟频率的不同选取。

(1)移位寄存器

        在这幅图中有两个移位寄存器,他的作用就是接收和发送数据。

        当我们想要发送数据的时候,就把值填入发送寄存器。之后该模块会自动把该寄存器的数据在时钟的频率下,一位位得把数据的二进制流交给控制电路。

        反过来,接收数据的时候,是先交给到了控制电路,控制电路对接收到的数据帧,进行解包(去除起始位、停止位、并检验校验位是否正确),把数据取出交给接收寄存器,然后由该寄存器把数据向上传递即可。

        在这个过程中两个寄存器的作用主要是串转并、并转串。因为在物理线路中的传递都是二进制流的串行数据,而用户想看到的则是8位一起的并行数据。

(2)控制电路

        控制电路主要就是进行封包和解包分用的。在这里可以通过配置寄存器来决定数据包的格式:数据位是7位还是8位?有没有校验位?、停止位是多少个时钟周期的高电平?

(3)波特率

        波特率指的是一分钟的时间,比特位传输的数量。比如你的串口选择的波特率是9600,那么他一分钟能传递的比特位就是9600个,即9600/8=1200个字节。大多数情况下波特率都会被配置成9600、115200、921600,这个和时钟的频率有关,尽可能选择可以由时钟频率直接分频得到的,精确度较高。

        在这幅图中,波特率是由时钟经过波特率寄存器BRR和一个16分频的分频器得到的。因为STM32的时钟频率往往是36、72MHz比较大,经过这些分频降低频率更好用。不过如果你对数据的传输时间限制很短,可以尝试较高的频率。

(4)C语言接口

在库函数中可以找到一个USART_Init,他就是用来配置UART(上述)模块的函数。可以在这里设置波特率、数据位长度、校验方式、接收还是发送数据等。

当然还需要一个时钟总开关使能

USART_Cmd(USART1,ENABLE);//使能USART模块

三、串口的引脚初始化

        我们在上面已经了解了UART模块的配置方法。那么既然要向外传输数据,必然会有引脚暴露出来供我们使用,那么他们是谁呢?

        USART的引脚有这5个,其中Tx和Rx最为熟悉,是用来传输数据的。而硬件流控我们暂时并不会涉及到,也不过多讲解。同步模式的时钟线,则是如果你想让两个STM32单片机进行数据交流,则可以用这个时钟线把两台主机连接到一起,让他们都遵循一个时钟,在该时钟的指导下进行串口通信,保证数据的准确性。

(1)引脚分布表

在数据手册中有这样两幅图,他们表示了当前芯片的封装情况、重映射情况。

由于他比较多,我直接把和UASRT相关的引脚内容挑出来看,所以知道了我们在不使用重映射的情况下USART的输入输出引脚是接在PA9和PA10上面的。如果你就想使用默认情况,则直接配置PA9和PA10两个引脚即可。

当然,在重映射后他们的位置则变为了PB6和PB7。注意你如果把他们配置成了USART的引脚,则原本的GPIO功能是无法使用的。

(2)重映射表

在上面直接看引脚分布表比较麻烦,可以直接到使用手册中查看。内容是一样的。

(3)GPIO配置表

        我们已经找到了其引脚,配置成什么模式呢?

在使用手册中同样有一个表格,明确说明了各种外设在使用GPIO的时候,应当被配置为什么模式。

在这里我们看到全双工模式下,Tx要配置成推挽复用输出、Rx要配置成上拉输入。

        复用推挽输出和通用推挽输出的区别就是:一个是由CPU直接控制引脚的电平高低,另一个把引脚电平的控制权交给外设模块自己操作,更加方便。

(4)C语言接口使用

默认情况:

重映射情况:

四、标志位的使用

        在USART的框图中我们曾有一部分没有讲解,就是右上角的标志位。通过读取标志位,可以让我们时刻检查到USART模块的运行情况。

(1)读写标志位

TxE:检查能否填入数据到发送寄存器

TC:检查档次发送过程是否结束

RxNE:

(2)错误标志位

        我们在通过USART协议传输数据的时候,难免会出现某些原因,使得数据的发送端和接收端并不一致,我们就认为他出错了。虽然USART的控制电路会自动检测错误,但是我们上层应用要想知道仍需要查看这些标志位来获取状态。

        错误标志位是一个协议中非常重要的存在。通过检验错误标志位,你可以对不同的错误做出不同的处理,比如:如果接受数据错误,你可以选择向对端发送消息,告诉他你的数据错了,请重新发。有没有回想到我们之前学习TCP也是这样的!

PE:

FE:

比如没有接收到停止位,就是一种帧格式错误。

NE:

我们实际在接受一个USART协议的信号的时候,会在一个时钟周期内多次检测,看看每次检测的结果是不是一样的,如果不一样则表示有噪音,该数据不可信。

ORE:

当接受寄存器中有数据没有被上层应用取走,他会停留在原地(字节1),如果有数据又来了,他就保存在了接收端的移位寄存器(字节2),此时仍然没有问题。但是如果继续来了数据(字节3),他就会覆盖掉移位寄存器中的字节2,此时控制电路就会监测到该情况,并把ORE置1。

五、发送数据代码

向发送寄存器写入数据的函数

对上述代码进行封装:

void Init_USART()
{//USART配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate=115200;USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_WordLength=USART_WordLength_8b;USART_InitStruct.USART_Parity=USART_Parity_No;USART_InitStruct.USART_StopBits=USART_StopBits_1;USART_Init(USART1,&USART_InitStruct);//GPIO配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//使能USARTUSART_Cmd(USART1,ENABLE);}void My_USART_SendBytes(USART_TypeDef* USARTx,uint8_t* pData,uint16_t Number)
{for(uint16_t i=0;i<Number;i++){//不为空的时候就在while循环中出不来while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//走到这说明发送寄存器为空了USART_SendData(USARTx,pData[i]);//如果移位寄存器没有清空,就不退出这个函数while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}
}int main(void)
{Init_USART();uint8_t datas[]={10,50,90,100,66};while(1){My_USART_SendBytes(USART1,datas,5);}
}

如果你上述步骤都正确的话你是可以成功的通过STM32单片机向电脑主机发送消息的。结果如下:

六、接收数据代码

具体使用如下:

示例代码:

void Init_USART()
{//USART配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);USART_InitTypeDef USART_InitStruct;USART_InitStruct.USART_BaudRate=115200;USART_InitStruct.USART_Mode=USART_Mode_Tx | USART_Mode_Rx;USART_InitStruct.USART_WordLength=USART_WordLength_8b;USART_InitStruct.USART_Parity=USART_Parity_No;USART_InitStruct.USART_StopBits=USART_StopBits_1;USART_Init(USART1,&USART_InitStruct);//GPIO配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);//使能USARTUSART_Cmd(USART1,ENABLE);}void My_USART_SendBytes(USART_TypeDef* USARTx,uint8_t* pData,uint16_t Number)
{for(uint16_t i=0;i<Number;i++){//不为空的时候就在while循环中出不来while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//走到这说明发送寄存器为空了USART_SendData(USARTx,pData[i]);//如果移位寄存器没有清空,就不退出这个函数while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);}
}void My_Led_Init(void)
{//GPIO配置RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_OD;GPIO_InitStruct.GPIO_Pin=GPIO_Pin_13;GPIO_InitStruct.GPIO_Speed=GPIO_Speed_2MHz;GPIO_Init(GPIOC,&GPIO_InitStruct);//初始设置为灭,即GPIOC_Pin_13为高电平GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);
}int main(void)
{My_Led_Init();Init_USART();uint8_t datas[]={10,50,90,100,66};while(1){// My_USART_SendBytes(USART1,datas,5);//接收数据,并处理while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);uint8_t byteEecv=USART_ReceiveData(USART1);//处理//0灭if(byteEecv==0){GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET);}//1亮else if(byteEecv==1){GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_RESET);}}}

如果你的操作正确,则可以看到用串口控制芯片上的LED了。

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

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

相关文章

流程架构是什么?为什么要构建流程架构,以及如何构建流程结构?

本文从&#xff1a;流程架构是什么&#xff1f;为什么要构建流程架构&#xff1f;如何构建流程结构三个方面来介绍。 一、首先&#xff0c;我们来了解流程架构是什么&#xff1f; 流程架构是人体的骨架&#xff0c;是大楼的砌筑&#xff0c;是课本的目录&#xff0c;是流程管理…

网络结构及安全科普

文章目录 终端联网网络硬件基础网络协议示例&#xff1a;用户访问网页 OSI七层模型网络攻击&#xff08;Hack&#xff09;网络攻击的主要类别&#xff08;一&#xff09;按攻击目标分类&#xff08;二&#xff09;按攻击技术分类 网络安全防御 典型攻击案例相关名词介绍网络连接…

同z科技面经

同z科技-2025-4-23 1.自我介绍 个人信息 校园经历 实习经历 项目经历 个人技能掌握 目前学习技术 2.封装缓存工具类怎么封装的 先介绍使用缓存的问题 解决的逻辑 封装的逻辑 应用 缓存穿透&#xff1a; 缓存雪崩&#xff1a; 缓存击穿&#xff1a; https://www…

基于LoRA的Llama 2二次预训练实践:高效低成本的大模型领域适配

引言 近年来&#xff0c;大语言模型&#xff08;LLM&#xff09;如Meta的Llama 2系列凭借其强大的生成和理解能力成为NLP领域的核心工具。然而&#xff0c;直接将通用预训练模型应用于垂直领域&#xff08;如医疗、法律、金融&#xff09;时&#xff0c;常面临领域知识不足的问…

Python爬虫(2)Python爬虫入门:从HTTP协议解析到豆瓣电影数据抓取实战

目录 一、背景与需求‌二、 Web基础与HTTP协议核心解析‌2.1 HTTP协议&#xff1a;数据交互的基石‌2.2 为何爬虫需理解HTTP协议&#xff1f;‌ 三、 Python爬虫实战&#xff1a;Requests库核心用法‌3.1 安装与环境配置‌3.2 案例1&#xff1a;GET请求抓取豆瓣电影Top250‌3.3…

深度学习--ResNet残差神经网络解析

文章目录 前言一、什么是ResNet网络二、传统卷积神经网络存在的问题1、梯度消失和梯度爆炸2、退化问题 三、如何解决问题四、残差结构五、18层残差网络1、解释2、隔层相加优点3、隔层相加数值增大问题 六、18层残差网络以外的表格示例七、BN层&#xff08;Batch Normalization&…

【go】go run-gcflags常用参数归纳,go逃逸分析执行语句,go返回局部变量指针是安全的

go官方参考文档&#xff1a; https://pkg.go.dev/cmd/compile 基本语法 go run 命令用来编译并运行Go程序&#xff0c;-gcflags 后面可以跟一系列的编译选项&#xff0c;多个选项之间用空格分隔。基本语法如下&#xff1a; go run -gcflags "<flags>" main.…

K8S探针的应用

目录&#xff1a; 1、探针的简介2、启用探针2.1、启用就绪探针2.2、启用存活探针2.3、启用启动探针&#xff08;可选&#xff09; 1、探针的简介 在Kubernetes中&#xff0c;探针&#xff08;Probes&#xff09;是用来检查容器健康状况的工具&#xff0c;它们帮助Kubernetes了…

体积小巧的 Word 转 PDF 批量工具

软件介绍 今天给大家介绍一款能批量把 Word 文档转换成 PDF 的实用小工具。 软件特点 这款 Word 批量转 PDF 软件&#xff0c;身材小巧&#xff0c;体积不到 1M&#xff0c;还没界面呢&#xff01;使用时&#xff0c;只要把软件和要转换的 Word 文档放在一个文件夹&#xff…

JMeter介绍

文章目录 1. JMeter简介2. JMeter 下载3. JMeter修改编码集4. 启动并运行JMeter 1. JMeter简介 JMeter 是 Apache 组织使用 Java 开发的一款测试工具&#xff1a; 1、可以用于对服务器、网络或对象模拟巨大的负载 2、通过创建带有断言的脚本来验证程序是否能返回期望的结果 优…

URP-UGUI相关知识

一、UGUI的基本组成部分 Canvas &#xff08;画布&#xff09;所有UI都需要放在Canvas画布下面&#xff0c;不然无法显示EventSystem 所有的事件响应系统都需要依赖于EventSystem,若删除该组件&#xff0c;交互效果就 不会显示 1.Canvas(画…

ShenNiusModularity项目源码学习(20:ShenNius.Admin.Mvc项目分析-5)

ShenNiusModularity项目的系统管理模块主要用于配置系统的用户、角色、权限、基础数据等信息&#xff0c;上篇文章中学习的日志列表页面相对独立&#xff0c;而后面几个页面之间存在依赖关系&#xff0c;如角色页面依赖菜单页面定义菜单列表以便配置角色的权限&#xff0c;用户…

JavaFX 实战:从零打造一个功能丰富的英文“刽子手”(Hangman)游戏

大家好&#xff01;今天我们要挑战一个经典的单词猜谜游戏——“刽子手”&#xff08;Hangman&#xff09;&#xff0c;并使用 JavaFX 这个强大的 GUI 工具包来赋予它现代化的交互体验。这个项目不仅有趣&#xff0c;而且是学习和实践 JavaFX 核心概念的绝佳途径&#xff0c;涵…

【自我介绍前端界面分享】附源码

我用夸克网盘分享了「800套HTML模板」&#xff0c;链接&#xff1a;https://pan.quark.cn/s/a205a794552c <!DOCTYPE HTML> <html> <head> <title>Miniport</title> <meta http-equiv"content-type" content&q…

安宝特分享|AR智能装备赋能企业效率跃升

AR装备开启智能培训新时代 在智能制造与数字化转型浪潮下&#xff0c;传统培训体系正面临深度重构。安宝特基于工业级AR智能终端打造的培训系统&#xff0c;可助力企业构建智慧培训新生态。 AR技术在不同领域的助力 01远程指导方面 相较于传统视频教学的单向输出模式&#x…

今日html笔记

原手写笔记 ------------------------------------------------------------------------------------------------------- 关于超链接的使用 <a href"https://www.luogu.com.cn/" target"_blank">//href属性指定了超链接的目标地址,即当用户点击超…

【人工智能】Ollama 负载均衡革命:多用户大模型服务的高效调度与优化

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在 多用户大模型推理 场景下,负载均衡 是确保高并发、低延迟的关键挑战。本文以 Ollama(一个流行的本地大模型运行框架)为例,深入探讨 …

线上救急-AWS限频

线上救急-AWS限频 问题 在一个天气炎热的下午&#xff0c;我正喝着可口可乐&#xff0c;悠闲地看着Cursor生成代码&#xff0c;忽然各大群聊中出现了加急➕全体的消息&#xff0c;当时就心里一咯噔&#xff0c;点开一看&#xff0c;果然&#xff0c;线上服务出问题&#xff0…

Maven 项目中引入本地 JAR 包

在日常开发过程中&#xff0c;我们有时会遇到一些未上传到 Maven 中央仓库或公司私有仓库的 JAR 包&#xff0c;比如第三方提供的 SDK 或自己编译的库。这时候&#xff0c;我们就需要将这些 JAR 包手动引入到 Maven 项目中。本文将介绍两种常见方式&#xff1a;将 JAR 安装到本…

解锁webpack:对html、css、js及图片资源的抽离打包处理

面试被问到webpack&#xff0c;可别只知道说 HtmlWebpackPlugin 了哇。 前期准备 安装依赖 npm init -y npm install webpack webpack-cli --save-dev配置打包命令 // package.json {"scripts": {// ... 其他配置信息"build": "webpack --mode pr…