STM32F103ZET6开发板串口只发不收问题解决

问题描述

最近在使用 STM32F103ZET6 开发板调试串口时,遇到了一个诡异的问题:单片机能正常向 PC 发送数据,但始终无法接收 PC 下发的数据,甚至连串口接收中断都没触发。更奇怪的是,相同的代码在STM32F103C8T6 最小系统板上能完美运行收发双向通信。经过多轮排查,发现串口重定向可以解决问题,在此记录完整过程,给遇到类似问题的开发者避坑。

解决:引脚重定向

将 USART1 默认引脚(A9/A10)重定向到 GPIOB 的备用引脚,无需修改串口核心配置,仅调整引脚相关代码即可。

硬件展示

第一个是问题开发板STM32F103ZET6,第二个是STM32F103C8T6

file-20251201184355114

file-20251201184414313

原始代码 (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 卡等)复用,导致接收引脚信号被占用或干扰,表现为 “只发不收”。

posted @ 2025-12-02 19:54  PC2005-cloud  阅读(33)  评论(0)    收藏  举报