UART/USART串口通信一:概念

前言

UART:universal asynchronous receiver and transmitter通用异步收/发器
USART:universal synchronous asynchronous receiver and transmitter通用同步/异步收/发器

通信是嵌入式系统的重要功能之一。使用的通信接口有很多,比如UART,SPI,IIC,USB和CAN等。其中UART是最常见,最方便,使用最频繁的通信接口。

从数据通信的基本概念出发,讲述微控制器的UART部件——USART的工作原理和开发技术。注:学过计算机网络的对这些就很简单了。

1.数据通信的基本概念

1.1 并行和串行

按数据传送的方式,通讯可分为串行通讯与并行通讯,串行通讯是指设备之间通过少量数据信号线(一般是 8 根以下),地线以及控制信号线,按数据位形式一位一位地传输数据的通讯方式。而并行通讯一般是指使用 8、 16、 32 及 64 根或更多的数据线进行传输的通讯方式,并行通讯就像多个车道的公路,可以同时传输多个数据位的数据,而串行通讯,而串行通讯就像单个车道的公路,同一时刻只能传输一个数据位的数据。
在这里插入图片描述
在这里插入图片描述

1.2 单工,半双工,全双工

根据数据通讯的方向,通讯又分为全双工、半双工及单工通讯,它们主要以信道的方向来区分。
在这里插入图片描述
在这里插入图片描述

1.3 同步和异步

根据通讯的数据同步方式,又分为同步和异步两种,可以根据通讯过程中是否有使用到时钟信号进行简单的区分。

1.4 通信速率

衡量通讯性能的一个非常重要的参数就是通讯速率,通常以比特率(Bitrate)来表示,即每秒钟传输的二进制位数,单位为比特每秒(bit/s)。容易与比特率混淆的概念是“波特率”(Baudrate),它表示每秒钟传输了多少个码元。

而码元是通讯信号调制的概念,通讯中常用时间间隔相同的符号来表示一个二进制数字,这样的信号称为码元。如常见的通讯传输中,用 0V 表示数字 0, 5V 表示数字 1,那么一个码元可以表示两种状态 0 和 1,所以一个码元等于一个二进制比特位,此时波特率的大小与比特率一致;如果在通讯传输中,有 0V、2V、 4V 以及 6V 分别表示二进制数 00、 01、 10、 11,那么每个码元可以表示四种状态,即两个二进制比特位,所以码元数是二进制比特位数的一半,这个时候的波特率为比特率的一半。因为很多常见的通讯中一个码元都是表示两种状态,人们常常直接以波特率来表示比特率,虽然严格来说没什么错误,但希望能了解它们的区别。

2.UART/USART通信原理物理层

2.1 UART

2.1.1 UART接口

UART为异步串行全双工通信。最简单的接口可以由TxD,RxD和GND三条线构成,想要更复杂的功能,还需要更多的引脚。

2.1.2 UART电平

UART使用电子电路中常使用 TTL 的电平标准,理想状态下,使用 5V 表示二进
制逻辑 1,使用 0V 表示逻辑 0;

2.1.3 UART互连

若想链接两个UART设备进行相互通信,他们使用相同的电平标准,直接连接就可以。
在这里插入图片描述

2.2 RS232标准原理

UART采用的电平标准限制了它的传输距离,为了扩展传输距离和应用范围,使用RS232标准。

2.2.1 RS232接口

RS232接口通常采用DB9或DB25的形式,以DB9最常见。
在这里插入图片描述
在这里插入图片描述

2.2.2 RS232电平

采用负逻辑,为了增加串口通讯的远距离传输及抗干扰能力,它使用-3~-15V 表示逻辑 1, +3~+15V 表示逻辑 0。传输距离最高可达15m。

2.2.3 RS232互连

在这里插入图片描述

2.2.4 RS232和UART互连

在这里插入图片描述

2.2.4 USB转串口通讯结构图

在这里插入图片描述
1、USB转串口主要用于设备跟电脑通信
2、电平转换芯片一般有CH340、PL2303、CP2102、FT232
3、使用的时候电脑端需要安装电平转换芯片的驱动

3.UART/USART通信原理协议层

通信协议一般包括三个方面:
时序,数据帧格式,传输速率,一般不使用时钟线,不考虑时序

3.1 UART数据格式

在这里插入图片描述
起始位:由1个逻辑 0 的数据位表示
结束位:由 0.5、 1、 1.5 或 2 个逻辑 1 的数据位表示
有效数据:在起始位后紧接着的就是有效数据,有效数据的长度常被约定为 5、 6、 7 或 8 位长
校验位:可选,为的是数据的抗干扰性。
校验方法分为:
1-奇校验(odd),有效数据和校验位中“ 1”的个数为奇数
2-偶校验(even) ,有效数据和校验位中“ 1”的个数为偶数
3-0 校验(space),不管有效数据中的内容是什么,校验位总为“ 0”
4-1校验(mark),不管有效数据中的内容是什么,校验位总为“ 1”
5-无校验(noparity)
空闲位,总是保持逻辑1。

3.1 UART传输速率

常见的波特率为4800、 9600、 115200 等。

4.STM32 的 USART 工作原理

通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于 USART 还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在 USART 基础上裁剪掉了同步通信功能,只有异步通信。 简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是 UART

4.1 主要特性

行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数据信息、停止信息,可能还有校验信息。 USART 就是对这些传输参数有具体规定,当然也不是只有唯一一个参数值,很多参数值都可以自定义设置,只是增强它的兼容性。
USART 满足外部设备对工业标准 NRZ 异步串行数据格式的要求,并且使用了小数波
特率发生器,可以提供多种波特率,使得它的应用更加广泛。 USART 支持同步单向通信和半双工单线通信;还支持局域互连网络 LIN、智能卡(SmartCard)协议与lrDA(红外线数据协会) SIR ENDEC 规范。
USART 支持使用 DMA,可实现高速数据通信,有关 DMA 具体应用将在 DMA 章节
作具体讲解。
USART 在 STM32 应用最多莫过于“打印”程序信息,一般在硬件设计时都会预留一
个 USART 通信接口连接电脑,用于在调试程序是可以把一些调试信息“打印”在电脑端的串口调试助手工具上,从而了解程序运行是否正确、如果出错哪具体哪里出错等等。

4.2 USART功能框图

在这里插入图片描述

4.2.1 引脚

在这里插入图片描述
STM32F10x数据手册—Pinouts and pin description。
ST每个系列的芯片都有一个数据手册,里面有引脚的详细功能。
要注意重映射,就是一个功能,可能映射了两个端口。
TX:数据发送
RX:是数据接收
SCLK:时钟,仅同步通信时使用
nRTS:请求发送(Request To Send)
nCTS:允许发送(Clear To Send)n表示低电平有效

4.2.2 数据寄存器

数据寄存器—USART_DR:9位有效,包含一个发送数据寄存器TDR和一个接收数据寄存器RDR。一个地址对应了两个物理内存。

USART 数据寄存器(USART_DR)只有低 9 位有效,并且第 9 位数据是否有效要取决于USART 控制寄存器 1(USART_CR1)的 M 位设置,当 M 位为 0 时表示 8 位数据字长,当 M位为 1 表示 9 位数据字长,我们一般使用 8 位数据字长。

USART_DR 包含了已发送的数据或者接收到的数据。 USART_DR 实际是包含了两个寄存器,一个专门用于发送的可写 TDR,一个专门用于接收的可读 RDR。当进行发送操作时,往 USART_DR 写入数据会自动存储在 TDR 内;当进行读取操作时,向 USART_DR读取数据会自动提取 RDR 数据。

4.2.3 控制器

USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用 USART 之前需要向 USART_CR1 寄存器的 UE 位置 1 使能 USART, UE 位用来开启供给给串口的时钟。发送或者接收数据字长可选 8 位或 9 位,由 USART_CR1 的 M 位控制。

在这里插入图片描述
在这里插入图片描述
控制器—USART_CR1、CR2、CR3熟读手册即可

4.2.4 波特率控制

USART_BRR:波特率寄存器
USART_CR1:OVER8
小数波特率生成
波特率指数据信号对载波的调制速率, 它用单位时间内载波调制状态改变次数来表示,单位为波特。比特率指单位时间内传输的比特数,单位 bit/s(bps)。对于 USART 波特率与比特率相等,以后不区分这两个概念。波特率越大,传输速率越快。
在这里插入图片描述

4.2.5 中断控制

USART 有多个中断请求事件,具体见表
在这里插入图片描述

5.USART 初始化结构体详解

这里我们要注意一个问题,初始化一个外设的结构体时,就相当于控制相应的寄存器了。结构体成员用于设置外设工作参数,并由外设初始化配置函数,比如 USART_Init()调用,这些设定参数将会设置外设相应的寄存器,达到配置外设工作环境的目的.

初始化结构体和初始化库函数配合使用是标准库精髓所在,理解了初始化结构体每个成员意义基本上就可以对该外设运用自如了。初始化结构体定义在 stm32f10x_usart.h 文件中,初始化库函数定义在 stm32f10x_usart.c 文件中,编程时我们可以结合这两个文件内注释使用

typedef struct {
uint32_t USART_BaudRate; // 波特率,标准库函数会根据设定值计算得到 USARTDIV 值, 从而设置 USART_BRR 寄存器值。
uint16_t USART_WordLength; // 字长可选 8 位或 9 位。它设定 USART_CR1 寄存器的 M 位的值。如果没有使能奇偶校验控制,一般使用 8 数据位;如果使能了奇偶校验则一般设置为 9 数据位。
uint16_t USART_StopBits; // 停止位设置,可选 0.5 个、 1 个、 1.5 个和 2 个停止位,它设定USART_CR2 寄存器的 STOP[1:0]位的值,一般我们选择 1 个停止位。
uint16_t USART_Parity; // 校验位
uint16_t USART_Mode; //USART 模式选择,有 USART_Mode_Rx 和 USART_Mode_Tx,允许使用逻辑或运算选择两个,它设定 USART_CR1 寄存器的 RE 位和 TE 位。
uint16_t USART_HardwareFlowControl; // 硬件流控制,不用
} USART_InitTypeDef;

注意
还有一个USART 时钟初始化结构体,这个只有在同步通信的时候才用到,异步不用管它。

后记

这一篇文章说了很多,先介绍了通信的基本概念。
然后分别从物理层和协议层介绍UART的东西。
最后介绍UART的框图和结构体函数。

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
USART (Universal Synchronous/Asynchronous Receiver/Transmitter) 是一种通用的串行通信接口,常用于单片机与外部设备之间的通信。USART 可以以同步模式或异步模式进行数据传输。 在使用 USART 进行串口通信时,需要先设置 USART 的通信参数,包括波特率、数据位数、停止位数、奇偶校验等。然后将数据通过 USART 发送出去,或者从 USART 接收数据。 在发送数据时,需要将数据写入 USART 的数据寄存器中,USART 会自动将数据进行传输。在接收数据时,需要读取 USART 的数据寄存器,USART 会自动将接收到的数据存储在数据寄存器中。 通常情况下,我们可以使用 printf 函数来向串口发送数据,或使用 scanf 函数从串口接收数据。在使用这些函数之前,需要先初始化串口的通信参数。 下面是一个使用 USART 进行串口通信的例子,使用的是 STM32 单片机的 HAL 库: ```c #include "stm32f1xx_hal.h" UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); char buffer[20]; while (1) { printf("Enter a string: "); scanf("%s", buffer); printf("You entered: %s\n", buffer); HAL_Delay(1000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } } void Error_Handler(void) { } ``` 在上面的例子中,我们先通过 MX_USART1_UART_Init 函数初始化了 USART1 的通信参数,然后在 while 循环中使用 printf 和 scanf 函数进行串口通信。注意,在使用 printf 函数前,需要在头文件中包含 stdio.h 和 usart.h 文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值