MPU6050六轴传感器
MPU6050 是 InvenSense 公司推出的整合性 6 轴运动处理组件,其内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个IIC 接口, 可用于连接外部磁力传感器,并利用自带的数字运动处理器(DMP: Digital Motion Processor) 硬件加速引擎,通过主 IIC 接口,向应用端输出完整的 9 轴融合演算数据。
InvenSense 公司提供了一套基于DMP的运动处理驱动库,可大大降低单片机对动处理运算的负荷,同时也大大降低了编程难度。该模块广泛运用于飞控、计步等电子产品中。
模块来源
采购链接:
https://item.taobao.com/item.htm?spm=a1z10.3-c-s.w4002-19589090137.10.478736b4NYZQSb&id=609979451344
资料下载链接:https://pan.baidu.com/s/1dNDqcp76L9QdM7iSZYfz_A
提取码:4eum
规格参数
工作电压:3-5V(模块带有LDO)
工作电流:5MA
通信接口:IIC
移植过程
我们的目标是在【立创开发板GD32E230C8T6】上能够获取当前传感器的偏移角度功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
查看资料
常用寄存器说明
初始化步骤:
1、 复位MPU6050,让MPU6050内部的所有寄存器恢复默认值(向0X6B写入0x80)
2、设置电源管理寄存器位0x00,以唤醒MPU6050,进入正常工作状态(向0x6B写入0x00)
3、 陀螺仪配置寄存器(0x1B)设置MPU6050陀螺仪传感器满量程范围,这里选择正负2000dps
4、加速度传感器配置寄存器(0x1C)这里选择正负2g
5、陀螺仪采样率,由采样率分频寄存器(0x19)控制;这里设置为50hz即输出频率=1KHz,SMPLRT_DIV=19
6、设置MPU6050的数字低通滤波器,因为配置为50hz,找一个接近值,所以配置为0x03,42hz
7、设置PLL,一般选择x轴陀螺PLL作为时钟源,以获得更高精度的时钟。(向0X6B写入0x01)
8、设置加速度与陀螺仪都工作(向0X6C写入0x00)
这里还有一个寄存器可以用来检测是否有mpu6050(当AD0接地时,向0x75读取数据则返回0x68;当AD0接VCC时,向0x75读取数据则返回0x69)
以上是初始化的部分,初始化完成之后开始读取数据
读取温度的地址:
读取陀螺仪测量值(原始值)分别有X/Y/Z轴的数据
读取加速度计测量值(原始值)分别有X/Y/Z轴的数据
引脚选择
移植至工程
移植步骤中的导入.c和.h文件与之前相同,只是将.c和.h文件更改为bsp_mpu6050.c与bsp_mpu6050.h。详细可见【TTP224触摸传感器】中的移植至工程目录。这里不再过多讲述。移植完成后面修改相关代码。
在文件bsp_mpu6050.c中,编写如下代码
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "bsp_mpu6050.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "systick.h"
#define delay_us delay_1us
/******************************************************************
* 函 数 名 称:MPU6050_GPIO_Init
* 函 数 说 明:MPU6050的引脚初始化
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void MPU6050_GPIO_Init(void)
{
/* 使能时钟 */
rcu_periph_clock_enable(RCU_SCL);
rcu_periph_clock_enable(RCU_SDA);
/* 配置SCL为输出模式 */
gpio_mode_set(PORT_SCL,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_SCL);
/* 配置为推挽输出 50MHZ */
gpio_output_options_set(PORT_SCL,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_SCL);
/* 配置SDA为输出模式 */
gpio_mode_set(PORT_SDA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_SDA);
/* 配置为推挽输出 50MHZ */
gpio_output_options_set(PORT_SDA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_SDA);
}
/******************************************************************
* 函 数 名 称:IIC_Start
* 函 数 说 明:IIC起始时序
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Start(void)
{
SDA_OUT();
SCL(1);
SDA(0);
SDA(1);
delay_us(5);
SDA(0);
delay_us(5);
SCL(0);
}
/******************************************************************
* 函 数 名 称:IIC_Stop
* 函 数 说 明:IIC停止信号
* 函 数 形 参:无
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Stop(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_us(5);
SDA(1);
delay_us(5);
}
/******************************************************************
* 函 数 名 称:IIC_Send_Ack
* 函 数 说 明:主机发送应答或者非应答信号
* 函 数 形 参:0发送应答 1发送非应答
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void IIC_Send_Ack(unsigned char ack)
{
SDA_OUT();
SCL(0);
SDA(0);
delay_us(5);
if(!ack) SDA(0);
else SDA(1);
SCL(1);
delay_us(5);
SCL(0);
SDA(1);
}
/******************************************************************
* 函 数 名 称:I2C_WaitAck
* 函 数 说 明:等待从机应答
* 函 数 形 参:无
* 函 数 返 回:0有应答 1超时无应答
* 作 者:LC
* 备 注:无
******************************************************************/
unsigned char I2C_WaitAck(void)
{
char ack = 0;
unsigned char ack_flag = 10;
SCL(0);
SDA(1);
SDA_IN();
SCL(1);
while( (SDA_GET()==1) && ( ack_flag ) )
{
ack_flag--;
delay_us(5);
}
if( ack_flag <= 0 )
{
IIC_Stop();
return 1;
}
else
{
SCL(0);
SDA_OUT();
}
return ack;
}
/******************************************************************
* 函 数 名 称:Send_Byte
* 函 数 说 明:写入一个字节
* 函 数 形 参:dat要写人的数据
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void Send_Byte(uint8_t dat)
{
int i = 0;
SDA_OUT();
SCL(0);//拉低时钟开始数据传输
for( i = 0; i < 8; i++ )
{
SDA( (dat & 0x80) >> 7 );
delay_us(2);
SCL(1);
delay_us(5);
SCL(0);
delay_us(5);
dat<<=1;
}
}
/******************************************************************
* 函 数 名 称:Read_Byte
* 函 数 说 明:IIC读时序
* 函 数 形 参:无
* 函 数 返 回:读到的数据
* 作 者:LC
* 备 注:无
******************************************************************/
unsigned char Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
SCL(0);
delay_us(5);
SCL(1);
delay_us(5);
receive<<=1;
if( SDA_GET() )
{
receive|=1;
}
delay_us(5);
}
SCL(0);
return receive;
}
/******************************************************************
* 函 数 名 称:MPU6050_WriteReg
* 函 数 说 明:IIC连续写入数据
* 函 数 形 参:addr器件地址 regaddr寄存器地址 num要写入的长度 regdata写入的数据地址
* 函 数 返 回:0=读取成功 其他=读取失败
* 作 者:LC
* 备 注:无
******************************************************************/
char MPU6050_WriteReg(uint8_t addr,uint8_t regaddr,uint8_t num,uint8_t *regdata)
{
uint16_t i = 0;
IIC_Start();
Send_Byte((addr<<1)|0);
if( I2C_WaitAck() == 1 ) {IIC_Stop();return 1;}
Send_Byte(regaddr);
if( I2C_WaitAck() == 1 ) {IIC_Stop();return 2;}
for(i=0;i<num;i++)
{
Send_Byte(regdata[]);
if( I2C_WaitAck() == 1 ) {IIC_Stop();return (3+i);}
}
IIC_Stop();
return 0;
}
/******************************************************************
* 函 数 名 称:MPU6050_ReadData
* 函 数 说 明:IIC连续读取数据
* 函 数 形 参:addr器件地址 regaddr寄存器地址 num要读取的长度 Read读取到的数据要存储的地址
* 函 数 返 回:0=读取成功 其他=读取失败
* 作 者:LC
* 备 注:无
******************************************************************/
char MPU6050_ReadData(uint8_t addr, uint8_t regaddr,uint8_t num,uint8_t* Read)
{
uint8_t i;
IIC_Start();
Send_Byte((addr<<1)|0);
if( I2C_WaitAck() == 1 ) {IIC_Stop();return 1;}
Send_Byte(regaddr);
if( I2C_WaitAck() == 1 ) {IIC_Stop();return 2;}
IIC_Start();
Send_Byte((addr<<1)|1);
if( I2C_WaitAck() == 1 ) {IIC_Stop();return 3;}
for(i=0;i<(num-1);i++){
Read[]=Read_Byte();
IIC_Send_Ack(0);
}
Read[]=Read_Byte();
IIC_Send_Ack(1);
IIC_Stop();
return 0;
}
/******************************************************************
* 函 数 名 称:MPU_Set_Gyro_Fsr
* 函 数 说 明:设置MPU6050陀螺仪传感器满量程范围
* 函 数 形 参:fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
* 函 数 返 回:0,设置成功 其他,设置失败
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr)
{
return MPU6050_WriteReg(0x68,MPU_GYRO_CFG_REG,1,(uint8_t*)(fsr<<3)); //设置陀螺仪满量程范围
}
/******************************************************************
* 函 数 名 称:MPU_Set_Accel_Fsr
* 函 数 说 明:设置MPU6050加速度传感器满量程范围
* 函 数 形 参:fsr:0,±2g;1,±4g;2,±8g;3,±16g
* 函 数 返 回:0,设置成功 其他,设置失败
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t MPU_Set_Accel_Fsr(uint8_t fsr)
{
return MPU6050_WriteReg(0x68,MPU_ACCEL_CFG_REG,1,(uint8_t*)(fsr<<3)); //设置加速度传感器满量程范围
}
/******************************************************************
* 函 数 名 称:MPU_Set_LPF
* 函 数 说 明:设置MPU6050的数字低通滤波器
* 函 数 形 参:lpf:数字低通滤波频率(Hz)
* 函 数 返 回:0,设置成功 其他,设置失败
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t MPU_Set_LPF(uint16_t lpf)
{
uint8_t data=0;
if(lpf>=188)data=1;
else if(lpf>=98)data=2;
else if(lpf>=42)data=3;
else if(lpf>=20)data=4;
else if(lpf>=10)data=5;
else data=6;
return data=MPU6050_WriteReg(0x68,MPU_CFG_REG,1,&data);//设置数字低通滤波器
}
/******************************************************************
* 函 数 名 称:MPU_Set_Rate
* 函 数 说 明:设置MPU6050的采样率(假定Fs=1KHz)
* 函 数 形 参:rate:4~1000(Hz) 初始化中rate取50
* 函 数 返 回:0,设置成功 其他,设置失败
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t MPU_Set_Rate(uint16_t rate)
{
uint8_t data;
if(rate>1000)rate=1000;
if(rate<4)rate=4;
data=1000/rate-1;
data=MPU6050_WriteReg(0x68,MPU_SAMPLE_RATE_REG,1,&data); //设置数字低通滤波器
return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半
}
/******************************************************************
* 函 数 名 称:MPU6050ReadGyro
* 函 数 说 明:读取陀螺仪数据
* 函 数 形 参:陀螺仪数据存储地址
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void MPU6050ReadGyro(short *gyroData)
{
uint8_t buf[];
uint8_t reg = 0;
//MPU6050_GYRO_OUT = MPU6050陀螺仪数据寄存器地址
//陀螺仪数据输出寄存器总共由6个寄存器组成,
//输出X/Y/Z三个轴的陀螺仪传感器数据,高字节在前,低字节在后。
//每一个轴16位,按顺序为xyz
reg = MPU6050_ReadData(0x68,MPU6050_GYRO_OUT,6,buf);
if( reg == 0 )
{
gyroData[] = (buf[] << 8) | buf[];
gyroData[] = (buf[] << 8) | buf[];
gyroData[] = (buf[] << 8) | buf[];
}
}
/******************************************************************
* 函 数 名 称:MPU6050ReadAcc
* 函 数 说 明:读取加速度数据
* 函 数 形 参:加速度数据存储地址
* 函 数 返 回:无
* 作 者:LC
* 备 注:无
******************************************************************/
void MPU6050ReadAcc(short *accData)
{
uint8_t buf[];
uint8_t reg = 0;
//MPU6050_ACC_OUT = MPU6050加速度数据寄存器地址
//加速度传感器数据输出寄存器总共由6个寄存器组成,
//输出X/Y/Z三个轴的加速度传感器值,高字节在前,低字节在后。
reg = MPU6050_ReadData(0x68, MPU6050_ACC_OUT, 6, buf);
if( reg == 0)
{
accData[] = (buf[] << 8) | buf[];
accData[] = (buf[] << 8) | buf[];
accData[] = (buf[] << 8) | buf[];
}
}
/******************************************************************
* 函 数 名 称:MPU6050_GetTemp
* 函 数 说 明:读取MPU6050上的温度
* 函 数 形 参:无
* 函 数 返 回:温度值单位为℃
* 作 者:LC
* 备 注:温度换算公式为:Temperature = 36.53 + regval/340
******************************************************************/
float MPU6050_GetTemp(void)
{
short temp3;
uint8_t buf[];
float Temperature = 0;
MPU6050_ReadData(0x68,MPU6050_RA_TEMP_OUT_H,2,buf);
temp3= (buf[] << 8) | buf[];
Temperature=((double) temp3/340.0)+36.53;
return Temperature;
}
/******************************************************************
* 函 数 名 称:MPU6050ReadID
* 函 数 说 明:读取MPU6050的器件地址
* 函 数 形 参:无
* 函 数 返 回:0=检测不到MPU6050 1=能检测到MPU6050
* 作 者:LC
* 备 注:无
******************************************************************/
uint8_t MPU6050ReadID(void)
{
unsigned char Re[] = {0};
//器件ID寄存器 = 0x75
printf("mpu=%d\r\n",MPU6050_ReadData(0x68,0X75,1,Re)); //读器件地址
if (Re[] != 0x68)
{
printf("NOT Find MPU6050 !!!\r\n");
return 1;
}
else
{
printf("MPU6050 ID = %x\r\n",Re[]);
return 0;
}
return 0;
}
/******************************************************************
* 函 数 名 称:MPU6050_Init
* 函 数 说 明:MPU6050初始化
* 函 数 形 参:无
* 函 数 返 回:0成功 1没有检测到MPU6050
* 作 者:LC
* 备 注:无
******************************************************************/
char MPU6050_Init(void)
{
MPU6050_GPIO_Init();
delay_1ms(10);
//复位6050
MPU6050_WriteReg(0x68,MPU6050_RA_PWR_MGMT_1, 1,(uint8_t*)(0x80));
delay_1ms(100);
//电源管理寄存器
//选择X轴陀螺作为参考PLL的时钟源,设置CLKSEL=001
MPU6050_WriteReg(0x68,MPU6050_RA_PWR_MGMT_1,1, (uint8_t*)(0x00));
MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps
MPU_Set_Accel_Fsr(0); //加速度传感器,±2g
MPU_Set_Rate(50);
MPU6050_WriteReg(0x68,MPU_INT_EN_REG , 1,(uint8_t*)0x00); //关闭所有中断
MPU6050_WriteReg(0x68,MPU_USER_CTRL_REG,1,(uint8_t*)0x00); //I2C主模式关闭
MPU6050_WriteReg(0x68,MPU_FIFO_EN_REG,1,(uint8_t*)0x00); //关闭FIFO
MPU6050_WriteReg(0x68,MPU_INTBP_CFG_REG,1,(uint8_t*)0X80); //INT引脚低电平有效
if( MPU6050ReadID() == 0 )//检查是否有6050
{
MPU6050_WriteReg(0x68,MPU6050_RA_PWR_MGMT_1, 1,(uint8_t*)0x01);//设置CLKSEL,PLL X轴为参考
MPU6050_WriteReg(0x68,MPU_PWR_MGMT2_REG, 1,(uint8_t*)0x00);//加速度与陀螺仪都工作
MPU_Set_Rate(50);
return 1;
}
return 0;
}
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
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
在文件bsp_mpu6050.h中,编写如下代码
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#ifndef _BSP_MPU6050_H_
#define _BSP_MPU6050_H_
#include "gd32e23x.h"
//端口移植
#define RCU_SDA RCU_GPIOA
#define PORT_SDA GPIOA
#define GPIO_SDA GPIO_PIN_2
#define RCU_SCL RCU_GPIOA
#define PORT_SCL GPIOA
#define GPIO_SCL GPIO_PIN_1
//设置SDA输出模式
#define SDA_OUT() gpio_mode_set(PORT_SDA,GPIO_MODE_OUTPUT,GPIO_MODE_OUTPUT,GPIO_SDA)
//设置SDA输入模式
#define SDA_IN() gpio_mode_set(PORT_SDA,GPIO_MODE_INPUT,GPIO_MODE_OUTPUT,GPIO_SDA)
//获取SDA引脚的电平变化
#define SDA_GET() gpio_input_bit_get(PORT_SDA,GPIO_SDA)
//SDA与SCL输出
#define SDA(x) gpio_bit_write(PORT_SDA,GPIO_SDA, (x?SET:RESET))
#define SCL(x) gpio_bit_write(PORT_SCL,GPIO_SCL, (x?SET:RESET))
//MPU6050的AD0是IIC地址引脚,接地则IIC地址为0x68,接VCC则IIC地址为0x69
#define MPU6050_RA_SMPLRT_DIV 0x19 //陀螺仪采样率 地址
#define MPU6050_RA_CONFIG 0x1A //设置数字低通滤波器 地址
#define MPU6050_RA_GYRO_CONFIG 0x1B //陀螺仪配置寄存器
#define MPU6050_RA_ACCEL_CONFIG 0x1C //加速度传感器配置寄存器
#define MPU_INT_EN_REG 0X38 //中断使能寄存器
#define MPU_USER_CTRL_REG 0X6A //用户控制寄存器
#define MPU_FIFO_EN_REG 0X23 //FIFO使能寄存器
#define MPU_PWR_MGMT2_REG 0X6C //电源管理寄存器2
#define MPU_GYRO_CFG_REG 0X1B //陀螺仪配置寄存器
#define MPU_ACCEL_CFG_REG 0X1C //加速度计配置寄存器
#define MPU_CFG_REG 0X1A //配置寄存器
#define MPU_SAMPLE_RATE_REG 0X19 //采样频率分频器
#define MPU_INTBP_CFG_REG 0X37 //中断/旁路设置寄存器
#define MPU6050_RA_PWR_MGMT_1 0x6B
#define MPU6050_RA_PWR_MGMT_2 0x6C
#define MPU6050_WHO_AM_I 0x75
#define MPU6050_SMPLRT_DIV 0 //8000Hz
#define MPU6050_DLPF_CFG 0
#define MPU6050_GYRO_OUT 0x43 //MPU6050陀螺仪数据寄存器地址
#define MPU6050_ACC_OUT 0x3B //MPU6050加速度数据寄存器地址
#define MPU6050_RA_TEMP_OUT_H 0x41 //温度高位
#define MPU6050_RA_TEMP_OUT_L 0x42 //温度低位
#define MPU_ACCEL_XOUTH_REG 0X3B //加速度值,X轴高8位寄存器
#define MPU_ACCEL_XOUTL_REG 0X3C //加速度值,X轴低8位寄存器
#define MPU_ACCEL_YOUTH_REG 0X3D //加速度值,Y轴高8位寄存器
#define MPU_ACCEL_YOUTL_REG 0X3E //加速度值,Y轴低8位寄存器
#define MPU_ACCEL_ZOUTH_REG 0X3F //加速度值,Z轴高8位寄存器
#define MPU_ACCEL_ZOUTL_REG 0X40 //加速度值,Z轴低8位寄存器
#define MPU_TEMP_OUTH_REG 0X41 //温度值高八位寄存器
#define MPU_TEMP_OUTL_REG 0X42 //温度值低8位寄存器
#define MPU_GYRO_XOUTH_REG 0X43 //陀螺仪值,X轴高8位寄存器
#define MPU_GYRO_XOUTL_REG 0X44 //陀螺仪值,X轴低8位寄存器
#define MPU_GYRO_YOUTH_REG 0X45 //陀螺仪值,Y轴高8位寄存器
#define MPU_GYRO_YOUTL_REG 0X46 //陀螺仪值,Y轴低8位寄存器
#define MPU_GYRO_ZOUTH_REG 0X47 //陀螺仪值,Z轴高8位寄存器
#define MPU_GYRO_ZOUTL_REG 0X48 //陀螺仪值,Z轴低8位寄存器
char MPU6050_WriteReg(uint8_t addr,uint8_t regaddr,uint8_t num,uint8_t *regdata);
char MPU6050_ReadData(uint8_t addr, uint8_t regaddr,uint8_t num,uint8_t* Read);
char MPU6050_Init(void);
void MPU6050ReadGyro(short *gyroData);
void MPU6050ReadAcc(short *accData);
float MPU6050_GetTemp(void);
uint8_t MPU6050ReadID(void);
#endif
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
移植完成以上文件后,只是完成了获取陀螺仪和加速度的原始数据,我们是希望获取到角度数据。
因为MPU6050内部带有DMP处理单元,加上官方提供了比较完整的运动处理驱动库,大大降低了我们的编程和对数据的处理难度。我们可以将各个运动的参数计算,如旋转矩阵、四元数(quaternion)、欧拉角格式(Euler Angle forma)的融合演算数据,通过调用运动处理驱动库函数,直接读取出数据来。
这里提供官方的运动处理驱动库,分别需要用到“inv_mpu.h”、“inv_mpu.c”、“dmpKey.h”、“dmpmap.h“、“inv_mpu_dmp_motion_driver.h”、“inv_mpu_dmp_motion_driver.c”等六个文件。已经移植完成并适配【立创开发板GD32E230C8T6】的官方库文件,见下方的文件下载。
文件下载
官方库文件下载(已经适配-立创开发板GD32E230C8T6)
下载完成之后,将其.c和.h导入到工程中,下面是导入操作:
- 将文件拉入Hardware文件夹
- 添加h文件的路径
- 添加C文件到工程目录中
- 这时我们就能发现工程中就能发现我们添加的文件了
移植验证
在自己工程中的main主函数中,编写如下
/******************************************************************************
* 测试硬件:立创开发板·GD32E230C8T6 使用主频72Mhz 晶振8Mhz
* 版 本 号: V1.0
* 修改作者: www.lckfb.com
* 修改日期: 2023年11月02日
* 功能介绍:
*****************************************************************************
* 梁山派软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 立创论坛:club.szlcsc.com
* 其余模块移植手册:【立创·GD32E230C8T6开发板】模块移植手册
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
******************************************************************************/
#include "gd32e23x.h"
#include "systick.h"
#include <stdio.h>
#include "bsp_usart.h"
#include "bsp_mpu6050.h"
#include "inv_mpu.h"
int main(void)
{
uint8_t ret = 1;
float pitch=0,roll=0,yaw=0; //欧拉角
systick_config(); // 滴答定时器初始化
usart_gpio_config(115200U); // 串口0初始化
printf("start\r\n");
//MPU6050初始化
MPU6050_Init();
//DMP初始化
while( mpu_dmp_init() )
{
printf("dmp error\r\n");
delay_1ms(200);
}
printf("Initialization Data Succeed \r\n");
while(1)
{
//获取欧拉角
if( mpu_dmp_get_data(&pitch,&roll,&yaw) == 0 )
{
printf("\r\npitch =%.2f\r\n", pitch);
printf("\r\nroll =%.2f\r\n", roll);
printf("\r\nyaw =%.2f\r\n", yaw);
}
delay_1ms(20);//根据设置的采样率,不可设置延时过大
}
}
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
移植现象:
pitch yaw roll是什么