STM32系列 USART通信

本文介绍了UART和USART的区别,USART是UART的增强型,能提供主动时钟。阐述了USART的主要特性,如全双工异步通信、可配置参数等。说明了其功能、引脚连接,还介绍了使用DMA进行通信的方法、USART中断情况,最后给出代码实现,包括初始化、数据收发,数据量大时可考虑用DMA传输。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 前言

UART:通用异步收发传输器,是一种通用串行数据线,用于异步通信,双向通信,可以实现全双工传输和接收。
USART:通用同步/异步串行收发器,是一个全双工通用同步/异步串行收发模块。
USART收发模块分为三个部分:时钟发生器、数据发送器和接收器。
时钟发生器由同步逻辑电路(在同步从模式下由外部时钟输入驱动)和波特率发生器组成。发送时钟引脚XCK仅用于同步发送模式下。
发送器部分由一个单独的写入缓冲器(发送UDR)、一个串行移位寄存器、校验位发生器和用于处理不同帧结构的控制逻辑电路构成。使用吸入缓冲器,实现了连续发送多帧数据无延时的通信。
接收器最主要的是时钟和数据接收单元。数据接收单元用作异步数据的接收。除了接收单元,接收器还包括校验位校验器、控制逻辑、移位寄存器和两级接收缓冲器(接收UDR)。接收器支持与发送器相同的帧结构,同时支持帧错误、数据溢出和校验错误的检测。
UART和USART的区别:
从名字上看,USART在UART基础上增加了同步功能,即USART是UART的增加型,使用USART在异步通信时,与UART没什么区别,但是用在同步通信时,区别就明显了,同步通信需要时钟来触发数据传输,也就是说USART相对于UART能提供主动时钟。

1 简介

通用同步异步收发器(USART)能够灵活的与外部设备进行全双工数据交换,满足外部设备对工业标准NRZ异步串行数据格式的要求。通过小数波特率发生器提供了多种波特率。支持同步单向通信和半双工担心通信;还支持LIN(局域互连网络)、智能卡协议与IrDA(红外线数据协会)SIR ENDEC规范,以及调制解调器操作(CTS/RTS)。而且还支持多处理器通信。通过配置多个缓冲区使用DMA可实现高速数据通信。

2 主要特性

  • 全双工异步通信
  • NRZ标准格式(标记/空格)
  • 可配置为16倍过采样或8倍过采样,因而为速度容差与时钟容差的灵活配置提供了可能
  • 小数波特率发生器系统
     - 通用可编程收发波特率
  • 数据字长度可编程(8位或9位)
  • 停止位可配置
     - 支持1或2个停止位
  • LIN主模式同步停止符号发送功能和LIN从模式停止符号检测功能
     - 对USART进行LIN硬件配置时可发生13位停止符合和检测10/11位停止符号
  • 用于同步发送的发送器时钟输出
  • IrDA SIR编码解码器
     - 正常模式下,支持3/16位持续时间
  • 智能卡仿真功能
     - 智能卡接口支持符合ISO 7816-3标准中定义的异步协议智能卡
     - 智能卡工作模式下,支持0.5或1.5个停止位
  • 单线半双工通信
  • 使用DMA(直接存储器访问)实现可配置的多缓冲区通信
     - 使用DMA在预留的SRAM缓冲区中收/发字节
  • 发送器和接收器具有单独使能位
  • 传输检测标志:
     - 接收缓冲区已满
     - 发送缓冲区为空
     - 传输结束标志
  • 奇偶校验控制:
     - 发送奇偶校验位
     - 检查接收的数据字节的奇偶性
  • 四个错误检测标志:
     - 溢出错误
     - 噪声检测
     - 帧错误
     - 奇偶检验错误
  • 十个具有标志位的中断源:
     - CTS变化
     - LIN停止符号检测
     - 发送数据寄存器为空
     - 发送完成
     - 接收数据寄存器已满
     - 接收到线路空闲
     - 溢出错误
     - 帧错误
     - 噪声错误
     - 奇偶检验错误
  • 多处理器通信
     - 
  • 从静模式唤醒(通过线路空闲检测或地址标记检测)
  • 两个接收器唤醒模式:地址位(MSB,第9位),线路空闲

3 功能说明

接口通过三个引脚从外部设备连接到其他设备。任何USART双向通信均需要至少两个引脚:接收数据输入引脚(RX)和发送数据输出引脚(TX)
RX:就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据
TX:如果关闭发送器,该输出引脚模式由其I/O端口配置决定。如果使能了发送器但没有待发送的数据,则TX引脚处于高电平。在单线和智能卡模式下,该I/O用于发送和接收数据(USART电平下,随后在SW_RX上接收数据)
正常USART模式下,通过这些引脚以帧的形式发送和接收串行数据:

  • 发送或接收前保持空闲线路
  • 起始位
  • 数据(字长8位或9位),最低有效位在前
  • 用于指示帧传输已完成的0.5个、1个、1.5个、2个停止位
  • 该接口使用小数波特率发生器 - 带12位尾数和4位小数
  • 状态寄存器(USART_SR)
  • 数据寄存器(USART_DR)
  • 波特率寄存器(USART_BRR) - 12位尾数和4位小数
  • 智能卡模式下的保存时间寄存器(USART_GTPR)
    在同步模式下连接时需要一下引脚:
    SCLK:发送器时钟输出,用于输出发送器数据时钟,一遍按照SPI主模式进行同步发送(起始位和结束位上无时钟脉冲,可通过软件向最后一位数据位发送时钟脉冲)。RX上可同步接收并行数据。可用于控制带移位寄存器的外设(如LCD驱动器)。时钟相位和极性可通过软件编程。在智能卡模式下,SCLK可向智能卡提供时钟
    在硬件流控制模式下需要以下引脚:
    nCTS:“清除以发送”用于在当前传输结束时阻止数据发送(高电平时)
    nRTS:“请求以发送”用于指示USART已准备好接收数据(低电平时)

4 使用DMA进行通信

USART能够使用DMA进行连续通信,接收缓冲区和发送缓冲区的DMA请求时独立的

  • 使用DMA进行发送
    将USART_CR3寄存器中的DMAT位置1可以使能DMA模式进行发送。当TXE位置1时,可将数据从SRAM区加载到USART_DR寄存器。要映射一个DMA通道以进行USART发送,按以下步骤操作(x表示通道编号):
  1. 在DMA控制寄存器中写入USART_DR寄存器地址,将其配置为传输的目标地址。每次发生TXE事件后,数据都会从存储器移动到此地址。
  2. 在DMA控制寄存器中写入存储器地址,将其配置为传输的源地址。每次发生TXE后,数据都会从这个存储区域加载到USART_DR寄存器中。
  3. 在DMA控制寄存器中配置要传输的总字节数。
  4. 在DMA寄存器中配置通道的优先级
  5. 根据应用的需求,在完成一半或全部传输后产生DMA中断
  6. 向SR寄存器中的TC位写入0,将其清零
  7. 在DMA寄存器中激活该通道
    当达到在DMA控制器中设置的数据传输量时,DMA控制器会在DMA通道中的中断向量生上产生一个中断。
    在发送模式下,DMA对所有要发送的数据执行了写操作(DMA_ISR寄存器中的TCIF标志置1)后,可以对TC标志进行监视,以确保USART通信已完成。在禁止USART或进入停止模式前必须执行此步骤,以避免损坏最后一次发送。软件必须等待直到TC=1。TC标志在所有数据发送期间都必须保持清零状态,然后在最后一帧发送结束后由硬件置1。

使用DMA进行发送
在这里插入图片描述

  • 使用DMA进行接收
    将USART_CR3寄存器中的DMAR位置1可以使能DMA模式进行接收。接收数据字节时,数据会从USART_DR寄存器加载到SRAM区域中。要映射一个DMA通道以进行USART接收,按以下步骤操作:

  • 在DMA控制器中写入USART_DR寄存器地址,将其配置为传输的源地址。每次发生RXNE事件后,数据都会以此地址移动到存储器

  • 在DMA控制寄存器中写入存储器地址,将其配置为传输的目标地址。每次发生RXNE事件后,数据都会从USART_DR寄存器加载到此存储区

  • 在DMA控制寄存器中配置要传输的总字节数

  • 在DMA控制寄存器中配置通道优先级

  • 根据应用的需求,在完成一半或全部传输后产生中断

  • 在DMA控制寄存器中激活该通道
    当达到在DMA控制器中设置的数据传输量时,DMA控制器会在DMA通道的中断向量上产生一个中断。在中断子程序中,USART_CR3寄存器中的DMAR位应有软件清零。
    如果DMA用于接收,则不要使能RXNEIE位。

  • 使用DMA进行接收

在这里插入图片描述
在多缓冲区通信中,如果发生任何错误,都会在当前字节后放置错误标志。如果中断使能置1,则会产生中断。在单字节接收过程中,与RXNE一同置位的帧错误、上溢错误和噪声标志具有单独的错误标志中断使能位(USART_CR3寄存器中的EIE位);如果该位置1,则会因其中任何一个错误而在当前字节后产生中断。

5 USART中断

中断事件事件标志使能控制位
发送数据寄存器为空TXETXEIE
CTS标志CTSCTSIE
发送完成TCTCIE
准备好读取接收到的数据RXNERXNEIE
检测到上溢错误ORERXNEIE
检测到空闲线路IDLEIDLEIE
奇偶校验错误PEPEIE
断路标志LBDLBDIE
多缓冲区通信中的噪声标志、上溢错误和帧错误NF或ORE或FEEIE
USART中断事件被连接到相同的中断向量
  • 发送期间:发送完成、清楚以发送或发送数据寄存器为空中断
  • 接收期间:空闲线路检测、上溢错误、接收数据寄存器不为空、奇偶校验错误、LIN断路检测、噪声标志(仅限多缓冲区通信)和帧错误(仅限多缓冲区通信)
    如果相应的使能控制位置1,则这些事件会发生中断

6 代码实现

USART初始化

 void USART_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);         //GPIO时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);        //USART时钟使能
	GPIO_PinAFConfig(GPIO_DEBUG, GPIO_PinSource9, GPIO_AF_USART1); //GPIO复用
	GPIO_PinAFConfig(GPIO_DEBUG, GPIO_PinSource10, GPIO_AF_USART1);//GPIO复用

	GPIO_InitStructure.GPIO_Pin = GPIO_PIN_TX | GPIO_PIN_RX;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;             //设置为复用推免输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIO_DEBUG, &GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 115200;                  //设置波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;        //1个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;           //无奇偶校验位
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件数据流控制
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
	USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
	USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);   //使能USART接收中断
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);   //使能检测到空闲线路中断
	
	USART_Cmd(USART1, ENABLE);  //使能USART   
}

USART发送数据
调用USART_SendData函数进行数据发送

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
USARTx:选择USART或者UART设备
Data:传输的数据

USART_SendData()只能一个字节一个字节的发送

USART接收数据
可以通过轮询,中断和DMA的发送接收数据

void USART1_IRQHandler(void)
{
	uint32_t temp;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
	{
		RecvBuf[recvcnt] = USART_ReceiveData(USART1);  //接收数据,放入接收buff
		recvcnt++;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除接收中断
	}
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
	{
	    //清除空闲中断
		temp = USART1->SR;
		temp = USART1->DR;
		idle_flag = 1;
	}
}
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
USARTx:选择USART或者UART设备

STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,产生的条件是,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一断接收的数据断流,没有接收到数据,即产生IDLE中断。IDLE位不会再次被置高直到RXNE位被置起(即又检测到一次空闲总线)。RXNE接收中断可以不用开启,减少进中断的次数
串口总线空闲检测这一特性,尤其是对收到的数据是不定长时更有效果
在这里插入图片描述
如果数据量比较大的时候,我们可以考虑使用DMA进行数据的传输

### N32 USART 引脚重映射配置 对于N32系列单片机USART引脚的重映射同样依赖于AFIO(Alternate Function Input/Output)模块来实现。通过配置特定的寄存器位,可以选择不同的GPIO引脚作为USART的功能引脚。 #### 配置过程概述 为了完成USART引脚的重映射,在初始化阶段需调用`GPIO_PinRemapConfig()`函数并传入相应的参数以启用指定的重映射选项[^1]。此过程中涉及到的主要步骤包括但不限于: - 启动RCC时钟以便访问AFIO外设。 - 使用`GPIO_PinRemapConfig()`函数激活所需的引脚重映射模式。 - 对目标GPIO端口及其对应的引脚进行标准的初始化设置,确保这些引脚被配置成交替功能推挽输出或其他适当的工作方式。 #### 实际应用案例 下面给出一段针对N32G457芯片将USART1_TXD和RXD分别重映射至PA9和PA10之外其他位置的具体代码实例。这里假设希望把它们重新分配给PB6(PA9替代) 和 PB7(PA10替代)[^3]。 ```c #include "n32g457.h" void UART_Remap_Config(void){ /* 使能相关外设时钟 */ RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_AFIO | RCC_APB2PERIPH_GPIOB, ENABLE); /* 设置为部分重映射模式 */ GPIO_PinRemapConfig(GPIO_PartialRemap_USART1, ENABLE); /* 初始化PB6(TX), PB7(RX)*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // TX Pin Configuration GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_Init(GPIOB,&GPIO_InitStructure); // RX Pin Configuration GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; GPIO_Init(GPIOB,&GPIO📐⚗⚗ ⚗⚗⚗<tool_call>📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐📐⚗⚗⚗ 📐📐📐
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值