USART(Universal Synchronous Asynchronous Receiver Transmitter)是一种串行通信接口,可以支持异步和同步通信模式。在STM32F1系列单片机中,USART接口用于实现与外部设备的串行数据通信,例如与其他单片机、计算机、传感器等设备进行数据交换。USART接口可以配置为多种通信模式,包括UART(Universal Asynchronous Receiver Transmitter)模式和SMARTCARD模式等。
全双工通信:USART接口支持同时发送和接收数据。
多种通信模式:支持异步(UART)和同步(SPI)模式。
灵活的波特率设置:可以通过软件配置多种波特率,以适应不同的通信需求。
多种数据帧格式:支持8位、9位数据长度,可以选择不同的停止位和校验位。
中断和DMA支持:可以使用中断或DMA进行数据传输,提高通信效率。
多种触发条件:支持多种中断触发条件,如接收数据完成、发送数据完成、错误检测等。
USART接口广泛应用于各种嵌入式系统中,常见的应用场景包括:
与PC通信:通过串行通信与PC进行数据交换,常用于调试和数据采集。
与传感器通信:读取传感器数据,如温度、湿度等。
与外部设备通信:与其他单片机或模块进行数据通信,实现协同工作。
STM32F1系列单片机的USART接口主要由以下几个寄存器组成:
USART_SR(Status Register):状态寄存器,用于指示USART的工作状态。
USART_DR(Data Register):数据寄存器,用于读取或写入数据。
USART_BRR(Baud Rate Register):波特率寄存器,用于设置通信速度。
USART_CR1(Control Register 1):控制寄存器1,用于配置基本功能。
USART_CR2(Control Register 2):控制寄存器2,用于配置高级功能。
USART_CR3(Control Register 3):控制寄存器3,用于配置通信模式和流量控制。
USART_GTPR(Guard Time and Prescaler Register):保护时间和预分频寄存器,用于配置SMARTCARD模式。
PE(Parity Error):奇偶校验错误标志。
FE(Framing Error):帧错误标志。
NE(Noise Error):噪声错误标志。
ORE(Overrun Error):溢出错误标志。
IDLE(Idle Line Detected):空闲线检测标志。
RXNE(Read Data Register Not Empty):读数据寄存器非空标志。
TC(Transmission Complete):传输完成标志。
TXE(Transmit Data Register Empty):写数据寄存器空标志。
LBDF(LIN Break Detected Flag):LIN中断标志。
CTS(Clear To Send):清除发送标志。
CTSIF(CTS Interrupt Flag):CTS中断标志。
REACK(Receiver Break Acknowledge):接收器中断标志。
TEACK(Transmitter Break Acknowledge):发送器中断标志。
RTOF(Receiver Time Out):接收超时标志。
DIV_Fraction[3:0]:波特率分频的分数部分。
DIV_Mantissa[11:4]:波特率分频的整数部分。
UE(USART Enable):USART使能位。
UESM(USART in Mode 11110): USART模式。
RE(Receiver Enable):接收器使能位。
TE(Transmitter Enable):发送器使能位。
RTE(Receiver Time Out Enable):接收超时使能位。
IDLEIE(Idle Line Interrupt Enable):空闲线中断使能位。
RXNEIE(RXNE Interrupt Enable):读数据寄存器非空中断使能位。
TCIE(Transmission Complete Interrupt Enable):传输完成中断使能位。
TXEIE(TXE Interrupt Enable):写数据寄存器空中断使能位。
PS(Parity Selection):奇偶校验选择位。
PCE(Parity Control Enable):奇偶校验使能位。
WAKE(Wake-up Method):唤醒方法选择位。
M(Word Length):数据长度选择位。
UE(USART Enable):USART使能位。
OVER8(Oversampling by 8-bit or 16-bit):8位或16位过采样选择位。
LINEN(LIN mode enable):LIN模式使能位。
STOP[1:0]:停止位选择位。
CLKEN(Clock Enable):时钟使能位。
CPOL(Clock Polarity):时钟极性选择位。
CPHA(Clock Phase):时钟相位选择位。
LBCL(Last Bit Clock Pulse):最后一位时钟脉冲选择位。
ADD[3:0]:地址位。
RTSEN(RTS Enable):RTS使能位。
CTSEN(CTS Enable):CTS使能位。
ONEBIT(One-sample bit method enable):单样本位方法使能位。
OVRDIS(Overrun Disable):溢出禁用位。
DMAR(DMA Enable Receiver):DMA接收使能位。
DMAT(DMA Enable Transmitter):DMA发送使能位。
SCEN(SmartCard mode enable):SMARTCARD模式使能位。
HSE(Half-duplex mode enable):半双工模式使能位。
IRLP(IrDA Low-Power mode):IrDA低功耗模式选择位。
IREN(IrDA mode enable):IrDA模式使能位。
EIE(Error Interrupt Enable):错误中断使能位。
GT[7:0]:保护时间,用于SMARTCARD模式。
PSC[7:0]:预分频器值,用于SMARTCARD模式。
在使用USART接口之前,需要进行初始化配置。初始化过程包括配置波特率、数据格式、中断和DMA等。以下是一个详细的初始化步骤:
波特率决定了数据传输的速度,可以通过USART_BRR寄存器进行配置。波特率的计算公式如下:
KaTeX parse error: Expected 'EOF', got '_' at position 58: …es (\text{USART_̲DIV})}
其中,USART_DIV
是USART_BRR寄存器的值。
数据格式包括数据长度、停止位和校验位。通过USART_CR1和USART_CR2寄存器进行配置。
数据长度:通过USART_CR1寄存器的M
位配置,0为8位,1为9位。
停止位:通过USART_CR2寄存器的STOP
位配置,00为1位停止位,01为0.5位停止位,10为1.5位停止位,11为2位停止位。
校验位:通过USART_CR1寄存器的PCE
和PS
位配置,PCE
为1时启用校验,PS
为0时选择偶校验,PS
为1时选择奇校验。
可以通过USART_CR1寄存器的中断使能位配置中断,例如RXNEIE
位用于使能接收数据完成中断。
DMA(Direct Memory Access)可以用于高效的数据传输。通过USART_CR3寄存器的DMAR
和DMAT
位配置DMA接收和发送。
以下是一个使用STM32F103C8T6的USART1接口进行初始化的代码示例:
#include "stm32f10x.h"
// 初始化USART1
void USART1_Init(void) {
// 使能GPIO和USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的TX和RX引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // PA9为TX,PA10为RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; // 波特率9600
USART_InitStructure.USART_WordLength = USART_WordLength_8Bits; // 8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 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(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 使能接收数据完成中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// USART1中断处理函数
void USART1_IRQHandler(void) {
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
// 读取接收到的数据
uint8_t data = USART_ReceiveData(USART1);
// 处理数据
// 例如:发送回收到的数据
USART_SendData(USART1, data);
// 清除中断标志
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
// 主函数
int main(void) {
// 初始化USART1
USART1_Init();
// 无限循环
while (1) {
// 主循环中的其他代码
}
}
使能GPIO和USART1的时钟:通过RCC_APB2PeriphClockCmd
函数使能GPIO和USART1的时钟。
配置USART1的TX和RX引脚:使用GPIO_InitTypeDef
结构体配置PA9和PA10引脚为复用推挽输出模式。
配置USART1:使用USART_InitTypeDef
结构体配置USART1的波特率、数据长度、停止位、校验位、硬件流控制和通信模式。
使能USART1:通过USART_Cmd
函数使能USART1。
使能接收数据完成中断:通过USART_ITConfig
函数使能USART1的接收数据完成中断。
配置NVIC:使用NVIC_InitTypeDef
结构体配置NVIC,使能USART1的中断。
USART1中断处理函数:在中断处理函数中,读取接收到的数据并发送回该数据,然后清除中断标志。
异步数据传输是最常用的通信模式。在这种模式下,数据的发送和接收不需要同步时钟信号。
发送数据时,需要将数据写入USART_DR寄存器。当USART_DR寄存器为空时,数据会自动发送。
void USART1_Send(uint8_t data) {
// 等待发送寄存器为空
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// 发送数据
USART_SendData(USART1, data);
}
// 发送字符串
void USART1_SendString(char *str) {
while (*str) {
USART1_Send(*str++);
}
}
接收数据时,需要读取USART_DR寄存器。当USART_DR寄存器非空时,数据可以被读取。
uint8_t USART1_Receive(void) {
// 等待接收寄存器非空
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
// 读取数据
return USART_ReceiveData(USART1);
}
// 接收字符串
void USART1_ReceiveString(char *str, uint8_t length) {
for (uint8_t i = 0; i < length; i++) {
str[i] = USART1_Receive();
}
}
同步数据传输需要外部时钟信号。在STM32F1系列中,USART接口可以配置为同步模式,但不常用。同步模式的配置与异步模式类似,主要区别在于时钟信号的配置。
DMA(Direct Memory Access)可以用于高效的数据传输,特别是在需要大量数据传输时。以下是一个使用DMA进行数据传输的代码示例:
void DMA_Config(void) {
// 使能DMA1的时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 配置DMA1通道4(USART1_TX)
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&txBuffer);
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = TX_BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
// 配置DMA1通道5(USART1_RX)
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)(&rxBuffer);
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
// 使能DMA1通道4和5
DMA_Cmd(DMA1_Channel4, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
// 使能USART1的DMA发送和接收
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
}
uint8_t txBuffer[TX_BUFFER_SIZE] = "Hello, World!";
uint8_t rxBuffer[RX_BUFFER_SIZE];
void USART1_SendDMA(uint8_t *data, uint8_t length) {
// 配置DMA传输
DMA_SetCurrDataCounter(DMA1_Channel4, length);
DMA_SetMemoryAddress(DMA1_Channel4, (uint32_t)data);
// 使能DMA传输
DMA_Cmd(DMA1_Channel4, ENABLE);
}
void USART1_ReceiveDMA(uint8_t *data, uint8_t length) {
// 配置DMA传输
DMA_SetCurrDataCounter(DMA1_Channel5, length);
DMA_SetMemoryAddress(DMA1_Channel5, (uint32_t)data);
// 使能DMA传输
DMA_Cmd(DMA1_Channel5, ENABLE);
}
// 主函数
int main(void) {
// 初始化USART1
USART1_Init();
// 配置DMA
DMA_Config();
// 发送数据
USART1_SendDMA(txBuffer, sizeof(txBuffer));
// 接收数据
USART1_ReceiveDMA(rxBuffer, RX_BUFFER_SIZE);
// 无限循环
while (1) {
// 主循环中的其他代码
}
}
使能DMA1的时钟:通过RCC_AHBPeriphClockCmd
函数使能DMA1的时钟。
配置DMA1通道4(USART1_TX):使用DMA_InitTypeDef
结构体配置DMA1通道4,用于USART1的发送数据。DMA_PeripheralBaseAddr
设置为USART1的数据寄存器地址,DMA_MemoryBaseAddr
设置为发送缓冲区地址,DMA_DIR
设置为DMA_DIR_PeripheralDST
(外设作为目标),DMA_BufferSize
设置为缓冲区大小,DMA_PeripheralInc
设置为DMA_PeripheralInc_Disable
(外设地址不递增),DMA_MemoryInc
设置为DMA_MemoryInc_Enable
(内存地址递增),DMA_PeripheralDataSize
和DMA_MemoryDataSize
设置为DMA_PeripheralDataSize_Byte
(单字节传输),DMA_Mode
设置为DMA_Mode_Normal
(正常模式),DMA_Priority
设置为DMA_Priority_High
(高优先级),DMA_M2M
设置为DMA_M2M_Disable
(禁止内存到内存传输)。
配置DMA1通道5(USART1_RX):使用DMA_InitTypeDef
结构体配置DMA1通道5,用于USART1的接收数据。DMA_DIR
设置为DMA_DIR_PeripheralSRC
(外设作为源),其他配置与发送通道类似。
使能DMA1通道4和5:通过DMA_Cmd
函数使能DMA1的通道4和5。
使能USART1的DMA发送和接收:通过USART_DMACmd
函数使能USART1的DMA发送和接收请求。
发送数据:通过USART1_SendDMA
函数发送数据。首先设置当前数据计数器和内存地址,然后使能DMA传输。
接收数据:通过USART1_ReceiveDMA
函数接收数据。首先设置当前数据计数器和内存地址,然后使能DMA传输。
USART接口支持硬件流量控制,可以通过RTS(Request to Send)和CTS(Clear to Send)信号来控制数据的传输。这种方式可以防止数据丢失和溢出。
在配置硬件流量控制时,需要确保RTS和CTS引脚已经正确配置,并且通过USART_CR3寄存器启用硬件流控制功能。以下是一个配置硬件流量控制的代码示例:
void USART1_InitWithFlowControl(void) {
// 使能GPIO和USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的TX、RX、RTS和CTS引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; // PA9为TX,PA10为RX,PA11为RTS,PA12为CTS
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; // 波特率9600
USART_InitStructure.USART_WordLength = USART_WordLength_8Bits; // 8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1位停止位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS; // 使能硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 使能接收和发送
USART_Init(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 使能接收数据完成中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
奇偶校验是一种简单的错误检测方法,可以在数据传输过程中检测到某些错误。通过USART_CR1寄存器的PCE
和PS
位可以配置奇偶校验。
在配置奇偶校验时,需要通过USART_CR1寄存器的PCE
位启用奇偶校验,并通过PS
位选择奇校验或偶校验。以下是一个配置奇偶校验的代码示例:
void USART1_InitWithParity(void) {
// 使能GPIO和USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的TX和RX引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // PA9为TX,PA10为RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; // 波特率9600
USART_InitStructure.USART_WordLength = USART_WordLength_8Bits; // 8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 1位停止位
USART_InitStructure.USART_Parity = USART_Parity_Odd; // 选择奇校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 使能接收和发送
USART_Init(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 使能接收数据完成中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
USART接口还支持低功耗模式,可以在不需要通信时关闭时钟或进入低功耗状态,以节省功耗。
在配置低功耗模式时,可以通过关闭USART1的时钟或使用USART的低功耗模式来实现。以下是一个示例代码:
void USART1_EnterLowPowerMode(void) {
// 关闭USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE);
// 关闭USART1
USART_Cmd(USART1, DISABLE);
}
void USART1_ExitLowPowerMode(void) {
// 使能USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 使能USART1
USART_Cmd(USART1, ENABLE);
}
在数据传输过程中,可能会出现各种错误,如奇偶校验错误、帧错误、噪声错误等。可以通过中断或轮询方式检测这些错误并进行处理。
在配置错误中断时,需要通过USART_CR1寄存器的EIE
位启用错误中断,并在中断处理函数中检查具体的错误类型。以下是一个配置错误中断的代码示例:
void USART1_InitWithErrorInterrupt(void) {
// 使能GPIO和USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的TX和RX引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // PA9为TX,PA10为RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; // 波特率9600
USART_InitStructure.USART_WordLength = USART_WordLength_8Bits; // 8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 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(USART1, &USART_InitStructure);
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 使能接收数据完成中断和错误中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_ERROR, ENABLE);
// 配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
// USART1中断处理函数
void USART1_IRQHandler(void) {
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
// 读取接收到的数据
uint8_t data = USART_ReceiveData(USART1);
// 处理数据
// 例如:发送回收到的数据
USART_SendData(USART1, data);
// 清除中断标志
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
if (USART_GetITStatus(USART1, USART_IT_ERROR) != RESET) {
// 检查具体的错误类型
if (USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET) {
// 奇偶校验错误
USART_ClearFlag(USART1, USART_FLAG_PE);
}
if (USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET) {
// 帧错误
USART_ClearFlag(USART1, USART_FLAG_FE);
}
if (USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET) {
// 噪声错误
USART_ClearFlag(USART1, USART_FLAG_NE);
}
if (USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) {
// 溢出错误
USART_ClearFlag(USART1, USART_FLAG_ORE);
}
// 清除错误中断标志
USART_ClearITPendingBit(USART1, USART_IT_ERROR);
}
}
LIN(Local Interconnect Network)模式是一种单主多从的通信协议,常用于汽车电子系统。通过USART_CR2寄存器的LINEN
位可以启用LIN模式。
SMARTCARD模式用于与智能卡进行通信。通过USART_CR3寄存器的SCEN
位可以启用SMARTCARD模式。此外,还需要配置保护时间和预分频器值。
void USART1_InitSMARTCARD(void) {
// 使能GPIO和USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的TX和RX引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // PA9为TX,PA10为RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; // 波特率9600
USART_InitStructure.USART_WordLength = USART_WordLength_8Bits; // 8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 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(USART1, &USART_InitStructure);
// 使能SMARTCARD模式
USART_CR3->SCEN = 1; // 启用SMARTCARD模式
USART_GTPR->PSC = 0; // 设置预分频器值
USART_GTPR->GT = 1; // 设置保护时间为1
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 使能接收数据完成中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
IrDA(Infrared Data Association)模式用于红外数据通信。通过USART_CR3寄存器的IREN
位可以启用IrDA模式。此外,还需要配置低功耗模式。
void USART1_InitIrDA(void) {
// 使能GPIO和USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1的TX和RX引脚
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // PA9为TX,PA10为RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600; // 波特率9600
USART_InitStructure.USART_WordLength = USART_WordLength_8Bits; // 8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 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(USART1, &USART_InitStructure);
// 使能IrDA模式
USART_CR3->IREN = 1; // 启用IrDA模式
USART_CR3->IRLP = 1; // 选择低功耗模式
// 使能USART1
USART_Cmd(USART1, ENABLE);
// 使能接收数据完成中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
USART接口在STM32F1系列单片机中是一个非常强大的串行通信接口,支持多种通信模式和高级功能。通过合理配置波特率、数据格式、中断和DMA,可以实现高效、可靠的串行通信。高级功能如流量控制、奇偶校验、低功耗模式、LIN模式、SMARTCARD模式和IrDA模式,可以进一步提高系统的灵活性和可靠性。希望本文的内容能帮助你更好地理解和使用STM32F1系列单片机的USART接口。