目录
++[1. STM32的串口通信概述](#1. STM32的串口通信概述)++
++[2. 串口通信的发送与接收机制](#2. 串口通信的发送与接收机制)++
++[- 串口发送](#- 串口发送)++
++[- 串口接收](#- 串口接收)++
++[3. STM32中串口的配置方法](#3. STM32中串口的配置方法)++
++[4. 串口接收的两种实现方式](#4. 串口接收的两种实现方式)++
++[- 查询RXNE标志位](#- 查询RXNE标志位)++
++[- 使用中断](#- 使用中断)++
++[5. 总结](#5. 总结)++
STM32的串口通信
本文旨在记录学习过程中遇到的问题,并对串口通信在STM32中的应用进行总结。串口通信在STM32的实际使用中占据重要地位,本文将对其进行全面梳理。
- STM32的串口通信概述
在STM32中,串口通信通过USART实现,支持与其他设备进行全双工、异步时钟控制的点对点数据传输。其对应的引脚为RX和TX,且STM32提供了USART1、USART2、USART3等多个串口资源。
串口通信的关键参数包括:
-
波特率:决定通信速率。
-
空闲位:通常为高电平。
-
起始位:低电平,标志数据帧的开始。
-
数据位:1为高电平,0为低电平,低位先行。
-
校验位:用于数据验证,可选奇校验、偶校验或无校验。
-
停止位:高电平,用于数据间隔。
数据传输以数据帧形式进行,每个数据帧由起始位、数据位和停止位组成,停止位可根据需求调整。

- 串口通信的发送与接收机制
USART是STM32内部集成的硬件外设,能够自动生成数据帧时序并发送数据,同时也能接收数据帧并将其拼接成字节数据存储在寄存器中。配置好USART后,可通过读取数据寄存器实现数据的发送与接收。
串口发送与接收涉及以下重要寄存器:
-
发送数据寄存器(TDR):用于写入待发送数据。
-
发送移位寄存器:将数据逐位移出。
-
接收数据寄存器(RDR):存储接收到的数据。
-
接收移位寄存器:逐位读取RX引脚电平。

**串口发送**
在配置串口参数时,可选择8位或9位数据位。发送数据时,对TDR寄存器进行写操作,具体过程如下:
-
检测发送移位寄存器是否正在移位。若无移位,则数据立即转移至移位寄存器,准备发送。
-
数据移位时,TXE标志位被置1,表示TDR寄存器为空,可写入下一个数据。
-
发送移位寄存器在发送器控制下向右移位,将数据逐位传输至TX引脚。
-
数据移位完成后,TDR中的新数据再次转移到移位寄存器,重复上述过程。

**串口接收**
数据从RX引脚进入接收移位寄存器,逐位读取电平,移位八次后完成一个字节的接收。接收完成后,数据移至RDR寄存器,并置RXNE标志位,表示数据可读。

- STM32中串口的配置方法
配置串口时,需明确以下几点:使用哪个串口外设、发送还是接收数据、相关参数配置以及是否使用中断。以下是串口发送的配置步骤:
- 开启USART及GPIO时钟。
```c
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
```
- 初始化GPIO口。根据需求配置发送或接收引脚,例如:
```c
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // USART2的TX端
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
```
- 初始化串口参数,包括波特率、模式、校验位、停止位和数据位等:
```c
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx; // 发送模式
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART2, &USART_InitStruct);
```
- 使能串口:
```c
USART_Cmd(USART2, ENABLE);
```
- 发送数据时,需判断TXE标志位状态:
```c
void Serial_SendByte(uint16_t Byte) {
USART_SendData(USART2, Byte);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
}
```
- 串口接收的两种实现方式
串口接收可通过查询或中断实现。查询方式通过不断检测RXNE标志位判断数据是否接收完成;中断方式则通过配置中断源和NVIC实现数据接收。

**查询RXNE标志位**
需配置串口RX引脚并添加接收模式:
- 初始化RX引脚:
```c
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &GPIO_InitStructure);
```
- 添加接收模式:
```c
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
```
- 在主程序中检测RXNE标志位:
```c
uint8_t RX_Data;
int main() {
Serial_Init();
Serial_SendByte(0x16);
while (1) {
if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET) {
RX_Data = USART_ReceiveData(USART2);
Serial_SendByte(RX_Data);
}
}
}
```
**使用中断**
通过配置串口接收中断源和NVIC实现接收:
- 配置中断输出控制:
```c
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
```
- 配置NVIC:
```c
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
```
- 编写中断服务函数:
```c
void USART2_IRQHandler(void) {
if (USART_GetITStatus(USART2, USART_IT_RXNE) == SET) {
RX_Data = USART_ReceiveData(USART2);
Flag = 1;
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
}
```
- 总结
本文详细介绍了STM32串口通信的发送与接收机制,以及串口的配置方法和接收实现方式。串口通信在嵌入式系统中应用广泛,掌握其配置与使用方法对于实际开发具有重要意义。如有不足之处,欢迎指正。