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
相关产品推荐
相关产品推荐

