[STM32F1] STM32F103ZET6的USART配置与使用

[复制链接]
 楼主| keaibukelian 发表于 2025-7-15 17:05 | 显示全部楼层 |阅读模式
一、为什么要配置 USART
        在嵌入式系统开发中,USART(通用同步 / 异步收发传输器)是一种非常重要的通信接口,它可以实现单片机与其他设备(如电脑、传感器、显示屏等)之间的数据传输。通过配置 USART,我们可以:

实现调试信息输出:在开发过程中,将程序运行状态和调试信息通过串口发送到电脑,方便开发者进行调试和故障排查。

与外部设备通信:通过串口与其他设备进行数据交换,实现更复杂的功能,如传感器数据采集、远程控制等。

实现设备间的数据传输:在多设备系统中,串口可以作为设备间通信的桥梁,实现数据的共享和协同工作。

二、硬件连接与引脚配置
1. 原理图分析

603926875e740ce108.png

根据原理图可知,我们需要配置 STM32 芯片的 PA9 和 PA10 引脚来实现 USART 通信:

PA9(TX):用于发送数据,需要配置为复用推挽输出模式()
PA10(RX):用于接收数据,需要配置为浮空输入模式(完全由外部信号驱动,引脚为高阻抗状态)
2. GPIO 引脚配置
        首先,我们需要启用 GPIOA 的时钟,并配置 PA9 和 PA10 引脚:

// 寄存器方式
// 启用GPIOA时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;  

// PA9 (TX) 配置为复用推挽输出
GPIOA->CRH &= ~(0xF << 4);  // 清除原来的配置
GPIOA->CRH |= (0xB << 4);   // 配置为复用推挽输出,50MHz

// PA10 (RX) 配置为浮空输入
GPIOA->CRH &= ~(0xF << 8);  // 清除原来的配置
GPIOA->CRH |= (0x4 << 8);   // 配置为浮空输入



// 库函数方式
// 时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

// PA9 (TX) 配置
GPIO_InitTypeDef pa9;
pa9.GPIO_Mode = GPIO_Mode_AF_PP;    // 复用推挽输出
pa9.GPIO_Pin = GPIO_Pin_9;
pa9.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &pa9);

// PA10 (RX) 配置
GPIO_InitTypeDef pa10;
pa10.GPIO_Mode = GPIO_Mode_IN_FLOATING;  // 浮空输入
pa10.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &pa10);



三、USART 配置步骤

769866875e72397b68.png

1. 启用 USART 时钟
// 寄存器方式
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;  // 启用USART1时钟

// 库函数方式
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);


2. 设置数据位、停止位和校验位
// 寄存器方式
USART1->CR1 &= ~(USART_CR1_M);    // 8个数据位
USART1->CR2 &= ~(USART_CR2_STOP);  // 1个停止位
USART1->CR1 &= ~(USART_CR1_PCE);   // 无校验

// 库函数方式
USART_InitTypeDef usart1;
usart1.USART_BaudRate = 9600;  // 波特率设置为9600
usart1.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  // 无硬件流控制
usart1.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  // 同时启用接收和发送
usart1.USART_Parity = USART_Parity_No;  // 无校验
usart1.USART_StopBits = USART_StopBits_1;  // 1个停止位
usart1.USART_WordLength = USART_WordLength_8b;  // 8个数据位
USART_Init(USART1, &usart1);



3. 配置波特率
        波特率是串口通信的重要参数,表示每秒传输的比特数。在 STM32 中,可以通过设置 USART_BRR 寄存器来配置波特率。

// 寄存器方式
// 设置波特率为9600(假设系统时钟为72MHz)
USART1->BRR = (72000000 / 9600);

// 库函数方式
// 在上面的USART_InitTypeDef结构体中已经设置了波特率
// usart1.USART_BaudRate = 9600;


4. 使能 USART
// 寄存器方式
USART1->CR1 |= USART_CR1_TE;  // 使能发送
USART1->CR1 |= USART_CR1_UE;  // 使能USART

// 库函数方式
USART_Cmd(USART1, ENABLE);  // 使能USART1


四、数据发送函数
1. 发送单个字符
// 寄存器方式
void USART1_SendChar(char data) {
    // 等待发送缓冲区为空
    while(!(USART1->SR & USART_SR_TXE));
    // 发送数据
    USART1->DR = data;
}

// 库函数方式
void USART1_SendChar(char data) {
    // 等待发送缓冲区为空
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    // 发送数据
    USART_SendData(USART1, (uint8_t)data);
}



2. 发送字符串
void USART1_SendString(char* str) {
    while(*str) {
        USART1_SendChar(*str++);
    }
}


五、数据接收函数
1. 接收单个字符
// 寄存器方式
char USART1_ReceiveChar(void) {
    // 等待接收缓冲区非空
    while(!(USART1->SR & USART_SR_RXNE));
    // 返回接收到的数据
    return (uint8_t)(USART1->DR & 0xFF);
}

// 库函数方式
char USART1_ReceiveChar(void) {
    // 等待接收缓冲区非空
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    // 返回接收到的数据
    return (uint8_t)USART_ReceiveData(USART1);
}



2. 接收字符串
void USART1_ReceiveString(char* buffer, uint8_t length) {
    uint8_t i = 0;
    char c;

    while(i < length - 1) {
        c = USART1_ReceiveChar();
        if(c == '\r' || c == '\n') {
            break;
        }
        buffer[i++] = c;
    }
    buffer = '\0';  // 添加字符串结束符
}



六、完整代码示例
        下面是一个完整的 USART1 配置和使用示例:

#include "stm32f10x.h"

// 初始化USART1
void USART1_Init(void) {
    // 使能GPIOA和USART1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);

    // 配置PA9 (TX)为复用推挽输出
    GPIO_InitTypeDef GPIO_InitStructure;
    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);

    // 配置PA10 (RX)为浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    // 配置USART1
    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;
    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_Tx | USART_Mode_Rx;
    USART_Init(USART1, &USART_InitStructure);

    // 使能USART1
    USART_Cmd(USART1, ENABLE);
}

// 发送单个字符
void USART1_SendChar(char data) {
    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
    USART_SendData(USART1, (uint8_t)data);
}

// 发送字符串
void USART1_SendString(char* str) {
    while(*str) {
        USART1_SendChar(*str++);
    }
}

// 接收单个字符
char USART1_ReceiveChar(void) {
    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
    return (uint8_t)USART_ReceiveData(USART1);
}

int main(void) {
    char receivedChar;

    // 初始化USART1
    USART1_Init();

    // 发送欢迎信息
    USART1_SendString("Hello, this is a USART1 test program!\r\n");

    while(1) {
        // 接收字符
        receivedChar = USART1_ReceiveChar();

        // 回显接收到的字符
        USART1_SendString("You sent: ");
        USART1_SendChar(receivedChar);
        USART1_SendString("\r\n");
    }
}



七、实验验证
配置好 USART 后,你可以使用串口调试助手(如 Putty、XCOM 等)来验证通信是否正常:

将 STM32 开发板通过 USB 转串口模块连接到电脑
打开串口调试助手,设置波特率为 9600,数据位 8 位,停止位 1 位,无校验
复位 STM32 开发板,应该能在串口调试助手中看到欢迎信息
在串口调试助手中输入字符,开发板会将接收到的字符回显回来
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_74186706/article/details/149219244

LOVEEVER 发表于 2025-7-29 23:35 | 显示全部楼层
STM32F103稳定性如何?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

97

主题

4324

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部

97

主题

4324

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部