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);
额外检查点
- 确认MPU6050初始化成功:可以在
MPU6050_Init()中添加串口打印,输出check变量的值,验证是否读取到正确的设备ID(十进制104,即0x68)。 - I2C通信可靠性:检查I2C引脚接线是否正确,确保SDA、SCL引脚的上拉电阻正常。
- 异步发送安全性:如果后续缩短
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
相关产品推荐
相关产品推荐

