You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

B-L4S5I-IOT01A板STM32 UART寄存器操作无数据输出问题

问题分析与修复方案

你的代码存在几个关键问题,导致UART无法正常发送数据,逐一排查并修复如下:

1. 系统时钟定义错误

STM32L4R5复位后默认系统时钟为MSI 4MHz,但你代码中定义SYS_FREQ 8000000(8MHz),这会导致波特率寄存器BRR计算错误,终端因波特率不匹配无法接收数据。

如果保持默认时钟,需修正宏定义:

#define SYS_FREQ 4000000

如果需要8MHz时钟,需手动配置MSI到8MHz(复位后默认是4MHz),在main开头添加:

RCC->CR |= RCC_CR_MSIRANGE_7; // 设置MSI为8MHz
while(!(RCC->CR & RCC_CR_MSIRDY)); // 等待MSI稳定

2. 多余的USART时钟使能

USART1挂载在APB2总线,你代码中错误地使能了APB1总线的USART2时钟(RCC->APB1ENR1 |= 1U << 17),这完全多余,直接删除该行即可。

3. GPIO复用配置冗余

GPIOA9对应USART1_TX的复用功能是AF7,你当前的写法虽然结果正确,但可以简化为更清晰的代码:

// 替换原来的AFR配置代码
GPIOA->AFR[1] &= ~(0xF << 4); // 先清零Pin9的AFR位(第4-7位)
GPIOA->AFR[1] |= (7 << 4);    // 设置为AF7

4. 可选:GPIO速度配置

HAL库通常会将UART引脚配置为高速模式,你当前代码未设置GPIO速度,可能在高速波特率下出现传输问题,建议添加:

GPIOA->OSPEEDR |= (3 << 18); // 设置Pin9为高速模式

修复后的完整代码

#include "stm32l4r5xx.h"

#define SYS_FREQ 4000000
#define UART_BAUDRATE 115200
#define TXE (1U << 7)

void write_uart(int value) {
  while (!(USART1->ISR & TXE)) {}
  USART1->TDR = (value & 0xFF);
}

int main() 
{
  // 使能GPIOA时钟
  RCC->AHB2ENR |= 1U << 0;

  // 配置GPIOA9为复用功能(USART1_TX)
  GPIOA->MODER &= ~(1U << 18);
  GPIOA->MODER |= 1U << 19;
  GPIOA->OSPEEDR |= (3 << 18); // 高速模式
  GPIOA->AFR[1] &= ~(0xF << 4);
  GPIOA->AFR[1] |= (7 << 4);    // AF7对应USART1_TX

  // 使能USART1时钟(APB2总线)
  RCC->APB2ENR |= 1U << 14;

  // 配置USART1
  USART1->CR1 &= ~(1U << 15); // 关闭OVER8采样
  USART1->BRR = (SYS_FREQ / UART_BAUDRATE);
  USART1->CR1 |= (1U << 3);   // 使能发送TE
  USART1->CR1 |= (1U << 0);   // 使能USART UE

  while (1)
  {
    write_uart('Y');
    // 可选:添加延时避免发送过快导致终端刷屏
    for(int i=0; i<100000; i++);
  }
}

额外注意事项

  • 确保终端工具的波特率、数据位(8位)、停止位(1位)、奇偶校验(无)与代码配置完全一致
  • 确认B-L4S5I-IOT01A的USART1_TX引脚确实为GPIOA9,硬件连接无误

内容的提问来源于stack exchange,提问作者Witnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:23:25