You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UART跨板通信故障:Nucleo144转发STM32设备数据乱码求助

Nucleo-144(Arduino IDE)串口转发STM32自研设备数据出现固定乱码的解决方案

针对你遇到的问题,结合硬件和代码层面,给出以下针对性排查和解决步骤:


1. 优先排查硬件连接与电平匹配

  • 确认引脚对应关系:设备1的TX必须接设备2的RX,RX接TX,禁止交叉连接。核对你当前的接线:设备1 PA9(TX)→ 设备2 D52(RX)、设备1 PA10(RX)→ 设备2 D53(TX),确保无接反。
  • 强制共地:将设备1、Nucleo-144、PC的GND引脚用导线连接,消除地电位差——高波特率下(115200),地电位偏移会直接导致信号采样错误,出现固定乱码。
  • 检查电平兼容性:用万用表测量设备1 TX引脚的高电平输出,确认是3.3V(STM32标准TTL电平)。若设备1输出为5V,需添加电平转换模块(如TXS0108),避免引脚采样阈值不匹配。

2. 修正Arduino串口初始化逻辑

你当前自定义HardwareSerial的方式,在部分STM32 Arduino核心中可能未正确绑定UART外设时钟与引脚复用,导致串口工作异常。推荐两种修正方案:

方案A:使用板载默认硬件串口实例

查Nucleo-144的Arduino引脚映射表,找到对应硬件UART的SerialX实例(比如多数Nucleo-144板型中,Serial1对应PA9/PA10),直接使用默认实例初始化:

#define BAUDRATE_USB 9600
#define BAUDRATE_BOARD 115200

void setup() 
{
  Serial.begin(BAUDRATE_USB);
  // 显式指定串口参数,确保与设备1完全一致(默认8N1,若设备1参数不同需修改)
  Serial1.begin(BAUDRATE_BOARD, SERIAL_8N1); 
  delay(10000);
  char str[] = "Test UART";
  Serial.write(str, sizeof(str));
}

void loop()
{
  delay(100);
  while (Serial1.available() > 0) 
  {
    byte b = Serial1.read();
    Serial.write(b);
  }
}

然后调整硬件连接为:设备1 PA9(TX)→ Nucleo-144 Serial1的RX引脚,设备1 PA10(RX)→ Nucleo-144 Serial1的TX引脚。

方案B:手动配置UART外设(针对自定义引脚)

若必须使用D52/D53引脚,需手动初始化UART时钟与引脚复用(以STM32F4系列Nucleo-144为例,假设D52对应PB7、D53对应PB6,属于USART1):

#include <stm32f4xx.h>
#define BAUDRATE_USB 9600
#define BAUDRATE_BOARD 115200

void setup() {
  Serial.begin(BAUDRATE_USB);
  
  // 启用USART1与GPIOB时钟
  __HAL_RCC_USART1_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  // 配置PB6(TX)、PB7(RX)为USART1复用功能
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  // 初始化USART1波特率与收发功能
  USART1->BRR = HAL_RCC_GetHCLKFreq() / BAUDRATE_BOARD;
  USART1->CR1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE;

  delay(10000);
  char str[] = "Test UART";
  Serial.write(str, sizeof(str));
}

void loop() {
  delay(100);
  // 检查USART1接收寄存器是否有数据
  if(USART1->SR & USART_SR_RXNE) {
    byte b = USART1->DR;
    Serial.write(b);
  }
}

3. 验证串口参数一致性

除波特率外,设备1与设备2的数据位、停止位、奇偶校验位必须完全一致。若设备1不是默认的8数据位、1停止位、无校验(8N1),需在设备2的串口初始化时显式指定对应参数,比如:

// 示例:设备1为8数据位、1停止位、偶校验
Serial1.begin(BAUDRATE_BOARD, SERIAL_8E1);

可遍历常见参数组合(SERIAL_8N1/SERIAL_8E1/SERIAL_8O1/SERIAL_7N1)测试,直到乱码消失。


内容的提问来源于stack exchange,提问作者Tohkai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:35:30