STM32_USART_寄存器操作

文章目录

  • 一、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→编写收发 / 中断函数;

相关推荐
蓝斯49711 小时前
从.到实现一个Windows上的虚拟hid键盘设备
windows·单片机·计算机外设
熙芯XiChip11 小时前
硬实时与软实时RTOS核心区别
嵌入式硬件
伟大的前程12 小时前
unsigned int 定义的变量 在 电脑的 64 位系统中 和 32 位 cortex-m0 和 8 位的 51 单片机
单片机·嵌入式硬件
小渔村的拉线工12 小时前
1.HPM6E80 解析芯片整体工作原理和存储架构
单片机·嵌入式硬件·mcu·架构·hpm6e80
熙芯XiChip13 小时前
CAN与CANopen的本质区别
单片机
lilihewo13 小时前
Altium Designer 封装库的创建(分享pcb 3D封装库)
嵌入式硬件·51单片机
神罚天下ET14 小时前
典型arm位单片机启动流程(从上电到main.c)
c语言·arm开发·单片机
碧海银沙音频科技研究院15 小时前
蓝牙耳机使用WSDF5361锂保芯片进入船运模式实现方法
嵌入式硬件·算法
Zevalin爱灰灰16 小时前
模拟信号链电路——基于TL431的电压基准电路
单片机·嵌入式硬件
csdn杰哥16 小时前
瑞萨单片机开发教程[二十七] DTC 外部中断触发传输实验
单片机·嵌入式硬件·mongodb·瑞萨·ra6m5