STM32F1与STM32CubeIDE编程实例-MPU-6050 六轴(陀螺仪 + 加速度计)驱动

MPU-6050 六轴(陀螺仪 + 加速度计)驱动

1、MPU-6050介绍

MPU-6050™ 部件是一款针对智能手机、平板电脑和可穿戴传感器的低功耗、低成本和高性能要求而设计的运动跟踪设备。

MPU-6050 集成了 InvenSense 的 MotionFusion™ 和运行时校准固件,使制造商能够消除在运动支持产品中分立器件的昂贵和复杂的选择、鉴定和系统级集成,确保传感器融合算法和校准程序提供最佳的为消费者提供性能。

MPU-6050 器件在同一硅芯片上结合了 3 轴陀螺仪和 3 轴加速度计,以及处理复杂 6 轴 MotionFusion 算法的板载 Digital Motion Processor™ (DMP™)。该器件可以通过辅助主 I²C 总线访问外部磁力计或其他传感器,从而使器件无需系统处理器干预即可收集全套传感器数据。这些器件采用 4 mm x 4 mm x 0.9 mm QFN 封装。

在这里插入图片描述

MPU-6050 随附的 InvenSense MotionApps™ 平台将基于运动的复杂性抽象化,从操作系统中卸载传感器管理,并为应用程序开发提供一组结构化的 API。

对于快速和慢速运动的精确跟踪,这些部件具有一个用户可编程陀螺仪满量程范围为 ±250、±500、±1000 和 ±2000°/秒 (dps),以及一个用户可编程加速度计满量程 ±2g、±4g、±8g和±16g的刻度范围。 其他特性包括一个嵌入式温度传感器和一个在工作温度范围内具有 ±1% 变化的片上振荡器。

MPU-6050的特性如下:

在这里插入图片描述

2、MPU-6050配置

关于STM32CubeIDE工程创建、配置请参考前面文章:

本次MPU-6050的配置如下:

在这里插入图片描述

3、MPU-6050驱动实现

1)驱动基本定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/\*
\* mpu6050.h
\*
\* Created on: Jun 26, 2022
\* Author: jenson
\*/

#ifndef \_\_MPU6050\_H\_\_
#define \_\_MPU6050\_H\_\_

#include <stm32f1xx\_hal.h>
#include <stdbool.h>

#define MPU6050\_ADDR (0x68 << 1) // 校正地址
#define MPU6050\_SMPLRT\_DIV\_REGISTER 0x19
#define MPU6050\_CONFIG\_REGISTER 0x1a
#define MPU6050\_GYRO\_CONFIG\_REGISTER 0x1b
#define MPU6050\_ACCEL\_CONFIG\_REGISTER 0x1c
#define MPU6050\_PWR\_MGMT\_1\_REGISTER 0x6b

#define MPU6050\_GYRO\_OUT\_REGISTER 0x43
#define MPU6050\_ACCEL\_OUT\_REGISTER 0x3B

#define RAD\_2\_DEG 57.29578 // [deg/rad]
#define CALIB\_OFFSET\_NB\_MES 500
#define TEMP\_LSB\_2\_DEGREE 340.0 // [bit/celsius]
#define TEMP\_LSB\_OFFSET 12412.0

#define DEFAULT\_GYRO\_COEFF 0.98

typedef enum {
DEG_RANGE_NONE = -1,
DEG_RANGE_NP_250 = 0,
DEG_RANGE_NP_500 = 1,
DEG_RANGE_NP_1000 = 2,
DEG_RANGE_NP_2000 = 3
} mpu6050\_gyro\_cfg\_t;

typedef enum {
ACC_RANGE_NONE = -1,
ACC_RANGE_NP_2G = 0,
ACC_RANGE_NP_4G = 1,
ACC_RANGE_NP_8G = 2,
ACC_RANGE_NP_16G = 3
} mpu6050\_acc\_cfg\_t;

typedef struct {
uint16\_t id;
I2C_HandleTypeDef \*I2C_Handle;
uint8\_t device_address;
float filter_gyro_coef; // 陀螺仪系数
float filter_acc_coef; // 加速计系数

mpu6050\_gyro\_cfg\_t gyro_cfg;
mpu6050\_acc\_cfg\_t acc_cfg;
float gyro_lsb_to_degsec; // 陀螺仪重力配置参数
float acc_lsb_to_g; // 加速计重力配置参数

int16\_t gyro_raw_x, gyro_raw_y, gyro_raw_z; // 陀螺仪原始数据
float gyro_x, gyro_y, gyro_z; // 陀螺仪数据

float gyro_xoffset;
float gyro_yoffset;
float gyro_zoffset;

float gyro_angle_x; // 陀螺仪X方向角度
float gyro_angle_y; //陀螺仪Y方向角度
float gyro_angle_z; //陀螺仪Z方向角度

int16\_t acc_raw_x, acc_raw_y, acc_raw_z; // 加速计原始数据
int8\_t acc_raw_x_lo,acc_raw_x_hi;// 加速计原始数据X低位和高位
int8\_t acc_raw_y_lo,acc_raw_y_hi;// 加速计原始数据Y低位和高位
int8\_t acc_raw_z_lo,acc_raw_z_hi;// 加速计原始数据Z低位和高位
float acc_x, acc_y, acc_z; // 加速计数据

float acc_xoffset; // 加速计X方向偏移量
float acc_yoffset; // 加速计Y方向偏移量
float acc_zoffset; // 加速计Z方向偏移量

float acc_angle_x;// 加速计X方向角度
float acc_angle_y;// 加速计Y方向角度

float angle_x; // X方向角度
float angle_y; // Y方向角度
float angle_z; // Z方向角度

float temperature; // 温度
int16\_t temperature_raw; //温度原始数据

bool upside_down_mounting;
uint32\_t pre_interval;
uint32\_t dt;

} mpu6050\_t;

bool mpu6050\_begin(mpu6050\_t \*dev);
void mpu6050\_calibrate(mpu6050\_t \*dev);

void mpu6050\_set\_filter\_gyro\_coef(mpu6050\_t \*dev, float coeff);
void mpu6050\_calc\_gyro\_offsets(mpu6050\_t \*dev);
bool mpu6050\_set\_gyro\_config(mpu6050\_t \*dev, mpu6050\_gyro\_cfg\_t cfg);
void mpu6050\_set\_gyro\_offsets(mpu6050\_t \*dev, float x, float y, float z);
float mpu6050\_get\_gyro\_filter\_coef(mpu6050\_t \*dev);

void mpu6050\_set\_filter\_acc\_coef(mpu6050\_t \*dev, float coeff);
void mpu6050\_calc\_acc\_offsets(mpu6050\_t \*dev);
bool mpu6050\_set\_acc\_config(mpu6050\_t \*dev, mpu6050\_acc\_cfg\_t cfg);
void mpu6050\_set\_acc\_offsets(mpu6050\_t \*dev, float x, float y, float z);
float mpu6050\_get\_acc\_filter\_coef(mpu6050\_t \*dev);

void mpu6050\_fetch\_data(mpu6050\_t \*dev);
void mpu6050\_update(mpu6050\_t \*dev);

#endif /\* \_\_MPU6050\_H\_\_ \*/


2)驱动辅助函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/\*
\* mpu6050.c
\*
\* Created on: Jun 26, 2022
\* Author: jenson
\*/

#include "mpu6050.h"
#include <math.h>
#include <stdio.h>

HAL_StatusTypeDef \_\_mpu6050\_write\_data(mpu6050\_t \*dev, uint8\_t reg,
uint8\_t data);
HAL_StatusTypeDef \_\_mpu6050\_read\_data(mpu6050\_t \*dev, uint8\_t reg,
uint8\_t \*pData, uint16\_t size);
void \_\_mpu6050\_calc\_offsets(mpu6050\_t \*dev, bool is_calc_gyro, bool is_calc_acc);

static float wrap(float angle, float limit) {
while (angle > limit)
angle -= 2 \* limit;
while (angle < -limit)
angle += 2 \* limit;
return angle;
}

HAL_StatusTypeDef \_\_mpu6050\_write\_data(mpu6050\_t \*dev, uint8\_t reg,
uint8\_t data) {

uint8\_t datas[2] = { reg, data };

HAL_StatusTypeDef status = HAL_OK;
while (HAL\_I2C\_Master\_Transmit(dev->I2C_Handle, dev->device_address, datas,
2, 100) != HAL_OK)
;
return status;
}

HAL_StatusTypeDef \_\_mpu6050\_read\_data(mpu6050\_t \*dev, uint8\_t reg,
uint8\_t \*pData, uint16\_t size) {
HAL_StatusTypeDef status = HAL_OK;
while (HAL\_I2C\_Master\_Transmit(dev->I2C_Handle, dev->device_address, &reg,
1, 100) != HAL_OK)
;
while (HAL\_I2C\_Master\_Receive(dev->I2C_Handle, dev->device_address, pData,
size, 1000) != HAL_OK)
;
return status;
}

3)驱动定义实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
// mpu6050.c

bool mpu6050\_begin(mpu6050\_t \*dev) {
if (HAL\_I2C\_IsDeviceReady(dev->I2C_Handle, dev->device_address, 2, 5)
!= HAL_OK) {
printf("mpu6050 not found\r\n");
return false;
}
dev->acc_angle_x = 0.0;
dev->acc_angle_y = 0.0;
dev->acc_x = 0.0;
dev->acc_y = 0.0;
dev->acc_z = 0.0;
dev->gyro_x = 0.0;
dev->gyro_y = 0.0;
dev->gyro_z = 0.0;
dev->angle_x = 0.0;
dev->angle_y = 0.0;
dev->angle_z = 0.0;
dev->gyro_angle_x = 0.0;
dev->gyro_angle_y = 0.0;
dev->gyro_angle_z = 0.0;
dev->acc_raw_x_lo = 0;
dev->acc_raw_x_hi = 0;
dev->acc_raw_y_lo = 0;
dev->acc_raw_y_hi = 0;
dev->acc_raw_z_lo = 0;
dev->acc_raw_z_hi = 0;

dev->filter_gyro_coef = DEFAULT_GYRO_COEFF;
dev->filter_acc_coef = 1.0 - DEFAULT_GYRO_COEFF;
dev->gyro_cfg = DEG_RANGE_NP_500;
dev->acc_cfg = ACC_RANGE_NP_2G;
dev->upside_down_mounting = false;

mpu6050\_set\_filter\_gyro\_coef(dev, DEFAULT_GYRO_COEFF);
mpu6050\_set\_gyro\_offsets(dev, 0.0, 0.0, 0.0);
mpu6050\_set\_acc\_offsets(dev, 0.0, 0.0, 0.0);

mpu6050\_set\_gyro\_config(dev, dev->gyro_cfg);
mpu6050\_set\_acc\_config(dev, dev->acc_cfg);

\_\_mpu6050\_write\_data(dev, MPU6050_PWR_MGMT_1_REGISTER, 0x01);

\_\_mpu6050\_write\_data(dev, MPU6050_SMPLRT_DIV_REGISTER, 0x00);

\_\_mpu6050\_write\_data(dev, MPU6050_CONFIG_REGISTER, 0x00);

//\_\_mpu6050\_calc\_offsets(true,true);

mpu6050\_update(dev);

dev->pre_interval = HAL\_GetTick();

dev->angle_x = dev->acc_angle_x;
dev->angle_y = dev->acc_angle_y;
mpu6050\_calibrate(dev);
return true;
}

void mpu6050\_calibrate(mpu6050\_t \*dev) {
printf("mpu6050 start calibrate...\r\n");
\_\_mpu6050\_calc\_offsets(dev, true, true);
printf("mpu6050 calibrate done...\r\n");
}

void mpu6050\_set\_filter\_gyro\_coef(mpu6050\_t \*dev, float coeff) {
if (coeff < 0 || coeff > 1) {
dev->filter_gyro_coef = DEFAULT_GYRO_COEFF;
} else {
dev->filter_gyro_coef = coeff;
}

}

void mpu6050\_calc\_gyro\_offsets(mpu6050\_t \*dev) {
\_\_mpu6050\_calc\_offsets(dev, true, false);
}

bool mpu6050\_set\_gyro\_config(mpu6050\_t \*dev, mpu6050\_gyro\_cfg\_t cfg) {
HAL_StatusTypeDef status = HAL_OK;
switch (cfg) {
case DEG_RANGE_NP_250: // range = +- 250 deg/s
dev->gyro_lsb_to_degsec = 131.0;
status = \_\_mpu6050\_write\_data(dev, MPU6050_GYRO_CONFIG_REGISTER, 0x00);
break;
case DEG_RANGE_NP_500: // range = +- 500 deg/s
dev->gyro_lsb_to_degsec = 65.5;
status = \_\_mpu6050\_write\_data(dev, MPU6050_GYRO_CONFIG_REGISTER, 0x08);
break;
case DEG_RANGE_NP_1000: // range = +- 1000 deg/s
dev->gyro_lsb_to_degsec = 32.8;
status = \_\_mpu6050\_write\_data(dev, MPU6050_GYRO_CONFIG_REGISTER, 0x10);
break;
case DEG_RANGE_NP_2000: // range = +- 2000 deg/s
dev->gyro_lsb_to_degsec = 16.4;
status = \_\_mpu6050\_write\_data(dev, MPU6050_GYRO_CONFIG_REGISTER, 0x18);
break;
default:
status = HAL_ERROR;
break;
}
if (status != HAL_OK) {
return false;
}
return true;
}

void mpu6050\_set\_gyro\_offsets(mpu6050\_t \*dev, float x, float y, float z) {
dev->gyro_xoffset = x;
dev->gyro_yoffset = y;
dev->gyro_zoffset = z;
}

void mpu6050\_set\_filter\_acc\_coef(mpu6050\_t \*dev, float coeff) {
mpu6050\_set\_filter\_gyro\_coef(dev, 1.0 - coeff);
}
void mpu6050\_calc\_acc\_offsets(mpu6050\_t \*dev) {
\_\_mpu6050\_calc\_offsets(dev, false, true);
}

bool mpu6050\_set\_acc\_config(mpu6050\_t \*dev, mpu6050\_acc\_cfg\_t cfg) {
HAL_StatusTypeDef status = HAL_OK;

switch (cfg) {
case ACC_RANGE_NP_2G: // range = +- 2 g
dev->acc_lsb_to_g = 16384.0;
status = \_\_mpu6050\_write\_data(dev, MPU6050_ACCEL_CONFIG_REGISTER, 0x00);
break;
case ACC_RANGE_NP_4G: // range = +- 4 g
dev->acc_lsb_to_g = 8192.0;
status = \_\_mpu6050\_write\_data(dev, MPU6050_ACCEL_CONFIG_REGISTER, 0x08);
break;
case ACC_RANGE_NP_8G: // range = +- 8 g
dev->acc_lsb_to_g = 4096.0;
status = \_\_mpu6050\_write\_data(dev, MPU6050_ACCEL_CONFIG_REGISTER, 0x10);
break;
case ACC_RANGE_NP_16G: // range = +- 16 g
dev->acc_lsb_to_g = 2048.0;
status = \_\_mpu6050\_write\_data(dev, MPU6050_ACCEL_CONFIG_REGISTER, 0x18);
break;
default:
status = HAL_ERROR;
break;
}

if (status != HAL_OK) {
return false;
}
return true;
}

void \_\_mpu6050\_calc\_offsets(mpu6050\_t \*dev, bool is_calc_gyro, bool is_calc_acc) {
if (is_calc_gyro) {
mpu6050\_set\_gyro\_offsets(dev, 0.0, 0.0, 0.0);
}
if (is_calc_acc) {
mpu6050\_set\_acc\_offsets(dev, 0.0, 0.0, 0.0);
}

float ag[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; // 3\* acc ,3 \* gyro
for (uint16\_t i = 0; i < CALIB_OFFSET_NB_MES; i++) {
mpu6050\_fetch\_data(dev);
ag[0] += dev->acc_x;
ag[1] += dev->acc_y;
ag[2] += dev->acc_z - 1.0;

ag[3] += dev->gyro_x;
ag[4] += dev->gyro_y;
ag[5] += dev->gyro_z;

//HAL\_Delay(1);
}

if (is_calc_acc) {
dev->acc_xoffset = ag[0] / CALIB_OFFSET_NB_MES;
dev->acc_yoffset = ag[1] / CALIB_OFFSET_NB_MES;
dev->acc_zoffset = ag[2] / CALIB_OFFSET_NB_MES;
}

if (is_calc_gyro) {
dev->gyro_xoffset = ag[3] / CALIB_OFFSET_NB_MES;
dev->gyro_yoffset = ag[4] / CALIB_OFFSET_NB_MES;
dev->gyro_zoffset = ag[5] / CALIB_OFFSET_NB_MES;
}
}

void mpu6050\_set\_acc\_offsets(mpu6050\_t \*dev, float x, float y, float z) {
dev->acc_xoffset = x;
dev->acc_yoffset = y;
dev->acc_zoffset = z;
}

float mpu6050\_get\_acc\_filter\_coef(mpu6050\_t \*dev) {
return 1.0 - dev->filter_gyro_coef;
}

void mpu6050\_fetch\_data(mpu6050\_t \*dev) {
static uint8\_t raw_bytes[14] = { 0.0 };
static int16\_t raw_data[7] = { 0.0 }; // [ax,ay,az,temp,gx,gy,gz]

\_\_mpu6050\_read\_data(dev, MPU6050_ACCEL_OUT_REGISTER, raw_bytes, 14);

for (uint8\_t i = 0; i < 7; i++) {
raw_data[i] = raw_bytes[i \* 2] << 8;
raw_data[i] |= raw_bytes[i \* 2 + 1];
}

dev->acc_raw_x_hi = raw_bytes[0];
dev->acc_raw_x_lo = raw_bytes[1];
dev->acc_raw_y_hi = raw_bytes[2];
dev->acc_raw_y_lo = raw_bytes[3];
dev->acc_raw_z_hi = raw_bytes[4];
dev->acc_raw_z_lo = raw_bytes[5];

dev->acc_raw_x = raw_data[0];
dev->acc_x = ((float) raw_data[0]) / dev->acc_lsb_to_g - dev->acc_xoffset;

dev->acc_raw_y = raw_data[1];
dev->acc_y = ((float) raw_data[1]) / dev->acc_lsb_to_g - dev->acc_yoffset;

dev->acc_raw_z = raw_data[2];
dev->acc_z = (!dev->upside_down_mounting - dev->upside_down_mounting)
\* ((float) raw_data[2]) / dev->acc_lsb_to_g - dev->acc_zoffset;

dev->temperature_raw = raw_data[3];
dev->temperature = ((float) raw_data[3] + TEMP_LSB_OFFSET)
/ TEMP_LSB_2_DEGREE;

dev->gyro_raw_x = raw_data[4];
dev->gyro_x = ((float) raw_data[4]) / dev->gyro_lsb_to_degsec
- dev->gyro_xoffset;

dev->gyro_raw_y = raw_data[5];
dev->gyro_y = ((float) raw_data[5]) / dev->gyro_lsb_to_degsec
- dev->gyro_yoffset;

dev->gyro_raw_z = raw_data[6];
dev->gyro_z = ((float) raw_data[6]) / dev->gyro_lsb_to_degsec
- dev->gyro_zoffset;
//HAL\_Delay(1);

}

void mpu6050\_update(mpu6050\_t \*dev) {
mpu6050\_fetch\_data(dev);

// 估计倾斜角:这是小角度的近似值!
float sg_z = (dev->acc_z >= 0) - (dev->acc_z < 0); //允许一个角度从 -180 到 +180 度
float sg_x = sg_z \* sqrt(dev->acc_z \* dev->acc_z + dev->acc_x \* dev->acc_x);
float sg_y = sqrt(dev->acc_z \* dev->acc_z + dev->acc_y \* dev->acc_y);
dev->acc_angle_x = atan2(dev->acc_y, sg_x) \* RAD_2_DEG; // [-180,+180] DEG
dev->acc_angle_y = atan2(dev->acc_x, sg_y) \* RAD_2_DEG; // [- 90,+ 90] DEG

uint32\_t new_time = HAL\_GetTick();
float dt = (new_time - dev->pre_interval) \* 1e-3;
dev->dt = dt;
dev->pre_interval = new_time;

dev->angle_x = wrap(
dev->filter_gyro_coef
\* (dev->acc_angle_x
+ wrap(
dev->angle_x + dev->gyro_x \* dt
- dev->acc_angle_x, 180))
+ (1.0 - dev->filter_gyro_coef) \* dev->acc_angle_x, 180);

dev->angle_y = wrap(
dev->filter_gyro_coef
\* (dev->acc_angle_y
+ wrap(
dev->angle_y + sg_z \* dev->gyro_y \* dt
- dev->acc_angle_y, 90))
+ (1.0 - dev->filter_gyro_coef) \* dev->acc_angle_y, 90);

dev->angle_z = dev->gyro_z \* dt;

dev->gyro_angle_x = wrap(dev->gyro_angle_x + dev->gyro_x \* dt, 180);
dev->gyro_angle_y = wrap(dev->gyro_angle_y + dev->gyro_y \* dt, 180);
dev->gyro_angle_z = wrap(dev->gyro_angle_z + dev->gyro_z \* dt, 180);

dev->gyro_angle_x = wrap(dev->gyro_angle_x + dev->gyro_x \* dev->dt, 180);
dev->gyro_angle_y = wrap(dev->gyro_angle_y + dev->gyro_y \* dev->dt, 180);
dev->gyro_angle_z = wrap(dev->gyro_angle_z + dev->gyro_z \* dev->dt, 180);

dev->temperature = ((float) dev->temperature_raw / 340.0) + 36.53;
}

4、MPU驱动应用

main.c文件中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/\* Private includes ----------------------------------------------------------\*/
/\* USER CODE BEGIN Includes \*/
#include <stdio.h>
#include "mpu6050/mpu6050.h"
/\* USER CODE END Includes \*/

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\_USART1\_UART\_Init();
MX\_I2C1\_Init();
/\* USER CODE BEGIN 2 \*/

mpu6050.I2C_Handle = &hi2c1;
mpu6050.device_address = MPU6050_ADDR;

if (!mpu6050\_begin(&mpu6050)) {
printf("init mpu6050 failed\r\n");
while (1)
;
}
printf("mpu6050 inited\r\n");

/\* USER CODE END 2 \*/

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

/\* USER CODE BEGIN 3 \*/
mpu6050\_update(&mpu6050);

printf("acc offset x = %.2f, y = %.2f, z = %.2f\r\n",mpu6050.acc_xoffset,mpu6050.acc_yoffset,mpu6050.acc_zoffset);
printf("acc raw x = %d, y = %d, z = %d\r\n",mpu6050.acc_raw_x,mpu6050.acc_raw_y,mpu6050.acc_raw_z);
printf("acc x = %.2f m/s², y = %.2f m/s², z =%.2f m/s²\r\n", mpu6050.acc_x, mpu6050.acc_y, mpu6050.acc_z);
printf("acc angle x = %.2f, y = %.2f,\r\n", mpu6050.acc_angle_x, mpu6050.acc_angle_y);

printf("gyro offset x = %.2f,y = %.2f,z = %.2f\r\n", mpu6050.gyro_xoffset, mpu6050.gyro_yoffset, mpu6050.gyro_zoffset);
printf("gyro raw x = %d, y = %d, z = %d\r\n", mpu6050.gyro_raw_x, mpu6050.gyro_raw_y, mpu6050.gyro_raw_z);
printf("gyro x = %.2f deg/s, y = %.2f deg/s, z = %.2f deg/s\r\n", mpu6050.gyro_x, mpu6050.gyro_y, mpu6050.gyro_z);
printf("gyro angle x = %.2f, y = %.2f, z = %.2f\r\n", mpu6050.gyro_angle_x, mpu6050.gyro_angle_y, mpu6050.gyro_angle_z);

printf("angle x = %.2f,y = %.2f,z = %.2f\r\n", mpu6050.angle_x, mpu6050.angle_y, mpu6050.angle_z);

printf("temperature = %.2f\r\n", mpu6050.temperature);
printf("temperature raw = %d\r\n", mpu6050.temperature_raw);

printf("-----------------------------------------------\r\n");

HAL\_Delay(50);

}
/\* USER CODE END 3 \*/
}


文章来源: https://iotsmart.blog.csdn.net/article/details/125828471