一、为什么要配置 USART
在嵌入式系统开发中,USART(通用同步 / 异步收发传输器)是一种非常重要的通信接口,它可以实现单片机与其他设备(如电脑、传感器、显示屏等)之间的数据传输。通过配置 USART,我们可以:
实现调试信息输出:在开发过程中,将程序运行状态和调试信息通过串口发送到电脑,方便开发者进行调试和故障排查。
与外部设备通信:通过串口与其他设备进行数据交换,实现更复杂的功能,如传感器数据采集、远程控制等。
实现设备间的数据传输:在多设备系统中,串口可以作为设备间通信的桥梁,实现数据的共享和协同工作。
二、硬件连接与引脚配置
1. 原理图分析
根据原理图可知,我们需要配置 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 配置步骤
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
|
|