MCU常见通信总线串讲(一)—— UART和USART

news2024/9/30 15:22:02

🙌秋名山码民的主页
😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
获取源码,添加WX

目录

  • 前言
  • 一、简介
  • 二、帧格式
  • 三、硬件连接
  • 四、工作模式
  • 五、使用流程
  • 最后


前言

首先明确一个概念,关于MCU中通信总线和通信协议,通信总线是一种用于连接各种外设和模块的物理接口,它可以传输数据和控制信息。通信协议则是指在通信总线上传输数据时所遵循的规则和约定,以确保不同设备之间能够正确地交换信息,我们也可以把他叫做通信总线协议。

系列文章,主要讲解以下几个总线协议,读者可以按需选择:

  1. UART和USART
  2. RS232、RS485总线
  3. IIC总线
  4. SPI总线
  5. CAN总线
  6. USB总线

一、简介

UART:Universal Asynchronous Receiver/Transmitter,通用异步收发器。
USART:Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步/异步串行接收/发送器。

UART是一种通用的异步串行通信协议,它使用起始位、数据位、校验位和停止位来传输数据。在UART通信中,数据的传输是通过固定的波特率进行的,发送和接收端需要事先约定好波特率、数据位、校验位和停止位等参数。UART通常用于连接微控制器、传感器、外围设备等,并且在计算机系统中也广泛应用于串口通信。

USART是一种更为复杂的串行通信协议,它同时支持同步和异步的数据传输方式。与UART不同的是,USART可以选择同步或者异步模式进行通信,并且提供了更多的控制选项,比如硬件流控制、双向通信等。USART通常用于对数据传输速度要求较高、需要双向通信或者需要更灵活控制的场景。

二、帧格式

UART:
在这里插入图片描述

  1. 起始位(Start Bit):起始位指示数据帧的开始。它始终是逻辑低电平,并且标志着数据的传输即将开始

  2. 数据位(Data Bits):数据位是实际的数据传输部分。它表示要传输的数据,可以是5位、6位、7位或8位,取决于所选择的数据位长度。

  3. 校验位(Parity Bit):校验位是可选的,用于检测传输过程中的错误。常见的校验方式包括奇校验、偶校验或者不使用校验。校验位的选择取决于通信双方事先约定好的校验规则。

  4. 停止位(Stop Bit):停止位标志着数据帧的结束。它始终是逻辑高电平,用于告知接收端该数据帧已经传输完成

发送过程中,发送方和接收方的波特率需要保持一致,为了减少累计的误差,最多发送1个字节,也就是发送的数据位,最多为8位。

USART支持同步模式,因此USART 需要同步始终信号USART_CK,一般在单片机里面同步信号很少使用,所以USART和UART使用方式是一样的,都使用异步模式。

三、硬件连接

USART和UART在硬件连接上有一些差别,主要是因为USART支持同步通信而UART不支持。下面是它们的硬件连接方式:

  1. UART的硬件连接:
  • UART通常使用三根线进行连接:TX(发送端)、RX(接收端)和地线(GND)。发送端的TX线连接到接收端的RX线,接收端的TX线连接到发送端的RX线。此外,两端的地线需要连接在一起,以确保信号的参考电位相同。
  • 在单片机或者嵌入式系统中,UART通常通过芯片上的引脚来连接,例如MCU的TX引脚连接到外部设备的RX引脚,MCU的RX引脚连接到外部设备的TX引脚。

在这里插入图片描述

  1. USART的硬件连接:
  • USART的连接方式与UART类似,但是在同步模式下还需要连接一个时钟线(CLK)。因此,USART在同步模式下通常使用四根线进行连接:TX、RX、CLK和GND。
  • 在使用USART进行同步通信时,发送端和接收端需要共享一个时钟信号,因此需要额外的时钟线来进行连接。

总的来说,UART和USART在硬件连接上的主要区别在于是否需要连接时钟线。

四、工作模式

  • 单工模式(Simplex Communication)的数据传输是单向的。通信双方中,一方固定为发送端,一方则固定为接收端。信息只能沿一个方向传输,使用一根传输线。
  • 半双工模式(Half Duplex)通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。数据传输允许数据在两个方向上传输,但是,在任何时刻只能由其中的一方发送数据,另一方接收数据。因此半双工模式既可以使用一条数据线,也可以使用两条数据线。半双工通信中每端需有一个收发切换电子开关,通过切换来决定数据向哪个方向传输。因为有切换,所以会产生时间延迟,信息传输效率低些。
  • 全双工模式(Full Duplex)通信允许数据同时在两个方向上传输。因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。在全双工模式中,每一端都有发送器和接收器,有两条传输线,信息传输效率高。

显然,在其它参数都一样的情况下,全双工比半双工传输速度要快,效率要高。

五、使用流程

  1. 初始化:首先需要初始化UART模块,包括设置波特率(Baud Rate)、数据位长度、校验位和停止位等参数。这些参数需要与通信的对端设备相匹配,以确保正常的数据传输。

  2. 发送数据:要发送数据,首先将要发送的数据写入到UART发送缓冲区。通过编程方式将数据写入发送缓冲区后,UART模块会自动将数据发送出去。在发送数据之前,需要检查发送缓冲区是否为空,以确保可以安全地写入新的数据。

  3. 接收数据:接收数据时,需要检查接收缓冲区中是否有新的数据可供读取。如果接收缓冲区中有数据可读,可以通过编程方式读取数据并进行处理。

  4. 错误处理:在UART通信过程中,可能会发生一些错误,比如校验错误或者帧错误。在接收数据时,需要及时检查错误标志位,以便进行相应的错误处理和恢复。

  5. 中断处理:为了提高系统的响应速度和效率,通常会使用UART中断来处理接收和发送数据。在使用中断的情况下,需要编写相应的中断服务程序(ISR),以处理接收到的新数据或者发送缓冲区为空的情况。

  6. 关闭和清理:在程序结束或者不再需要使用UART时,需要关闭UART模块,并进行相应的资源清理工作,以释放相关的资源和关闭相应的中断。

具体示例(MCU为STM32F103)

#include "bsp_usart.h"
 /**
  * @brief  配置嵌套向量中断控制器NVIC
  * @param  无
  * @retval 无
  */
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

 /**
  * @brief  USART GPIO 配置,工作参数配置
  * @param  无
  * @retval 无
  */
void USART_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	// 打开串口GPIO的时钟
	DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
	
	// 打开串口外设的时钟
	DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  // 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
	
	// 配置串口的工作参数
	// 配置波特率
	USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式,收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(DEBUG_USARTx, &USART_InitStructure);
	
	// 串口中断优先级配置
	NVIC_Configuration();
	
	// 使能串口接收中断
	USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);	
	
	// 使能串口
	USART_Cmd(DEBUG_USARTx, ENABLE);		

  // 清除发送完成标志
	//USART_ClearFlag(USART1, USART_FLAG_TC);     
}

/*****************  发送一个字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx,ch);
		
	/* 等待发送数据寄存器为空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
	unsigned int k=0;
  do 
  {
      Usart_SendByte( pUSARTx, *(str + k) );
      k++;
  } while(*(str + k)!='\0');
  
  /* 等待发送完成 */
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  {}
}

/*****************  发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{
	uint8_t temp_h, temp_l;
	
	/* 取出高八位 */
	temp_h = (ch&0XFF00)>>8;
	/* 取出低八位 */
	temp_l = ch&0XFF;
	
	/* 发送高八位 */
	USART_SendData(pUSARTx,temp_h);	
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
	
	/* 发送低八位 */
	USART_SendData(pUSARTx,temp_l);	
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(DEBUG_USARTx, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(DEBUG_USARTx);
}

最后

如果本文对你有所帮助,还请三连支持一下博主!
请添加图片描述

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

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

相关文章

第七章 图【数据结构与算法】【精致版】

第七章 图【数据结构与算法】【精致版】 前言版权第七章 图7.1 应用实例7.2图的基本概念7.3图的存储结构7.3.1邻接矩阵**1-邻接矩阵.c****2-邻接矩阵plus.c** 7.3.2 邻接表**3-邻接表.c** **4-邻接表plus.c** 7.3.3 十字链表7.3.4多重链表 7.4图的遍历7.4.1深度优先搜索遍历**5…

每天一点python——day62

为了方便复制,我在下面附带了一个python文件。 C:\Users\Admin>python Python 3.9.13 (main, Aug 25 2022, 23:51:50) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32Warning: This Python interpreter is in a conda environment, but the environmen…

【蓝桥杯选拔赛真题13】C++最短距离 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

C/C++最短距离 第十二届青少组蓝桥杯C++选拔赛真题 一、题目要求 1、编程实现 有一个居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为 1,2,3……,当排满一行时,从下一行相邻的楼往反方向排号。 例如:小区为 3 行 6 列,矩阵排列方式: 要求:已知小区…

python 之列表的常用方法

文章目录 1. **append()** 方法2. **extend()** 方法3. **insert()** 方法4. **pop()** 方法5. **remove()** 方法6. **clear()** 方法7. **index()** 方法8. **count()** 方法9. **reverse()** 方法10. **sort()** 方法 当操作 Python 列表时,常用的方法如下。以下…

Python学习笔记--模块简介

一、Python 模块简介 在开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。 后面我们学习了函数,知道函数是实现一项或多项功能的一段程序,这样就更方便我们重复使用代码。 紧接着&…

解析半导体测试系统及半导体的测试方法步骤

半导体如今在集成电路、通信系统、照明等领域被广泛应用,是一种非常重要的材料。在半导体行业中,半导体测试是特别关键的环节,以保证半导体器件及产品符合规定和设计要求,确保其质量和性能。 随着现代电子技术的发展,半…

移远EC600U-CN开发板 day02

1.QuecPythonLVGL显示图片 由于官方提供的显示图片函数使用失败,为了能在屏幕上显示图片,通过对出厂脚本的分析,成功使用LVGL显示图片 (1)代码 import lvgl as lv from tp import gt9xx from machine import LCD from machine import Pin …

别让噪声偷走你的听力

欢声笑语,音乐悠扬,燕语莺声,流水潺潺,和亲友畅所欲言…… 这些愉悦的声音让我们每天的生活更充实,他们也是美好记忆的重要组成部分。听力对于我们的身体健康、情感幸福和整体生活质量起着巨大的作用。 因此保护听力健…

华为fusionInsigtht集群es连接工具

华为fusionInsight为用户提供海量数据的管理及分析功能,快速从结构化和非结构化的海量数据中挖掘您所需要的价值数据。开源组件结构复杂,安装、配置、管理过程费时费力,使用华为FusionInsight Manager将为您提供企业级的集群的统一管理平台,在…

大数据管理平台有什么用?如何利用大数据管理平台优化企业运营?

在数字化时代,大数据管理平台已经成为了企业和组织不可或缺的工具。它不仅可以帮助企业跟踪和解决报修问题,还为数据分析提供了丰富的信息。通过合理利用大数据管理平台进行数据分析,企业可以更好地了解其运营情况,优化设备维修和…

攻防世界题目练习——Web引导模式(四)(持续更新)

题目目录 1. shrine2. very_easy_sql 1. shrine 打开网页题目内容如下: 是一段代码,我们把它还原一下: import flask import osapp flask.Flask(__name__) app.config[FLAG] os.environ.pop(FLAG) #这里应该是将config配置里的FLAG字段设…

Time series analysis of InSAR data: Methods and trends(NASA,2015)

文章目录 ISPRS J PHOTOGRAMMIntroductionPhase unwrapping相位解缠算法综述 Time series analysis of InSAR dataPersistent Scatterer Interferometry (PSI)--持久散射体☆☆☆☆PSInSAR && SBAS-InSAR☆☆☆☆PS-InSARSBAS-InSARDS-InSAR(分布式散射体干…

金秋云创季——ECS爆品省钱攻略

阿里云双十一推出优惠活动——“金秋云创季”,其中,云服务ECS下的经济型e实例,低至99元/1年,新老用户都可购买,续费不涨价;轻量应用服务器,2核2G 低至87元1年……官方满减优惠享受折上折。惊喜不…

微服务架构——笔记(4)

微服务架构——笔记(4) 基于分布式的微服务架构 本次笔记为 此次项目的记录,便于整理思路,仅供参考,笔者也将会让程序更加完善 内容包括:8001集群构建,负载均衡,服务发现&#xff0…

day51

前端框架Booststrap 该框架已经帮我们写了很多页面样式,如果需要使用,只需要下载对应文件直接cv即可 在使用Booststrap的时候,所有发页面样式只需要通过修改class属性来调节即可 什么是Booststrap Bootstrap是一个开源的前端框架&#xff…

基于junit4搭建自定义的接口自动化测试框架

随着业务的逐步稳定,对于接口的改动也会逐渐变少。更多的是对业务逻辑的优化,功能实现的完善。对于测试来说,重复繁琐的功能测试不仅效率低下,而且耗费一定的人力资源。笔者支持的信息流业务下的一个图文管理平台就是一个功能较为…

Elasticsearch:ES|QL 的限制

尽管 ES|QL 带来性能及使用上的便捷,在实际的使用中,它还是有一些限制。在今天的文章中,我们来列举它的一些限制。 结果集大小限制 默认情况下,ES|QL 查询最多返回 500 行。 你可以使用 LIMIT 命令将行数增加到最多 10,000 行。 …

SDH设备

文章目录 实际的SDH设备结构:OSN3500

Archicad 26 (BIM建模软件)

Archicad 26是一款建筑信息模型(BIM)软件,由Graphisoft公司开发。它提供了全面的设计和建模工具,用于创建3D建筑模型、制作施工图纸等。 Archicad 26支持多种文件格式,并且可以与其他CAD软件进行互操作。它具有强大的建…

关于mysql自增列起始值与数据实际id不一致的问题

从一个数据表生成表结构和数据的脚本之后。把脚本复制到另一个数据库执行同步数据结构和数据。 Navicat 发生了如下异常提示,并中断了脚本执行: Duplicate entry 51110 for key sys_log.PRIMARY 然后检查sys_log表的建表脚本,发现有如下行&…