STM32中的串口UART知识点以及标准库的使用方法

叠个甲:部分素材来自B站UP主铁头山羊

目录

一、UART基本概念

[表格部分:USART 引脚配置](#表格部分:USART 引脚配置)

二、UART原理图

主要特性包括:

三、标准库相关函数

[1. 初始化相关函数](#1. 初始化相关函数)

[1.1 UART初始化函数](#1.1 UART初始化函数)

[2. GPIO配置相关函数](#2. GPIO配置相关函数)

[3. 数据传输函数](#3. 数据传输函数)

3.1数据发送函数

3.2数据接收函数

[4. 状态和标志位函数](#4. 状态和标志位函数)

4.1标志位状态函数

4.2标志位清除函数

[5. 中断相关函数](#5. 中断相关函数)

5.1中断配置函数

5.2中断状态检查函数

5.3中断标志清除函数

四、常用标志位和中断

标志位(USART_FLAG):

中断(USART_IT):

五、完整使用流程示例

场景1:查询方式收发数据

场景2:中断方式接收数据

六、总结(summary)


一、UART基本概念

UART(Universal Asynchronous Receiver/Transmitter) 是通用异步收发传输器,是一种串行通信接口,用于设备之间的异步通信。

主要特点:

  • 异步通信 :不需要时钟线同步

  • 全双工 :可同时发送和接收数据

  • 点对点 :通常用于两个设备之间的通信

  • 可配置参数 :波特率、数据位、停止位、校验位等

这张图片详细介绍了 USART(通用同步异步收发器) 的引脚配置、GPIO(通用输入输出)模式以及不同工作模式下的连接方式。

表格部分:USART 引脚配置

表格列出了 USART 的主要引脚、在不同模式下的配置,以及对应的 GPIO 配置。

  • USARTx_TX(发送引脚)

    • 在全双工模式和半双工同步模式下,GPIO 配置为推挽复用输出
    • 作用:负责发送数据。
  • USARTx_RX(接收引脚)

    • 在全双工模式下,GPIO 配置为浮空输入或带上拉输入
    • 在半双工同步模式下,该引脚未使用,可作为通用 I/O 口。
    • 作用:负责接收数据。
  • USARTx_CK(时钟引脚)

    • 仅在同步模式下使用,GPIO 配置为推挽复用输出
    • 作用:提供同步通信所需的时钟信号。
  • USARTx_RTS(请求发送,硬件流控)

    • 用于硬件流控制,GPIO 配置为推挽复用输出
    • 作用:发送"准备好接收"信号,通知对方可以发送数据。
  • USARTx_CTS(清除发送,硬件流控)

    • 用于硬件流控制,GPIO 配置为浮空输入或带上拉输入
    • 作用:接收"准备好接收"信号,控制是否允许发送数据。

这张图片展示了**USART(通用同步异步收发器)**在异步通信模式下的两种数据帧格式。它主要对比了不带校验位(8位数据)和带校验位(9位数据)两种情况下的数据结构。

二、UART原理图

STM32系列微控制器通常配备多个UART/USART接口

主要特性包括:

  1. 多通道支持 :STM32F103系列通常有3-5个USART/UART

  2. 可编程波特率 :支持多种波特率(如9600、115200等)

  3. DMA支持 :可使用DMA进行数据传输,减轻CPU负担

  4. 多种中断 :发送完成、接收完成、错误等中断

  5. 硬件流控 :支持RTS/CTS硬件流控制

三、标准库相关函数

1. 初始化相关函数

cpp 复制代码
// UART初始化结构体
typedef struct {
    uint32_t USART_BaudRate;            // 波特率
    uint16_t USART_WordLength;          // 数据位长度 (8位或9位)
    uint16_t USART_StopBits;            // 停止位
    uint16_t USART_Parity;              // 校验位
    uint16_t USART_Mode;                // 模式 (发送/接收)
    uint16_t USART_HardwareFlowControl; // 硬件流控
} USART_InitTypeDef;

// 初始化UART
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);

// 使能UART时钟
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);

1.1 UART初始化函数

作用 :配置UART的通信参数(波特率、数据位、停止位等)

cpp 复制代码
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);

参数说明 :

  • USARTx :UART外设(如 USART1 )。

  • USART_InitStruct :UART初始化结构体,包含以下成员:

  • USART_BaudRate :波特率(如9600、115200等)。

  • USART_WordLength :数据位长度( USART_WordLength_8b 或 USART_WordLength_9b )。

  • USART_StopBits :停止位( USART_StopBits_1 、 USART_StopBits_0_5 、 USART_StopBits_2 等)。

  • USART_Parity :校验位( USART_Parity_No 、 USART_Parity_Even 、 USART_Parity_Odd )。

  • USART_Mode :工作模式( USART_Mode_Rx | USART_Mode_Tx 表示同时开启收发)。

  • USART_HardwareFlowControl :硬件流控(通常为 USART_HardwareFlowControl_None )。

使用示例 :

cpp 复制代码
USART_InitTypeDef USART_InitStructure;

// 配置UART参数
USART_InitStructure.USART_BaudRate = 115200;  // 波特率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);

2. GPIO配置相关函数

cpp 复制代码
// GPIO初始化结构体
typedef struct {
    uint16_t GPIO_Pin;             // 引脚号
    GPIOSpeed_TypeDef GPIO_Speed;  // 速度
    GPIOMode_TypeDef GPIO_Mode;   // 模式
} GPIO_InitTypeDef;

// 初始化GPIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

// 复用功能配置
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);

3. 数据传输函数

cpp 复制代码
// 发送单个字节
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

// 接收单个字节
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

// 发送数据块
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

// 接收数据块
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

3.1数据发送函数

作用 :发送单个字节数据。

cpp 复制代码
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

参数说明 :

  • USARTx :UART外设。

  • Data :待发送的数据(低8位有效,高8位无意义)。

使用注意 :

  • 发送前必须等待 TXE标志位 (发送数据寄存器为空),否则会覆盖未发送完成的数据。

使用示例 :

cpp 复制代码
void UART1_SendByte(uint8_t data)
{
    // 等待发送数据寄存器为空(TXE标志置位)
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    
    // 发送数据
    USART_SendData(USART1, data);
}

3.2数据接收函数

作用 :接收单个字节数据。

cpp 复制代码
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

参数说明 :

  • USARTx :UART外设。

返回值 :接收到的数据(低8位有效)。

使用注意 :

  • 接收前必须等待 RXNE标志位 (接收数据寄存器非空),否则会读取无效数据。

使用示例 :

cpp 复制代码
uint8_t UART1_ReceiveByte(void)
{
    // 等待接收数据寄存器非空(RXNE标志置位)
    while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    
    // 读取并返回数据
    return USART_ReceiveData(USART1);
}

4. 状态和标志位函数

cpp 复制代码
// 获取标志位状态
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);

// 清除标志位
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

// 获取中断标志位
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

// 清除中断标志位
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);

4.1标志位状态函数

作用 :检查UART的状态标志位(如TXE、RXNE等)。

cpp 复制代码
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);

参数说明 :

  • USARTx :UART外设。

  • USART_FLAG :要检查的标志位(如 USART_FLAG_TXE 、 USART_FLAG_RXNE 等)。

返回值 : SET (标志置位)或 RESET (标志未置位)。

使用场景 :

  • 发送前检查 USART_FLAG_TXE 确保数据寄存器为空。

  • 接收前检查 USART_FLAG_RXNE 确保有数据可读。

  • 发送完成后检查 USART_FLAG_TC 确保数据完全发送(适用于需要等待发送结束的场景)。

4.2标志位清除函数

作用 :清除UART的状态标志位(如TC等)。

cpp 复制代码
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

参数说明 :

  • USARTx :UART外设。

  • USART_FLAG :要清除的标志位(如 USART_FLAG_TC )。

使用场景 :

  • 发送完成后清除 USART_FLAG_TC 标志,避免后续判断错误。

5. 中断相关函数

cpp 复制代码
// 使能/失能中断
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);

// 使能/失能UART
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

5.1中断配置函数

作用 :使能或禁用UART的中断(如接收中断、发送中断等)。

cpp 复制代码
void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);

参数说明 :

  • USARTx :UART外设。

  • USART_IT :要配置的中断类型(如 USART_IT_RXNE 、 USART_IT_TXE 等)。

  • NewState :使能状态( ENABLE 或 DISABLE )。

使用场景 :

  • 需要通过中断处理数据时(如接收数据),需先调用此函数使能对应中断。

5.2中断状态检查函数

作用 :检查UART的中断标志位(用于中断服务函数中判断中断来源)。

cpp 复制代码
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

参数说明 :

  • USARTx :UART外设。

  • USART_IT :要检查的中断类型。

返回值 : SET (中断触发)或 RESET (中断未触发)。

使用场景 :

  • 在中断服务函数中判断具体是哪种中断触发(如接收中断还是发送完成中断)。

5.3中断标志清除函数

作用 :清除UART的中断标志位(避免重复触发中断)。

cpp 复制代码
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);

参数说明 :

  • USARTx :UART外设。

  • USART_IT :要清除的中断类型。

使用场景 :

  • 在中断服务函数中处理完中断后,必须调用此函数清除中断标志位。

四、常用标志位和中断

标志位(USART_FLAG):

  • USART_FLAG_TXE :发送数据寄存器为空

  • USART_FLAG_TC :发送完成

  • USART_FLAG_RXNE :接收数据寄存器非空

  • USART_FLAG_IDLE :空闲线路检测

  • USART_FLAG_ORE :溢出错误

  • USART_FLAG_NE :噪声错误

  • USART_FLAG_FE :帧错误

  • USART_FLAG_PE :校验错误

中断(USART_IT):

  • USART_IT_TXE :发送数据寄存器空中断

  • USART_IT_TC :发送完成中断

  • USART_IT_RXNE :接收数据寄存器非空中断

  • USART_IT_IDLE :空闲线路中断

  • USART_IT_PE :校验错误中断

  • USART_IT_ERR :错误中断

五、完整使用流程示例

场景1:查询方式收发数据

步骤 :初始化UART → 发送/接收数据(通过查询标志位)。

cpp 复制代码
// 1. 初始化UART1
void UART1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    
    // 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置TX引脚(PA9)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置RX引脚(PA10)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置UART参数
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_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);
    
    // 使能UART
    USART_Cmd(USART1, ENABLE);
}

// 2. 发送字符串
void UART1_SendString(char *str)
{
    while (*str != '\0')
    {
        UART1_SendByte(*str);  // 调用发送单个字节的函数
        str++;
    }
}

// 3. 主函数中使用
int main(void)
{
    UART1_Init();
    
    // 发送字符串
    UART1_SendString("Hello STM32!\r\n");
    
    // 接收单个字节并回显
    uint8_t rx_data = UART1_ReceiveByte();
    UART1_SendByte(rx_data);
    
    while (1);
}

场景2:中断方式接收数据

步骤 :初始化UART → 配置NVIC中断 → 使能接收中断 → 在中断服务函数中处理数据。

cpp 复制代码
// 1. 初始化UART1(含中断)
void UART1_Init_IT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    // 开启时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    
    // 配置TX/RX引脚(同场景1)
    // ...(省略GPIO配置代码,与场景1相同)
    
    // 配置UART参数(同场景1)
    // ...(省略UART参数配置代码,与场景1相同)
    
    // 使能UART
    USART_Cmd(USART1, ENABLE);
    
    // 配置NVIC中断
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  // USART1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  // 使能通道
    NVIC_Init(&NVIC_InitStructure);
    
    // 使能接收中断(RXNE)
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}

// 2. 中断服务函数
void USART1_IRQHandler(void)
{
    uint8_t rx_data;
    
    // 检查是否为接收中断(RXNE)
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        // 读取接收到的数据
        rx_data = USART_ReceiveData(USART1);
        
        // 处理数据(例如回显)
        USART_SendData(USART1, rx_data);
        
        // 清除接收中断标志位
        USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    }
}

// 3. 主函数中使用
int main(void)
{
    UART1_Init_IT();
    
    while (1)
    {
        // 主循环可执行其他任务
    }
}

六、总结(summary)

STM32标准库中UART函数的使用流程可归纳为:

  1. 时钟使能 :开启UART和GPIO的时钟。

  2. GPIO配置 :设置TX为复用推挽输出,RX为浮空输入。

  3. UART参数配置 :设置波特率、数据位、停止位等。

  4. UART使能 :调用 USART_Cmd 使能UART。

  5. 数据收发 :

  • 查询方式:通过 USART_GetFlagStatus 等待标志位后收发数据。

  • 中断方式:配置NVIC和中断,在中断服务函数中处理数据。

  1. 错误处理 :检查并处理 ORE 、 FE 等错误标志。
相关推荐
不做无法实现的梦~11 小时前
ros2实现路径规划---nav2部分
linux·stm32·嵌入式硬件·机器人·自动驾驶
熊猫_豆豆16 小时前
同步整流 Buck 降压变换器
单片机·嵌入式硬件·matlab
chenchen0000000020 小时前
49元能否买到四核性能?HZ-RK3506G2_MiniEVM开发板评测:MCU+三核CPU带来的超高性价比
单片机·嵌入式硬件
孤芳剑影20 小时前
反馈环路设计总结
嵌入式硬件·学习
dump linux1 天前
设备树子系统与驱动开发入门
linux·驱动开发·嵌入式硬件
专注VB编程开发20年1 天前
简易虚拟 PLC 服务器-流水线自动化,上位机程序维护升级,西门子PLC仿真
服务器·单片机·自动化·上位机·plc·流水线·工控
LeoZY_1 天前
CH347/339W开源项目:集SPI、I2C、JTAG、SWD、UART、GPIO多功能为一体(3)
stm32·单片机·嵌入式硬件·mcu·开源
chenchen000000001 天前
国产显示芯势力新篇章:内置DDR+四核A35!MY-SSD2351-MINI开发板深度评测
驱动开发·嵌入式硬件
BackCatK Chen1 天前
第13篇:TMC2240 StallGuard4失速检测|寄存器配置+状态读取(保姆级)
单片机·嵌入式硬件·tmc2240·stm32实战·stallguard4·失速检测·电机故障识别
Hello_Embed1 天前
libmodbus STM32 板载串口实验(双串口主从通信)
笔记·stm32·单片机·学习·modbus