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

STM32G431CBT6读取MPU6050值串口显示为零问题排查

问题分析与解决

问题现象

在STM32G431CBT6开发板上通过UART输出MPU6050的加速度计、陀螺仪数据到串口监视器时,仅能正常打印字符串内容,但所有数值始终显示为0。

核心原因

既不是HAL_UART_Transmit_IT的实现问题,也不是数据类型问题,纯粹是变量名拼写错误:

  • 在MPU6050_Read_Accel()中,计算得到的加速度值存储在Ax、Ay、Az变量中;
  • 在MPU6050_Read_Gyro()中,计算得到的陀螺仪值存储在Gx、Gy、Gz变量中;
  • 但在sprintf格式化字符串时,错误使用了未赋值的ax、ay、az、gx、gy、gz变量(这些变量初始值为0)。

修复方法

将main函数中sprintf的参数替换为正确的变量:

// 原错误代码
sprintf(AccelX, "Accelerometer X: %.2f g\r\n",ax);
sprintf(AccelY, "Accelerometer Y: %.2f g\r\n",ay);
sprintf(AccelZ, "Accelerometer Z: %.2f g\r\n",az);

sprintf(GyroX, "Gyroscope X: %.2f dps\r\n", gx);
sprintf(GyroY, "Gyroscope Y: %.2f dps\r\n", gy);
sprintf(GyroZ, "Gyroscope Z: %.2f dps\r\n", gz);

修改为:

// 修正后的代码
sprintf(AccelX, "Accelerometer X: %.2f g\r\n",Ax);
sprintf(AccelY, "Accelerometer Y: %.2f g\r\n",Ay);
sprintf(AccelZ, "Accelerometer Z: %.2f g\r\n",Az);

sprintf(GyroX, "Gyroscope X: %.2f dps\r\n", Gx);
sprintf(GyroY, "Gyroscope Y: %.2f dps\r\n", Gy);
sprintf(GyroZ, "Gyroscope Z: %.2f dps\r\n", Gz);

额外检查点

  1. 确认MPU6050初始化成功:可以在MPU6050_Init()中添加串口打印,输出check变量的值,验证是否读取到正确的设备ID(十进制104,即0x68)。
  2. I2C通信可靠性:检查I2C引脚接线是否正确,确保SDA、SCL引脚的上拉电阻正常。
  3. 异步发送安全性:如果后续缩短HAL_Delay()时长,建议在HAL_UART_TxCpltCallback()中设置标志位,确保前一次UART发送完成后再发起新的发送,避免数据覆盖。

附用户提供的完整代码

char AccelX[50];
char AccelY[50];
char AccelZ[50];
char GyroX[50];
char GyroY[50];
char GyroZ[50];
char data[200];

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define SMPLRT_DIV_REG 0x19
#define GYRO_CONFIG_REG 0x1B
#define ACCEL_CONFIG_REG 0x1C
#define ACCEL_XOUT_H_REG 0x3B
#define TEMP_OUT_H_REG 0x41
#define GYRO_XOUT_H_REG 0x43
#define PWR_MGMT_1_REG 0x6B
#define WHO_AM_I_REG 0x75


int16_t Accel_X_RAW = 0;
int16_t Accel_Y_RAW = 0;
int16_t Accel_Z_RAW = 0;

int16_t Gyro_X_RAW = 0;
int16_t Gyro_Y_RAW = 0;
int16_t Gyro_Z_RAW = 0;

float Ax, Ay, Az, Gx, Gy, Gz, ax, ay, az, gx, gy, gz;

const double Accel_Z_corrector = 14418.0;

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
   // do nothing here
}

void MPU6050_Init (void)
{
    uint8_t check;
    uint8_t Data;

    // check device ID WHO_AM_I

    HAL_I2C_Mem_Read (&hi2c1, (0b1101000 <<1) + 0,WHO_AM_I_REG,1, &check, 1, 100);

    if (check == 104)  // 0x68 will be returned by the sensor if everything goes well
    {
        // power management register 0X6B we should write all 0's to wake the sensor up
        Data = 0;
        HAL_I2C_Mem_Write(&hi2c1, (0b1101000 <<1) + 0, PWR_MGMT_1_REG, 1,&Data, 1, 100);

        // Set DATA RATE of 1KHz by writing SMPLRT_DIV register
        Data = 0x07;
        HAL_I2C_Mem_Write(&hi2c1, (0b1101000 <<1) + 0, SMPLRT_DIV_REG, 1, &Data, 1, 100);

        // Set accelerometer configuration in ACCEL_CONFIG Register
        // XA_ST=0,YA_ST=0,ZA_ST=0, FS_SEL=0 -> ±2g
        Data = 0x00;
        HAL_I2C_Mem_Write(&hi2c1, (0b1101000 <<1) + 0, ACCEL_CONFIG_REG, 1, &Data, 1, 100);

        // Set Gyroscopic configuration in GYRO_CONFIG Register
        // XG_ST=0,YG_ST=0,ZG_ST=0, FS_SEL=0 -> ±250 °/s
        Data = 0x00;
        HAL_I2C_Mem_Write(&hi2c1, (0b1101000 <<1) + 0, GYRO_CONFIG_REG, 1, &Data, 1, 100);
    }

}


void MPU6050_Read_Accel (void)
{
    uint8_t Rec_Data[6];

    // Read 6 BYTES of data starting from ACCEL_XOUT_H register

    HAL_I2C_Mem_Read (&hi2c1, (0b1101000 <<1) + 0, ACCEL_XOUT_H_REG, 1, Rec_Data, 6, 100);

    Accel_X_RAW = (int16_t)(Rec_Data[0] << 8 | Rec_Data [1]);
    Accel_Y_RAW = (int16_t)(Rec_Data[2] << 8 | Rec_Data [3]);
    Accel_Z_RAW = (int16_t)(Rec_Data[4] << 8 | Rec_Data [5]);

    /*** convert the RAW values into acceleration in 'g'
         we have to divide according to the Full scale value set in FS_SEL
         FS_SEL = 0. So dividing by 16384.0
                       ****/

    Ax = Accel_X_RAW/16384.0;
    Ay = Accel_Y_RAW/16384.0;
    Az = Accel_Z_RAW/Accel_Z_corrector;
}


void MPU6050_Read_Gyro (void)
{
    uint8_t Rec_Data[6];

    // Read 6 BYTES of data starting from GYRO_XOUT_H register

    HAL_I2C_Mem_Read (&hi2c1, (0b1101000 <<1) + 0, GYRO_XOUT_H_REG, 1, Rec_Data, 6, 100);

    Gyro_X_RAW = (int16_t)(Rec_Data[0] << 8 | Rec_Data [1]);
    Gyro_Y_RAW = (int16_t)(Rec_Data[2] << 8 | Rec_Data [3]);
    Gyro_Z_RAW = (int16_t)(Rec_Data[4] << 8 | Rec_Data [5]);

    /*** convert the RAW values into dps (°/s)
                       ****/

    Gx = Gyro_X_RAW/131.0;
    Gy = Gyro_Y_RAW/131.0;
    Gz = Gyro_Z_RAW/131.0;
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  MPU6050_Init();


  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      MPU6050_Read_Accel();
      MPU6050_Read_Gyro();


          sprintf(AccelX, "Accelerometer X: %.2f g\r\n",ax);
          sprintf(AccelY, "Accelerometer Y: %.2f g\r\n",ay);
          sprintf(AccelZ, "Accelerometer Z: %.2f g\r\n",az);

          sprintf(GyroX, "Gyroscope X: %.2f dps\r\n", gx);
          sprintf(GyroY, "Gyroscope Y: %.2f dps\r\n", gy);
          sprintf(GyroZ, "Gyroscope Z: %.2f dps\r\n", gz);



          strcpy(data,AccelX);
          strcat(data,AccelY);
          strcat(data,AccelZ);
          strcat(data,GyroX);
          strcat(data,GyroY);
          strcat(data,GyroZ);

          HAL_UART_Transmit_IT(&huart1, (uint8_t *)data, strlen(data));

          HAL_Delay(1000); // Delay 1 second
  }
  /* USER CODE END 3 */
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:32:07