STM32-串口通信(串口的接收和发送)

文章目录

  • STM32的串口通信
  • 一、STM32里的串口通信
  • 二、串口的发送和接收
    • 串口发送
    • 串口接收
  • 三、串口在STM32中的配置
  • 四、串口接收的两种实现方式
    • 1. 需要更改的地方
    • 2. 查询RXNE标志位
    • 3. 使用中断
  • 总结


STM32的串口通信

本文在于记录自己的学习过程中遇到的问题和总结,各种情况下串口通信在STM32的实际使用方面占有很大的比重,本文主要对串口通信做一个简要的总结。


一、STM32里的串口通信

在STM32里,串口通信是USART,STM32可以通过串口和其他设备进行传输并行数据,是全双工异步时钟控制,设备之间是点对点的传输。对应的STM32引脚分别是RX和TX端。STM32的串口资源有USART1、USART2、USART3.

串口的几个重要的参数:

  • 波特率,串口通信的速率
  • 空闲,一般为高电平
  • 起始位,标志一个数据帧的开始,固定为低电平。当数据开始发送时,产生一个下降沿。(空闲–>起始位)
  • 数据位,发送数据帧,1为高电平,0为低电平。低位先行。
    比如 发送数据帧0x0F 在数据帧里就是低位线性 即 1111 0000
  • 校验位,用于数据验证,根据数据位的计算得来。有奇校验,偶校验和无校验。
  • 停止位,用于数据的间隔,固定为高电平。数据帧发送完成后,产生一个上升沿。(数据传输–>停止位)

下方就是一个字节数据的传输过程,从图中可以看出,串口发送的数据一般都是以数据帧的形式进行传输,每个数据帧都由起始位,数据位,停止位组成, 且停止位可变。
在这里插入图片描述


二、串口的发送和接收

USART是STM32内部集成的硬件外设,可以根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可以自动接收RX引脚的数据帧时序,拼接成一个字节数据,存放在数据寄存器里。

当配置好USART的电路之后,直接读取数据寄存器,就可以自动发送数据和接收数据了。在发送和接收的模块有4个重要的寄存器

  • 发送数据寄存器TDR
  • 发送移位寄存器,把一个字节的数据一位一位的移出去
  • 接收数据寄存器RDR
  • 接收移位寄存器,把一个字节的数据

下方为串口的发送和接收图解:

在这里插入图片描述


串口发送

在配置串口的各个参数时,可以选择发送数据帧的数据位的大小,可选8位或9位。

串口发送数据实际上就是对发送数据寄存器TDR进行写操作

1. 当串口发送数据时,会检测发送移位寄存器是不是有数据正在移位,如果没有移位,那么这个数据就会立刻转移到发送移位寄存器里。准备发送。

2. 当数据移动到移位寄存器时,会产生一个TXE发送寄存器空标志位,该位描述如下。当TXE被置1,那么就可以在TDR写入下一个数据了。即发送下一个数据。

在这里插入图片描述

3. 发送移位寄存器在发送器控制的控制下,向右移位,一位一位的把数据传输到TX引脚。
在这里插入图片描述

4. 数据移位完成后,新的数据就会再次从TDR转移到发送移位寄存器里来,依次重复1-3的过程。通过读取TXE标志位来判断是否发送下一个数据。


串口接收

  1. 数据从RX引脚通向接收移位寄存器,在接收控制的控制下,一位一位的读取RX的电平,把第一位放在最高位,然后右移,移位八次之后就可以接收一个字节了。
  2. 当一个字节数据移位完成之后,这一个字节的数据就会整体的移到接收数据寄存器RDR里来。
  3. 在转移时会置RXNE接收标志位,即RDR寄存器非空,下方为该位的描述。当被置1后,就说明数据可以被读出
    在这里插入图片描述
    下图即为串口接收的工作流程

在这里插入图片描述


三、串口在STM32中的配置

首先要明确几点:使用STM32串口外设中的哪一个?串口发送或者接收数据?串口相关的参数配置?发送或接收是否使用到中断?

下方为串口发送的配置。

1. RCC开启USART、串口TX/RX所对应的GPIO口

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);  //开启USART2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   //开启GPIOA的时钟

2. 初始化GPIO口
这里注意哈,根据自己的需求来配置GPIO口,发送和接收是都需要还是只需要其中一个。然后对应的根据引脚定义表来初始化对应的GPIO口。

USART2对应的引脚
在这里插入图片描述

USART1对应的引脚
在这里插入图片描述

这里根据手册来看,RX引脚模式配置成浮空输入或者上拉输入。TX引脚模式配置成复用推挽输出。

**比如我这里只初始化TX发送端**
//TX端GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;  //复用推挽输出GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;   //USART2对应的TX端为GPIOA2GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  //50MhZGPIO_Init(GPIOA,&GPIO_InitStructure);

3. 串口初始化
注意哈,USART_Init()这个函数,是用来配置串口的相关参数的。

  • USART_BaudRate 串口通信使用的波特率 一般是9600或者是115200,这里我们给9600
  • USART_HardwareFlowControl 是否选择硬件流触发,一般这个我们也不选,所以选择无硬件流触发。
  • USART_Mode 这个参数要注意了哈,串口的模式,发送模式还是接收模式,还是两者都有
  • USART_Parity 校验位,可以选择奇偶校验和不校验。没有需求就直接无校验
  • USART_StopBits 停止位 有1、0.5、2位,我们这里选1位停止位
  • USART_WordLength 数据位 有8位和9位可以选择
 //串口初始化USART_InitTypeDef USART_InitStruct;USART_StructInit(&USART_InitStruct);  //初始默认值USART_InitStruct.USART_BaudRate=9600;USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;   //不使用硬件流触发USART_InitStruct.USART_Mode=USART_Mode_Tx;   			//TX 发送模式USART_InitStruct.USART_Parity=USART_Parity_No;   		//不选择校验USART_InitStruct.USART_StopBits=USART_StopBits_1;  		//停止位1位USART_InitStruct.USART_WordLength=USART_WordLength_8b;	//数据位8位USART_Init(USART2,&USART_InitStruct);

4. 串口使能

//串口使能USART_Cmd(USART2,ENABLE);

5. 串口发送数据
注意哈,我们要判断TXE标志位的状态。0,数据还没有被转移到移位寄存器;1,数据已经被转移到移位寄存器。当TXE标志位为1时,就说明可以发送下一个数据了。详细过程可看上面串口发送的解释。

void Serial_SendByte(uint16_t Byte)
{USART_SendData(USART2,Byte);//0 表示数据还未转移到移位寄存器 循环等待 1 数据已经被转移到了移位寄存器可以发送数据while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);  //不需要手动清零 再次写入TDR时会自动清零	
}

经过上述五步的配置,单片机就可以通过串口发送数据了。

下方为发送数据图例,STM32向串口发送0x16数据
在这里插入图片描述


四、串口接收的两种实现方式

上方是发送数据的例子,那么串口接收又该如何配置,又要在串口发送的例子上做哪些更改呢?

这里我们可以通过查询或者中断的方式来进行接收数据的两种方式。

  • 查询方式就是通过不断的查询RXNE标志位,通过判断RXNE位的状态来确定数据是否接收。
  • 中断方式就是通过配置接收输出控制通道,配置NVIC,在中断服务子函数里进行数据的接收。

1. 需要更改的地方

既然我们要实现串口的接收,那么就要配置串口RX引脚,在串口模式中添加USART_Mode_RX模式。

  • 初始化RX引脚
//RX端GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  //上拉输入GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;  //50MhZGPIO_Init(GPIOA,&GPIO_InitStructure);
  • 添加串口模式
USART_InitStruct.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;   			//TX 发送模式  RX 接收模式

2. 查询RXNE标志位

这里我们还是来看一看RXNE标志位的描述

在这里插入图片描述
上图描述,为0时数据没有收到,为1时收到了数据,数据可以从RDR里读出

所以在主程序里不断读取RXNE标志位,如果为1,表示数据可以读出

uint8_t RX_Data;
int main()
{ Serial_Init();Serial_SendByte(0x16);while(1){if(USART_GetFlagStatus(USART2,USART_FLAG_RXNE)==SET)   //0 循环等待 1 可以接收数据{RX_Data=USART_ReceiveData(USART2);           Serial_SendByte(RX_Data);}}
}

下图为程序现象:pc向单片机发送数据0x15,单片机接收数据0x15,并且把接收到的数据作为数据发送到pc,在pc上显示0x15。
在这里插入图片描述

3. 使用中断

  • 通过配置串口的接收作为中断源,开启中断输出控制,配置NVIC。开启中断通道。
//开启中断输出控制USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStruct;NVIC_InitStruct.NVIC_IRQChannel=USART2_IRQn;   //选择USART2的中断通道NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;		//中断使能NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStruct);
  • 中断服务子函数
    中断服务子函数写好后,就可以在中断里读取接收到的数据了。
    当接收到数据后,触发接收中断,主程序暂停执行。接收完数据后主程序回复执行。当接收到数据时,就触发中断。
void USART2_IRQHandler(void)
{if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)   //RXNE 标志位为1 表示可以接收数据{RX_Data=USART_ReceiveData(USART2);Flag=1;USART_ClearITPendingBit(USART2,USART_IT_RXNE);  //清除RXNE标志位}
}
  • 主程序测试
uint8_t RX_Data;
uint8_t Flag;int main()
{Serial_Init();Serial_SendByte(0x16);while(1){if(Flag==1){Serial_SendByte(RX_Data);}}
}void USART2_IRQHandler(void)
{if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)   //RXNE 标志位为1 表示可以接收数据{RX_Data=USART_ReceiveData(USART2);Flag=1;USART_ClearITPendingBit(USART2,USART_IT_RXNE);  //清除RXNE标志位}
}

下图为程序现象:可以看到,串口确实收到了数据,只是我把接收到的数据0xFE放在了while循环里,这说明数据接收是成功的,使用中断是可行的。
在这里插入图片描述


总结

到这里,就大致总结了串口的发送和接收。

串口的配置,使用查询或者中断来接收数据。

串口的使用会很常用到,所以在这里对串口做一个总结,也算是对之前知识的一个回顾和总结,加强印象。

如果有什么写的不对的地方,欢迎指正!

加油加油!

听不懂就多看两遍,认真听,慢慢琢磨,多看几遍,一定可以学会!

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

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

相关文章

golang,gin脚手架,完美集成与结构化,gin-restful-api模板gin-layout,开箱即用

关于gtools golang非常奈斯,gin作为web框架也非常奈斯,但我们在开发过程中,前期搭建会花费大量的时间,且还不尽人意。 为此我集成了gin-restful-api的模板gin-layout,还有脚手架一键生成项目。 集成相关 ginviperz…

大型语言模型的语义搜索(一):关键词搜索

关键词搜索(Keyword Search)是文本搜索种一种常用的技术,很多知名的应用app比如Spotify、YouTube 或 Google map等都会使用关键词搜索的算法来实现用户的搜索任务,关键词搜索是构建搜索系统最常用的方法,最常用的搜索算法是Okapi BM25&#x…

Liunx使用nginx和http搭建yum-server仓库

文章目录 1. yum-server的搭建方式2. nginx搭建yum-server仓库2.1. 安装配置nginx2.2 配置yum-server的rpm2.3. 同步yum源相关包2.3.1 rsync同步源3.3.1 reposync同步源 2.4. 配置客户端访问yum配置2.5. 验证测试 3. http服务搭建yum-server仓库3.1. 安装配置http3.2 配置yum-s…

基于微信小程序校园洗衣系统设计与实现(PHP后台)可行性分析

博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

Firewalld防火墙

Firewalld概述 Firewalld firewalld防火墙是centos7系统默认防火墙的防火墙管理工具,取代了之前的iptables防火墙,也是工作在网络层,属于包过滤防火墙。 支持网络区域所定义的网络链接以及接口安全等级的动态防火墙管理工具至此IPv4、IPv6…

ECMAScript modules规范示例详解

ECMAScript modules(简称 ES modules)是JavaScript的标准模块系统。每个模块都是一个独立的JavaScript文件,可以在其中定义导出的变量、函数或类,并从其他模块中导入这些变量、函数或类。以下是ES modules规范的一些示例和详解&am…

Go 线程池实现案例

Go 语言并不像其他一些语言(例如 Java 或 C#)那样直接提供一个线程池的概念。相反,Go 使用 goroutines 来实现并发,它是一种比线程更轻量级的并发执行单元。不过,仍然可以实现一个类似线程池的结构,来管理和…

studio one 6正版多少钱?怎么购买studio one 更便宜,有优惠券哦

Presonus Studio One Studio One是由美国PreSonus公司开发的数字音频工作站,作为DAW届的新人,功能强大且全面,虽然它不像其他DAW那样拥有历史和声誉,但它是一个可爱的软件,包含许多其它DAW所不具备的实用功能&#xff…

web基础及http协议 (二)----------Apache相关配置与优化

一、httpd 安装组成 http 服务基于 C/S 结构 1 .常见http 服务器程序 httpd apache,存在C10K(10K connections)问题 nginx 解决C10K问题lighttpd IIS .asp 应用程序服务器 tomcat .jsp 应用程序服务器 jetty 开源的servlet容器&#xf…

选择 Python IDE(VSCode、Spyder、Visual Studio 2022和 PyCharm)

前言 当选择 Python 开发工具时,你需要考虑自己的需求、偏好和项目类型。下面是对VSCode、Spyder、Visual Studio 2022和 PyCharm的对比推荐总结: 结论 1、如果你专注于“数据科学”,选择SpyDer没错。 内容 Visual Studio Code (VS Code)…

react项目中的redux以及react-router-dom

扫盲知识点&#xff1a; 1 传递自定义事件&#xff1a; <button onClick{(e)>{change(e)}}>获取事件对象e</button> 将事件对象e传递到了change的这个方法中。 2 同时传递自定义事件和参数&#xff1a; <button onClick{(e)>{change(‘我…

基于微信小程序失物招领系统设计与实现(PHP后台+Mysql)可行性分析

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

CleanMyMac2024苹果电脑清理工具最新使用全面评价

作为软件评价专家&#xff0c;我对CleanMyMac X进行了全面的评估&#xff0c;以下是我的详细评价&#xff1a; CleanMyMac X4.14.6全新版下载如下: https://wm.makeding.com/iclk/?zoneid49983 一、功能 CleanMyMac X的功能相当全面&#xff0c;几乎涵盖了Mac电脑清理所需的…

nginx 具体介绍

一&#xff0c;nginx 介绍 &#xff08;一&#xff09;nginx 与apache 1&#xff0c; Apache event 模型 相对于 prefork 模式 可以同时处理更多的请求 相对于 worker 模式 解决了keepalive场景下&#xff0c;长期被占用的线程的资源浪费问题 因为有监听线程&#…

【数据结构】链式队列

链式队列实现&#xff1a; 1.创建一个空队列 2.尾插法入队 3.头删法出队 4.遍历队列 一、main函数 #include <stdio.h> #include "./3.linkqueue.h" int main(int…

文档控件DevExpress Office File API v23.2新版亮点 - 支持SVG

DevExpress Office File API是一个专为C#, VB.NET 和 ASP.NET等开发人员提供的非可视化.NET库。有了这个库&#xff0c;不用安装Microsoft Office&#xff0c;就可以完全自动处理Excel、Word等文档。开发人员使用一个非常易于操作的API就可以生成XLS, XLSx, DOC, DOCx, RTF, CS…

数据结构之单链表的操作

main函数 #include <stdio.h> #include "./03_linkList.h" int main(int argc, const char *argv[]) { linkList* head creatr_linkList(); insertHead_linkL…

运维SRE-19 网站Web中间件服务-http-nginx

Ans自动化流程 1.网站集群核心协议&#xff1a;HTTP 1.1概述 web服务&#xff1a;网站服务&#xff0c;网站协议即可. 协议&#xff1a;http协议,https协议 服务&#xff1a;Nginx服务&#xff0c;Tengine服务....1.2 HTTP协议 http超文本传输协议&#xff0c;负责数据在网站…

更高效的构建工具-vite

更高效的构建工具-vite 前言Vite是什么Vite和webpack的比较1. 运行原理2. 使用成本 Vite的初体验 前言 首先我们要认识什么时构建工具&#xff1f; 企业级项目都具备什么功能呢&#xff1f; Typescript&#xff1a;如果遇到ts文件&#xff0c;我们需要使用tsc将typescript代码…

Android约束布局中用ConstraintHelper实现过渡动画效果

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂&#xff0c;风趣幽默"&#xff0c;感觉非常有意思,忍不住分享一下给大家。 &#x1f449;点击跳转到教程 一.创建一个类CircularRevealHelper继承ConstraintHelper代码如下 /*** Author: ly* Da…