USART相关的笔记

串口通讯(Serial Communication)是一种设备间很常用的串行通讯方式,串口按位(bit)发送和接收字节,尽管比按字节(byte)的并行通讯慢,但是串口可以在使用一根线发送数据的同时使用,另一根线接收数据。我们一般使用的串口都是串行异步全双工通讯。

串行通俗的理解就是传输数据时,无论数据有多少位,都只用到一根线进行通讯,当然串口通讯至少会用到两根线,一根是TX,一根是RX,一根地线。

异步的意思是当设备进行通讯的时候,中间不需要连接时钟线(SCK)。串口通讯的时候需要配置波特率,只有当设备间的波特率相等的时候,才可以进行正常的通讯。波特率就是每秒钟内发送或接收多少位数据,常见的波特率有9600,115200等。

全双工的意思就是发送和接收可以同时进行。(单工是只能发送或者只能接收。半双工的意思是可以发送也可以接收,但是不能同时进行,比如IIC)。

串口通讯可以分为物理层和协议层。

一、物理层:

串口通讯有不同的标准,比如RS-232、RS-485。RS-232的常见通讯结构如图:

由于RS-232电平标准不能直接被寄存器识别,所以这些信号需要经过一个“电平转换芯片”转换成控制器能识别到的“TTL标准”的电平信号,才能实现通讯。

之前我用MCU引出来的TX和RX管脚直接连接电脑上的串口引脚,发现电脑上接收到的数据都是错的,后来加了一个CH340,就可以正常通讯,这就是因为两者的电平标准不一致导致的,这可能烧了MCU,比较费板子。

以下是TTL电平标准和RS-232电平标准:

 RS-232信号线原先采用25个脚的DB-25连接器,后来逐渐淘汰,现一般采用的是“DB-9”连接器,而工业控制的RS-232口一般只使用RXD、TXD、GND三条线。“DB9”串口线如图,接线口以针式引出的信号线称为公头,以孔式引出的信号线称为母头。

 标准信号线接法如图:

 

 引脚定义:

 

 二、协议层:

串口通讯的数据包由发送设备通过自身的TXD接口传输到接受设备的RXD接口。在串口通讯的协议层中,规定了数据包的内容,它由起始位、主体数据、校验位以及停止位组成。通讯双方的数据包格式要约定一致才能正常的发送和接收

 

 三、USART时钟框图

 

 1、引脚功能:

  TX:数据发送引脚

  RX:数据接收引脚

  SW_RX:数据接收引脚,用于单线和智能卡模式,只有内部引脚,没有引出来

  nRTS:请求以发送,n代表低电平有效。如果使能nRTS流控制,当USART准备好接受数据时将会拉低nRTS电平,当接收寄存器满了的时候,nRTS将会被设置为高电平。该引脚只适用于硬件流控制

  nCTS:清除已发送,n代表低电平有效。如果使能CTS流控制,发送器在发送下一帧之前会检测nCTS引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后就会停止发送,该引脚只适用硬件流控制

  IRDA_OUT/IRDA_IN:用于红外传输数据

  SCLK:发送器时钟输出引脚,只适用于同步模式。

2、数据寄存器

  数据寄存器只是低9位有效,并且第8位是否有效取决于数据字长,该位可以在USART的控制寄存器1(USART_CR1)的M位配置,当M位为0的时候表示8位数据字长,当M位为1表示9位数据字长。数据寄存器实际上包含了两个数据寄存器,一个是用于发送数据的TDR,另外一个是用于接受数据的RDR。当需要发送数据的时候,内核或者DMA外设就会把数据从内存写到发送数据寄存器TDR,因为TDR和RDR都是介于总线和移位寄存器之间,发送时,数据并行地转移到发送移位寄存器中,然后从移位寄存器中一位一位地发送出去。接收数据的过程则相反,数据一位一位地接收到接收移位寄存器中,再并行地转移到数据接收寄存器RDR中,最后使用内核指令或者DMA读取到内存中。

3、控制器

  USART有专门的控制发送的发送器,控制接收的接收器,还有唤醒单元、中断控制等。使用USART之前必须先使能,即向USART_CR1中的UE位写1

  1)发送器:当发送使能位(TE)置1时,发送移位寄存器中的数据在TX脚上输出,如果是同步模式,在SCLK引脚上也会输出时钟脉冲。每个字符前都有一个低电平的起始位,之后跟着一个停止位,数目可以通过USART控制寄存器2(USART_CR2)中的STOP[1:0]位控制,可选0.5、1、1.5、2个停止位,默认使用1个停止位,2个停止位可用于单线模式,常规的USART模式以及调制解调器模式,0.5和1.5个停止位用于智能卡模式。具体发送字符时序如图:

 在发送数据的时候,发送器对TE位置1,发送一个空闲帧作为第一次数据发送,把要发送的数据写到USART_DR中,在写入最后一个数据后,等待TC = 1,表示发送完成。如果USART_CR1中的TCIE位被置起,则会产生中断。

  2)接收器:设置USART_CR1的RE位。激活接收器,使其开始寻找起始位。在确定到起始位后就根据RX线的电平状态把数据存到接收移位寄存器内。接收完成后把数据并行地转移到接受数据寄存器(RDR)中,并且把USART_SR的RXNE位置1,表明数据已经被接收,而且可以被读出。如果USART_SR的RXNEIE位被置1,则会产生中断。

4、波特率控制:  

  波特率,即每秒传输的二进制位数,用 b/sbps) 表示,通过对时钟的控制可以改变波特率。在配置波特率时,我们在比率寄存器 USART_BRR 写入参数,修改了串口时钟的分频值 USARTDIVUSART_BRR 寄存器包括两部分,分别是 DIV_MantissaUSARTDIV 的整数部分) 和 DIV_FractionUSARTDIV 的小数) 部分,最终,计算公式为 USARTDIV=DIV_Mantissa+(DIV_Fraction/16)

例如, DIV_Mantissa=27DIV_Fraction=12USART_BRR=0x1BC
于是:
  MantissaUSARTDIV=27
  FractionUSARTDIV=12/16=0.75
  所以
USARTDIV=27.75

 

四、串口通讯硬件设计

  CH340是一种USB转串口芯片。MCU的TXD和RXD分别与CH340G的RXD和TXD相连,JP1和JP2 是跳线帽,为了方便串口2~5实现串口通讯。CH340G的VD+和VD-是USB的信号接口,直接连到USB的D+和D-。XI和XO为晶体振荡的输入端和反向输出端,外接12MHZ的晶振与晶振电容。

 

五、寄存器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

寄存器映射:

 

六、使用CubeMX生成USART工程

  CubeMX配置的过程比较简单,这里就不详细说明了,主要看看生成的代码中的函数以及一些结构体

1) 观察到下面的代码,其实这些在我们在配置 CubeMX 软件时,已经完成了各
项参数的设置。 这是它在 HAL 库中的结构体。 HAL 库函数对每个外设,都建
立了一个相当于对应外设总接口的结构体(官方称为句柄) 作为 HAL API
函参。 在使用 HAL 库配置工程中, 如果能掌握每个结构体成员的含义, 那么
对此外设就可以应用自如了。 在 bsp_usartx.c 的私有变量, 我们声明了一个
串口结构体,接下来我们来认识 UART_HandleTypeDef 这个结构体中各个成
员的含义, 见代码 。 了解各个成员的含义,有助于我们在开发更高级工
程时能够熟练的应用 HAL 库。

      UART 操作结构体定义

01 typedef struct {
02 USART_TypeDef *Instance; // UART 寄存器基地址
03 UART_InitTypeDef Init; //UART 通信参数
04 uint8_t *pTxBuffPtr; // 指向 UART 发送缓冲区
05 uint16_t TxXferSize; // UART 发送数据大小
06 uint16_t TxXferCount; // UART 发送计数器
07 uint8_t *pRxBuffPtr; //向 UART 接收缓冲区
08 uint16_t RxXferSize; // UART 接收数据大小
09 uint16_t RxXferCount; // UART 发送计数器
10 DMA_HandleTypeDef *hdmatx; //UART 发送参数设置(DMA 模式)
11 DMA_HandleTypeDef *hdmarx; // UART 接收参数设置(DMA 模式)
12 HAL_LockTypeDef Lock; // 锁定对象
13 __IO HAL_UART_StateTypeDef State; // UART 通信状态
14 __IO uint32_t ErrorCode; //UART 错误代码
15 } UART_HandleTypeDef;

  InstanceUART 寄存器基地址,按 F12(工程编译之后才有效)进入 USART_TyDef
    这个结构体的定义,可以发现, 里面是我们在前面讲过的 CR1CR2 等关于
    USART 功能的寄存器, 可以返回看图 13-5 及相关描述。
   InitUART 通信参数, 在代码 13-2, 会进行详细的讲解。
   中间的 6 个变量定义, 是服务于 HAL 库内封装函数对于数据接收和发送的处
    理。
   hdmatx/hdmarx:使用 DMA, 发送数据或接收数据的配置。
   Lock:对资源性操作增加操作锁的保护。
    StateUART通信状态。有 RESETREADYBUSYBUSY_TXBUSY_RXBUSY_TX_RX
    TIMEOUTERROR。根据不同的状态,控制 UART 的发送和接收。


2) UART 参数配置, UART_InitTypeDef,结构体成员用于设置外设工作参数,并
由外设初始化配置函数,比如 MX_USARTx_Init()调用,这些参数将会设置外
设相应的寄存器,达到配置外设工作环境的目的。 我们在代码 13-1 可以看
到在 USAT_HandleTypeDef 结构体中,定义了多个结构体成员,而这就是结构
体的嵌套。在 USAT_HandleTypeDef 结构体中, UART_InitTypeDef 相当于成员。
代码 13-2 UART_InitTypeDef 结构体的说明

01 typedef struct {
02 uint32_t BaudRate; //波特率
03 uint32_t WordLength; //字长
04 uint32_t StopBits; //停止位
05 uint32_t Parity; //校验位
06 uint32_t Mode; //USART 模式
07 uint32_t HwFlowCtl; //硬件流控制
08 uint32_t OverSampling; //过采样
09 } UART_InitTypeDef;

BaydRate:波特率设置。一般设置为 960019200115200。利用 HAL 库可
以直接配置波特率。
WordLength:数据帧字长,可选 8 位或 9 位。它设定 USART_CR1 寄存器的 M
位的值。 一般使用 8 数据位。
StopBits:停止位设置,可选 0.5 个、 1 个、 1.5 个和 2 个停止位,一般我们选
1 个停止位。
Parity : 奇 偶 校验位控制选择 , 可 选 UART_PARITY_NONE ( 无 校 验 )、
UART_PARITY_EVEN(偶检验) 以及 UART_PARITY_ODD(奇校验), 我们选择
无校验位。
ModeUSART 模式选择,有 UART_MODE_RX(接收)、 UART_MODE_TX(发
送) 和 UART_MODE_TX_RX(发送和接收模式)。
HwFlowpling: 硬件流控制, 只有在硬件流控制模式下有效。可选有使能 RTS
使能 CTS、 同时使能 RTS CTS、 不使能硬件流。
OverSampling: 过采样,提高精度。 按照 HAL 库原版英文介绍, 只能设置为
16
 

 


标准库:

   标准库和HAL库实际上很相似,有异曲同工之妙,不同的是HAL库可以用CubeMX生成,大大提高了开发的效率。但标准库的应用目前来说还是很普遍的,所以我觉得有必要学习标准库的用法,在这个过程中或许可以帮助我们更深入地理解相关的原理。

  1)USART寄存器结构体

 

 

 

   2)USART库函数

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/young-dalong/p/13577632.html