STM32F103ZET6开发板串口只发不收问题解决
问题描述
最近在使用 STM32F103ZET6 开发板调试串口时,遇到了一个诡异的问题:单片机能正常向 PC 发送数据,但始终无法接收 PC 下发的数据,甚至连串口接收中断都没触发。更奇怪的是,相同的代码在STM32F103C8T6 最小系统板上能完美运行收发双向通信。经过多轮排查,发现串口重定向可以解决问题,在此记录完整过程,给遇到类似问题的开发者避坑。
解决:引脚重定向
将 USART1 默认引脚(A9/A10)重定向到 GPIOB 的备用引脚,无需修改串口核心配置,仅调整引脚相关代码即可。
硬件展示
第一个是问题开发板STM32F103ZET6,第二个是STM32F103C8T6


原始代码 (A9/A10 配置,仅发不收)
以下代码配置 USART1 默认引脚 A9(TX)、A10(RX),可正常发送但无法接收:
void USART_Init(void) {
// 1. 时钟使能
// 引脚时钟
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
// 配置USART1时钟
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
// 复用功能时钟
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
// 2. 引脚配置
// 配置PA9为复用推挽输出
GPIOA->CRH |= GPIO_CRH_MODE9;
GPIOA->CRH |= GPIO_CRH_CNF9_1;
GPIOA->CRH &= ~GPIO_CRH_CNF9_0;
// 配置PA10为复用输入浮空
GPIOA->CRH &= ~GPIO_CRH_MODE10;
GPIOA->CRH &= ~GPIO_CRH_CNF10_1;
GPIOA->CRH |= GPIO_CRH_CNF10_0;
// 3. USART1配置
// 波特率
USART1->BRR = 0x271;
// 使能
USART1->CR1 |= USART_CR1_UE; // 使能USART1
USART1->CR1 |= USART_CR1_TE; // 发送使能
USART1->CR1 |= USART_CR1_RE; // 接收使能
// 其他配置
USART1->CR1 &= ~USART_CR1_M; // 数据字长8位
USART1->CR1 &= ~USART_CR1_PCE; // 禁止奇偶校验
USART1->CR2 &= ~USART_CR2_STOP; // 1个停止位
// 中断使能
USART1->CR1 |= USART_CR1_IDLEIE;
USART1->CR1 |= USART_CR1_RXNEIE;
NVIC_SetPriorityGrouping(3);
NVIC_SetPriority(USART1_IRQn, 3);
NVIC_EnableIRQ(USART1_IRQn);
}
改进代码(重定向到 PB6/PB7,收发正常)
通过 AFIO 开启 USART1 部分重映射,将引脚切换为 PB6(TX)、PB7(RX),核心配置不变:
void USART_Init(void) {
// 1. 时钟使能
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; // 改为GPIOB时钟
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
11
// 2. 使能部分重映射
AFIO->MAPR |= AFIO_MAPR_USART1_REMAP; // 部分重映射到PB6, PB7
// 3. 引脚配置 - PB6(TX), PB7(RX)
// 配置PB6为复用推挽输出 (USART1_TX) GPIOB->CRL &= ~GPIO_CRL_CNF6; // 清除配置位
GPIOB->CRL |= GPIO_CRL_CNF6_1; // 复用推挽输出
GPIOB->CRL |= GPIO_CRL_MODE6; // 输出模式,最大速度50MHz
// 配置PB7为浮空输入 (USART1_RX) GPIOB->CRL &= ~GPIO_CRL_MODE7; // 输入模式
GPIOB->CRL &= ~GPIO_CRL_CNF7; // 清除配置位
GPIOB->CRL |= GPIO_CRL_CNF7_0; // 浮空输入
// 4. USART1配置 (保持不变)
USART1->BRR = 0x271;
USART1->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
USART1->CR1 &= ~USART_CR1_M;
USART1->CR1 &= ~USART_CR1_PCE;
USART1->CR2 &= ~USART_CR2_STOP;
// 中断配置
USART1->CR1 |= USART_CR1_IDLEIE | USART_CR1_RXNEIE;
NVIC_SetPriorityGrouping(0);
NVIC_SetPriority(USART1_IRQn, 3);
NVIC_EnableIRQ(USART1_IRQn);
}
总结
问题根源大概率是 STM32F103ZET6 开发板的硬件设计:默认串口引脚 A9/A10 可能被板载其他外设(如 LCD、按键、SD 卡等)复用,导致接收引脚信号被占用或干扰,表现为 “只发不收”。

本文记录了 STM32F103ZET6 开发板串口 “只发不收” 问题的排查与解决过程。调试中发现,基于寄存器配置的 USART1 代码在 STM32F103C8T6 最小系统板上可正常双向通信,但在 STM32F103ZET6 开发板上仅能发送数据,无法接收(接收中断未触发)。经分析,问题根源为 ZET6 开发板默认串口引脚 A9/A10 被板载外设复用,导致接收信号受干扰。通过 AFIO 开启 重映射,即可实现正常收发。
浙公网安备 33010602011771号