STM32 USART学习
2025-11-06 来源:bilibili
USART(同步异步串口通信)
在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互联网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。还可以使用DMA方式,实现高速数据通信
STM32 中的USART框图

框图
1、引脚编号
TX:发送数据输出
RX:接收数据串行输入
SCLK(位于最右边):发送器时钟输出,仅同步通信时使用
nRTS:请求发送(Request To Send)
nCTS:允许发送(Clear To Send)
SW_RX:数据接收引脚,属于内部引脚。
2、数据寄存器
数据寄存器(USART_DR)只有低9位有效,实际上它包含一个发送数据寄存器USART_TDR和一个接收数据寄存器USART_RDR。TDR和RDR都是介于系统总线和移位寄存器之间。这里比较特别:一个地址对应了两个物理内存。
当进行发送操作时,往USART_DR写入数据会自动存储在 TDR内,然后把内容转移到发送移位寄存器,最后通过模块发送到TX引脚;
当进行读取操作时,信息从RX引脚进入,通过模块后存入接受移位寄存器,然后把内容转移到RDR内,最后USART_DR提取RDR数据。
3、控制器
USART有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等。
控制寄存器1(USART_CR1)的TE位负责使能发送器,发送器就会“叫醒”发送移位寄存器。
控制寄存器1(USART_CR1)的RX位负责使能接收器,接收器就会“叫醒”接收移位寄存器。
控制寄存器1的TXEIE或RXNEIE置1可以产生中断。
控制寄存器1其他位:TXE:发送移位寄存器为空,发送单个字节时使用。TC:发送完成,发送多个字节数据时候使用。TXIE:发送完成中断使能。
控制寄存器1的M位设置的是字长,该位定义了数据字的长度,由软件对其设置和清零。设置0:一个起始位,8个数据位;设置1:一个起始位,9个数据位。之前已经说过,数据寄存器(USART_DR)只有低9位有效,并且第9位数据是否有效要取决于控制寄存器1的M位设置。
控制寄存器2(USART_CR2)的STOP[1:0]位用于设置停止位,可选0.5个、1个、1.5个、2个停止位。默认使用1个停止位。2个停止位适用于正常USART模式、单线模式和调制解调器模式。0.5和1.5个停止位用于智能卡模式
4、波特率
通过波特率寄存器(USART_BRR)可设置波特率。由于计算出的分频因子有小数,因此寄存器分为两个部分:
DIV_Mantissa[11:0]:USARTDIV的整数部分,这12位定义了USART分频器除法因子(USARTDIV)的整数部分。
DIV_Fraction[3:0]:USARTDIV的小数部分,这4位定义了USART分频器除法因子(USARTDIV)的小数部分。
波特比率的计算公式为:


但开发中调用库函数只需调用库函数
USART.c
#include "USART.h" // Device header
#include "stdio.h"
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置 USART 为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级为 1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级为 1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置 NVIC */
NVIC_Init(&NVIC_InitStructure);
}
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);
}
/***************** 发送一个字符 **********************/
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)!='




