文章目录
- 一、UASRT寄存器
-
- [ 1、状态寄存器(USART_SR)](# 1、状态寄存器(USART_SR))
- [ 2、数据寄存器(USART_DR)](# 2、数据寄存器(USART_DR))
- [ 3、波特比率寄存器(USART_BRR)](# 3、波特比率寄存器(USART_BRR))
- [ 4、控制寄存器 1(USART_CR1)](# 4、控制寄存器 1(USART_CR1))
- [ 5、控制寄存器 2(USART_CR2)](# 5、控制寄存器 2(USART_CR2))
- [ 6、控制寄存器 3(USART_CR3)](# 6、控制寄存器 3(USART_CR3))
- [ 7、保护时间和预分频寄存器(USART_GTPR)](# 7、保护时间和预分频寄存器(USART_GTPR))
- [ 8、USART寄存器地址映象](# 8、USART寄存器地址映象)
- 二、代码实例
-
- [ 串口寄存器编程代码(含中断 + 查询模式)](# 串口寄存器编程代码(含中断 + 查询模式))
- 三、总结
-
- [ 1、关键寄存器](# 1、关键寄存器)
- [ 2、硬件接线:](# 2、硬件接线:)
- [ 3、串口寄存器编程核心流程:](# 3、串口寄存器编程核心流程:)
一、UASRT寄存器
1、状态寄存器(USART_SR)
地址偏移:0x00
复位值:0x00C0


2、数据寄存器(USART_DR)
地址偏移:0x04
复位值:不确定


3、波特比率寄存器(USART_BRR)
注意: 如果TE或RE被分别禁止,波特计数器停止计数
地址偏移:0x08
复位值:0x0000

4、控制寄存器 1(USART_CR1)
地址偏移:0x0C
复位值:0x0000



5、控制寄存器 2(USART_CR2)
地址偏移:0x10
复位值:0x0000


6、控制寄存器 3(USART_CR3)
地址偏移:0x14
复位值:0x0000


7、保护时间和预分频寄存器(USART_GTPR)
地址偏移:0x18
复位值:0x0000


8、USART寄存器地址映象

二、代码实例
串口寄存器编程代码(含中断 + 查询模式)
c
#include "stm32f10x.h"
#include <string.h>
// 全局接收缓冲区(中断接收用)
#define USART1_RX_BUF_SIZE 128
uint8_t USART1_Rx_Buf[USART1_RX_BUF_SIZE];
uint16_t USART1_Rx_Len = 0;
uint8_t USART1_Rx_Flag = 0; // 接收完成标志(0:未完成,1:完成)
/**
* @brief 系统时钟初始化(72MHz,HSE=8MHz)
* 串口波特率计算依赖系统时钟,必须先初始化
*/
void SystemClock_Init(void)
{
// 1. 开启HSE,等待稳定
RCC->CR |= RCC_CR_HSEON;
while(!(RCC->CR & RCC_CR_HSERDY));
// 2. 配置FLASH延迟、总线分频
FLASH->ACR |= FLASH_ACR_LATENCY_2;
RCC->CFGR &= ~RCC_CFGR_HPRE; // AHB不分频
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // APB1 2分频
RCC->CFGR &= ~RCC_CFGR_PPRE2; // APB2不分频
// 3. 配置PLL(8MHz×9=72MHz)
RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL);
RCC->CFGR |= RCC_CFGR_PLLMULL9;
// 4. 开启PLL,等待稳定
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));
// 5. 切换系统时钟到PLL
RCC->CFGR &= ~RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
}
/**
* @brief USART1初始化(9600波特率,8位数据位,1位停止位,无校验)
* @param baudrate:波特率(如9600、115200)
*/
void USART1_Init(uint32_t baudrate)
{
// 1. 开启GPIOA、USART1、AFIO时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN | RCC_APB2ENR_AFIOEN;
// 2. 配置GPIO引脚
// PA9(TX):复用推挽输出(10MHz)
GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9);
GPIOA->CRH |= GPIO_CRH_MODE9_0 | GPIO_CRH_CNF9_1;
// PA10(RX):浮空输入
GPIOA->CRH &= ~(GPIO_CRH_MODE10 | GPIO_CRH_CNF10);
GPIOA->CRH |= GPIO_CRH_CNF10_0;
// 3. 配置串口核心参数
USART1->CR1 &= ~USART_CR1_UE; // 先关闭串口
// 配置数据位:8位(M=0)、无校验(PCE=0)
USART1->CR1 &= ~(USART_CR1_M | USART_CR1_PCE);
// 配置停止位:1位(STOP[1:0]=00)
USART1->CR2 &= ~USART_CR2_STOP;
// 配置波特率(USART1时钟=72MHz)
USART1->BRR = 72000000 / baudrate;
// 4. 开启发送、接收、接收非空中断
USART1->CR1 |= USART_CR1_TE | USART_CR1_RE | USART_CR1_RXNEIE;
// 5. 开启串口
USART1->CR1 |= USART_CR1_UE;
}
/**
* @brief USART1 NVIC配置(中断优先级)
*/
void USART1_NVIC_Init(void)
{
// 配置优先级分组2:2位抢占+2位子优先级
SCB->AIRCR = 0x05FA0800;
// USART1对应37号中断通道
NVIC->IP[37] &= ~0xFF; // 清空优先级
NVIC->IP[37] |= 0x10; // 抢占优先级1,子优先级0
NVIC->ISER[1] |= (1 << 5); // 37=32+5 → ISER1的bit5置1
}
/**
* @brief USART1发送一个字节(查询模式)
* @param data:要发送的字节
*/
void USART1_SendByte(uint8_t data)
{
// 等待发送数据寄存器为空(TXE=1)
while(!(USART1->SR & USART_SR_TXE));
USART1->DR = data;
// 等待发送完成(TC=1)
while(!(USART1->SR & USART_SR_TC));
}
/**
* @brief USART1发送字符串(查询模式)
* @param str:要发送的字符串
*/
void USART1_SendString(char *str)
{
while(*str != '\0')
{
USART1_SendByte(*str);
str++;
}
}
/**
* @brief USART1中断服务函数(接收数据)
* 接收规则:接收到换行符'\n'表示接收完成
*/
void USART1_IRQHandler(void)
{
uint8_t recv_data;
// 检查接收非空标志(RXNE=1)
if(USART1->SR & USART_SR_RXNE)
{
recv_data = USART1->DR; // 读取数据(自动清除RXNE标志)
// 接收逻辑:未溢出且未完成
if(USART1_Rx_Len < USART1_RX_BUF_SIZE && !USART1_Rx_Flag)
{
if(recv_data == '\n') // 换行符表示接收完成
{
USART1_Rx_Buf[USART1_Rx_Len] = '\0'; // 字符串结束符
USART1_Rx_Flag = 1; // 置位完成标志
USART1_Rx_Len = 0; // 重置长度
}
else
{
USART1_Rx_Buf[USART1_Rx_Len++] = recv_data;
}
}
else // 溢出或已完成,重置
{
USART1_Rx_Len = 0;
USART1_Rx_Flag = 0;
}
}
}
// 主函数:测试串口收发(中断接收+查询发送)
int main(void)
{
// 1. 初始化系统时钟
SystemClock_Init();
// 2. 初始化USART1(9600波特率)
USART1_Init(9600);
// 3. 初始化NVIC
USART1_NVIC_Init();
// 4. 发送测试字符串
USART1_SendString("STM32 USART1 Register Test\r\n");
USART1_SendString("Input String (end with '\\n'):\r\n");
while(1)
{
// 检测到接收完成
if(USART1_Rx_Flag)
{
// 回显接收的字符串
USART1_SendString("Recv: ");
USART1_SendString((char*)USART1_Rx_Buf);
USART1_SendString("\r\n");
// 清空接收标志
USART1_Rx_Flag = 0;
}
}
}
三、总结
1、关键寄存器

2、硬件接线:
STM32 PA9(TX)→ USB 转 TTL 模块 RX
STM32 PA10(RX)→ USB 转 TTL 模块 TX
STM32 GND → USB 转 TTL 模块 GND
3、串口寄存器编程核心流程:
开时钟→配引脚→配波特率 / 帧格式→开收发 / 中断→配 NVIC→编写收发 / 中断函数;