问题描述
最近在使用 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 卡等)复用,导致接收引脚信号被占用或干扰,表现为 “只发不收”。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |