博客 / 詳情

返回

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 卡等)複用,導致接收引腳信號被佔用或干擾,表現為 “只發不收”。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.