STMicroelectronics 系列:STM32F1 系列_(8).STM32F1系列的USART接口及编程

STM32F1系列的USART接口及编程

1. USART接口概述

USART(Universal Synchronous Asynchronous Receiver Transmitter)是一种串行通信接口,可以支持异步和同步通信模式。在STM32F1系列单片机中,USART接口用于实现与外部设备的串行数据通信,例如与其他单片机、计算机、传感器等设备进行数据交换。USART接口可以配置为多种通信模式,包括UART(Universal Asynchronous Receiver Transmitter)模式和SMARTCARD模式等。

在这里插入图片描述

1.1 USART接口的特点

  • 全双工通信:USART接口支持同时发送和接收数据。

  • 多种通信模式:支持异步(UART)和同步(SPI)模式。

  • 灵活的波特率设置:可以通过软件配置多种波特率,以适应不同的通信需求。

  • 多种数据帧格式:支持8位、9位数据长度,可以选择不同的停止位和校验位。

  • 中断和DMA支持:可以使用中断或DMA进行数据传输,提高通信效率。

  • 多种触发条件:支持多种中断触发条件,如接收数据完成、发送数据完成、错误检测等。

1.2 USART接口的应用场景

USART接口广泛应用于各种嵌入式系统中,常见的应用场景包括:

  • 与PC通信:通过串行通信与PC进行数据交换,常用于调试和数据采集。

  • 与传感器通信:读取传感器数据,如温度、湿度等。

  • 与外部设备通信:与其他单片机或模块进行数据通信,实现协同工作。

2. USART接口的硬件结构

2.1 USART寄存器

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模式。

2.2 USART寄存器详解

2.2.1 USART_SR(Status Register)
  • 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):接收超时标志。

2.2.2 USART_DR(Data Register)
  • DR[8:0]:数据寄存器,用于读取或写入数据。如果配置为9位数据长度,第9位数据存储在DR[8]。
2.2.3 USART_BRR(Baud Rate Register)
  • DIV_Fraction[3:0]:波特率分频的分数部分。

  • DIV_Mantissa[11:4]:波特率分频的整数部分。

2.2.4 USART_CR1(Control Register 1)
  • 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位过采样选择位。

2.2.5 USART_CR2(Control Register 2)
  • 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]:地址位。

2.2.6 USART_CR3(Control Register 3)
  • 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):错误中断使能位。

2.2.7 USART_GTPR(Guard Time and Prescaler Register)
  • GT[7:0]:保护时间,用于SMARTCARD模式。

  • PSC[7:0]:预分频器值,用于SMARTCARD模式。

3. USART接口的初始化

在使用USART接口之前,需要进行初始化配置。初始化过程包括配置波特率、数据格式、中断和DMA等。以下是一个详细的初始化步骤:

3.1 配置波特率

波特率决定了数据传输的速度,可以通过USART_BRR寄存器进行配置。波特率的计算公式如下:

KaTeX parse error: Expected 'EOF', got '_' at position 58: …es (\text{USART_̲DIV})}

其中,USART_DIV是USART_BRR寄存器的值。

3.2 配置数据格式

数据格式包括数据长度、停止位和校验位。通过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寄存器的PCEPS位配置,PCE为1时启用校验,PS为0时选择偶校验,PS为1时选择奇校验。

3.3 配置中断

可以通过USART_CR1寄存器的中断使能位配置中断,例如RXNEIE位用于使能接收数据完成中断。

3.4 配置DMA

DMA(Direct Memory Access)可以用于高效的数据传输。通过USART_CR3寄存器的DMARDMAT位配置DMA接收和发送。

3.5 初始化代码示例

以下是一个使用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) {

        // 主循环中的其他代码

    }

}

3.5.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中断处理函数:在中断处理函数中,读取接收到的数据并发送回该数据,然后清除中断标志。

4. USART接口的数据传输

4.1 异步数据传输

异步数据传输是最常用的通信模式。在这种模式下,数据的发送和接收不需要同步时钟信号。

4.1.1 发送数据

发送数据时,需要将数据写入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++);

    }

}

4.1.2 接收数据

接收数据时,需要读取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();

    }

}

4.2 同步数据传输

同步数据传输需要外部时钟信号。在STM32F1系列中,USART接口可以配置为同步模式,但不常用。同步模式的配置与异步模式类似,主要区别在于时钟信号的配置。

4.3 DMA数据传输

DMA(Direct Memory Access)可以用于高效的数据传输,特别是在需要大量数据传输时。以下是一个使用DMA进行数据传输的代码示例:

4.3.1 配置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);

}

4.3.2 使用DMA发送和接收数据

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) {

        // 主循环中的其他代码

    }

}

4.3.3 代码解析

  • 使能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_PeripheralDataSizeDMA_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传输。

5. USART接口的高级功能

5.1 流量控制

USART接口支持硬件流量控制,可以通过RTS(Request to Send)和CTS(Clear to Send)信号来控制数据的传输。这种方式可以防止数据丢失和溢出。

5.1.1 配置硬件流量控制

在配置硬件流量控制时,需要确保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);

}

5.2 奇偶校验

奇偶校验是一种简单的错误检测方法,可以在数据传输过程中检测到某些错误。通过USART_CR1寄存器的PCEPS位可以配置奇偶校验。

5.2.1 配置奇偶校验

在配置奇偶校验时,需要通过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);

}

5.3 低功耗模式

USART接口还支持低功耗模式,可以在不需要通信时关闭时钟或进入低功耗状态,以节省功耗。

5.3.1 配置低功耗模式

在配置低功耗模式时,可以通过关闭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);

}

5.4 错误处理

在数据传输过程中,可能会出现各种错误,如奇偶校验错误、帧错误、噪声错误等。可以通过中断或轮询方式检测这些错误并进行处理。

5.4.1 配置错误中断

在配置错误中断时,需要通过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);

    }

}

5.5 其他高级功能

5.5.1 LIN模式

LIN(Local Interconnect Network)模式是一种单主多从的通信协议,常用于汽车电子系统。通过USART_CR2寄存器的LINEN位可以启用LIN模式。

5.5.2 SMARTCARD模式

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);

}

5.5.3 IrDA模式

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);

}

6. 总结

USART接口在STM32F1系列单片机中是一个非常强大的串行通信接口,支持多种通信模式和高级功能。通过合理配置波特率、数据格式、中断和DMA,可以实现高效、可靠的串行通信。高级功能如流量控制、奇偶校验、低功耗模式、LIN模式、SMARTCARD模式和IrDA模式,可以进一步提高系统的灵活性和可靠性。希望本文的内容能帮助你更好地理解和使用STM32F1系列单片机的USART接口。

你可能感兴趣的:(单片机开发,stm32,嵌入式硬件,单片机)