让自己别忘了大学里学的东西,那么就把它记录下下来,效率会比忘记然后重新再去找资料再重头学高的多
一开始自己死命的去网上找现成的代码,但是发现大多都是打着dmp的幌子,给的是得出原始数据的代码,或者确实是dmp的代码,但是太复杂,自己看不懂,所以果断放弃,直接去网上找dmp移植的教程,结果文字教材也是差不多的效果,不过忽然在百度上发现了一个视频教材,”与非网”上的”小马哥STM32课程系列直播-如何两个月做出自己的暴力空心杯小四轴”里面有几讲是关于mpu6050的教程的,所以就点进去看了,他的内容还挺方便的 直接教你怎么去移植修改dmp的官方代码到stm32的文件中,但是并不是很详细的讲解官方给的代码的具体含义,对我这种不给我一个字一个字翻译很难理解的人来说是相当痛苦,然后还有一些不足的就是那个视频的进度条拖动很困难,不能精确回看定位到某个点,而且视频声音有点小,还有就是看视频的时候要全程投入,一旦错过某个修改的细节,你的代码就凉凉了,而且你不是很懂代码的含义,就不知道怎么修改,然后又得重看长达5,6个小时的视频,简直痛苦,当时我看了整整两遍,然而仍然不知道代码错在哪里,所以果断放弃,不过好的是,视频给了我一个贼清晰的框架和流程,那么我接下来只要慢慢的一点去研究代码内容就ok了。
》》》》”小马哥STM32课程系列直播-如何两个月做出自己的暴力空心杯小四轴”-链接:
http://www.moore8.com/courses/1406
记录一下MPU6050的dmp代码移植的过程
-
准备四个东西
- mpu6050硬件
- mpu6050寄存器手册,
- stm32f10x单片机
- dmp固件库(我的是5.1版的)
PS:固件库只需要提取下面7个文件即可,其他文件没啥用
“inv_mpu_dmp_motion_driver.h”
“inv_mpu_dmp_motion_driver.c”
“inv_mpu.h”
“inv_mpu.c”
“dmpmap.h”
“dmpKey.h”(前6个在同一个目录下) 和“motion_driver_test.c“
把前6个文件通过keil导入文件的方式,导入的keil中。第7个文件不是代码文件,而是适用于msp430的main函数文件,我们把第七个文件当作参照,来自己写一份关于stm32的main文件即可.
-
观察它文件内容的结构
- 整体文件分析
- 在”inv_mpu.c” “inv_mpu_dmp_motion_driver.c”这两个文件里面全是大片大片的英文,但是仔细看,你会发现,这么多的英文,其实结构很清晰,都是单个的模块的函数内容定义的集合以及一些条件预定义而已,并不是什么杂乱无章的东西,。打开“motion_driver_test.c“,你也会发现也是大量的函数定义以及条件预定义和一个main函数,而这个main函数是针对MSP430的一个代码,刚好是用于读取实时的欧拉角代码,首先我们对main函数进行分析,我们知道一个main函数一般分为两部分,各个内外设的初始化,和while循环内的无限操作函数,对于我们的要求也是也一样,我们无非也就是需要两个代码,mpu6050的初始化,以及无限的读出欧拉角,刚好和main函数对应上了,所以开始分析代码,因为main上自带英文注释,咱先把它通过谷歌翻译在”inv_mpu.c” “inv_mpu_dmp_motion_driver.c”这两个文件里面全是大片大片的英文,但是仔细看,你会发现,这么多的英文,其实结构很清晰,都是单个的模块的函数内容定义的集合以及一些条件预定义而已,并不是什么杂乱无章的东西,。打开“motion_driver_test.c“,你也会发现也是大量的函数定义以及条件预定义和一个main函数,而这个main函数是针对MSP430的一个代码,刚好是用于读取实时的欧拉角代码,首先我们对main函数进行分析,我们知道一个main函数一般分为两部分,各个内外设的初始化,和while循环内的无限操作函数,对于我们的要求也是也一样,我们无非也就是需要两个代码,mpu6050的初始化,以及无限的读出欧拉角,刚好和main函数对应上了,所以开始分析代码,因为main上自带英文注释,咱先把它通过谷歌翻译
- main文件分析
- 初始化:{
1. 初始化MSP430芯片
2. 初始化mpu6050
3. 检测返回值,如果返回值>0,重启MSP430
4. 开启陀螺仪和加速计
5. 加载mpu6050内部的陀螺仪和加速计的FIFO-根据内部参数配置
6. 设置mpu6050内部采样率
7. 返回刚刚配置的内部的一系列的值
8. 数组置数函数-c语言特有,将hal数组内的所有值都置为0
9. Hal.sesors=ACCEL_ON | GYRO_ON,标志-加速计和陀螺仪都开了
10. 上报四元数
11. 加载DMP功能
12. 将陀螺仪和加速度方向矩阵推入DMP
13. 手势回调函数-和我们的意图无关手势回调函数-和我们的意图无关
14. 安卓回调函数-和我们的意图无关
15. 选择dmp要加载的功能-和这些传入参数的值有关
16. 加载已选功能
17. 设置FIFO缓存的速率
18. 开启DMP
19. hal.dmp_on = 1 标志-DMP开启
20. 开启MPS430的中断
} - While(1){
- USB相关函数-和上位机有关,和我们的意图无关-
- 获得时间戳=当时的时间,和我们的意图无关-
- 运动中断函数,和我们的意图无关-
- 控制MSP430芯片休眠函数,和我们的意图无关-
- 查询DMP开了没和是否有数据更新了(两个都要满足)-
- 向DMP的fifo读取并且计算四元数
- 再检测FIFO内是否还存在有剩余的数据-如果没有,数据更新标志位清零
- 返回四元数
}
- 初始化:{
- 整体文件分析
-
翻译”inv_mpu.c”和“motion_driver_test.c“的函数大概内容
- “inv_mpu.c”
- static int set_int_enable(unsigned char enable) 模块中断使能函数
- int mpu_reg_dump(void) 测试打印函数
- int mpu_read_reg(unsigned char reg, unsigned char *data) 3.向芯片读寄存器值,除了MEMERY和FIFO
- int mpu_init(void) MPU6050的初始化
- int mpu_lp_accel_mode(unsigned char rate) 进入低功耗模式
- int mpu_get_gyro_reg(short *data, unsigned long *timestamp) 获取新的原始陀螺仪数据
- int mpu_get_accel_reg(short *data, unsigned long *timestamp获取新的原始加速度数据
- int mpu_get_temperature(long *data, unsigned long *timestamp) 获取新的温度数据
- int mpu_set_accel_bias(const long *accel_bias) 偏差配置函数
- int mpu_reset_fifo(void) 重置FIFO函数
- int mpu_get_gyro_fsr(unsigned short *fsr) 获得陀螺仪全尺寸范围函数
- int mpu_set_gyro_fsr(unsigned short fsr) 设置陀螺仪全尺寸范围函数
- int mpu_get_accel_fsr(unsigned char *fsr) 获得加速度全尺寸范围函数
- int mpu_set_accel_fsr(unsigned char fsr) 配置加速度全尺寸范围函数
- int mpu_get_lpf(unsigned short *lpf) .获得DLPF范围函数
- int mpu_set_lpf(unsigned short lpf) 配置DLPF范围函数
- int mpu_get_sample_rate(unsigned short *rate) 获得采样频率范围函数
- int mpu_set_sample_rate(unsigned short rate) 配置采样频率范围函数
- int mpu_get_compass_sample_rate(unsigned short *rate) 获得罗盘采样频率范围函数
- int mpu_set_compass_sample_rate(unsigned short rate) 配置罗盘采样频率范围函数
- int mpu_get_gyro_sens(float *sens) 获得陀螺仪灵敏度比例因子函数
- int mpu_get_accel_sens(unsigned short *sens) 获得加速计灵敏度比例因子函数
- int mpu_get_fifo_config(unsigned char *sensors) 获得开启的FIFO通道函数
- int mpu_configure_fifo(unsigned char sensors) 配置开启FIFO通道函数
- int mpu_get_power_state(unsigned char *power_on) 获得芯片工作状态
- int mpu_set_sensors(unsigned char sensors) 配置传感器的时钟和工作状态函数
- int mpu_get_int_status(short *status).获得中断状态函数
- int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp,unsigned char *sensors, unsigned char *more) 获得FIFO数据函数
- int mpu_read_fifo_stream(unsigned short length, unsigned char *data,unsigned char *more) 获得FIFO数据长度函数
- int mpu_set_bypass(unsigned char bypass_on) 设置旁路模式函数
- int mpu_set_int_level(unsigned char active_low) 设置中断优先级函数
- int mpu_set_int_latched(unsigned char enable) 设置中断锁存函数-
- 设置自检函数
- static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) 获取所有的偏差值函数
- int mpu_run_self_test(long *gyro, long *accel) 行自检值函数
- int mpu_write_mem(unsigned short mem_addr, unsigned short length,unsigned char *data) 向DMP写记忆函数
- int mpu_read_mem(unsigned short mem_addr, unsigned short length,unsigned char *data) 向DMP读记忆函数
- int mpu_load_firmware(unsigned short length, const unsigned char *firmware,unsigned short start_addr, unsigned short sample_rate) 加载并验证DMP映像函数
- int mpu_set_dmp_state(unsigned char enable) DMP状态控制函数
- int mpu_get_dmp_state(unsigned char *enabled) DMP状态读取函数
- “motion_driver_test.c“
1.*
2. static __inline unsigned short inv_row_2_scale(const signed char row) 矩阵转换方向标量函数
3. static void setup_gyro(void) 陀螺仪配置函数
4.
5.*
6. void STM32F103_Reset(void) 外部控制芯片复位函数,我们是stm32,所以重写
7. static __inline void run_self_test(void) 自检函数,用于坐标原点标定
8.*
9. static void gyro_data_ready_cb(void) 数据获得后的状态回调函数
- ”inv_mpu.c”和“inv_mpu_dmp_motion_driver.c“的文件格式的修改
-
根据“motion_driver_test.c“创建兼容STM32F10X的代码
- DMP初始化函数:
u8 DMP_Init(void) { int result; unsigned char accel_fsr; unsigned short gyro_rate, gyro_fsr; unsigned long timestamp;
result = mpu_init(); //1.6050初始化,成功=0,失败=1 if (result) { STM32F103_Reset(); //2.如果失败,重新复位stm32 return 8; } if(mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL)) //3.配置陀螺仪和加速计传感器的时钟和工作状态函数 {return 1;} if(mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL)) //4.配置陀螺仪和加速计开启FIFO通道函数 {return 2;} if(mpu_set_sample_rate(DEFAULT_MPU_HZ)) //5.配置默认的采样率 {return 3;} mpu_get_sample_rate(&gyro_rate); //6.获得陀螺仪采样频率范围函数 mpu_get_gyro_fsr(&gyro_fsr); //7.获得陀螺仪全尺寸范围函数 mpu_get_accel_fsr(&accel_fsr); //8.获得加速计全尺寸范围函数 memset(&hal, 0, sizeof(hal)); //9.数组填数函数 hal.sensors = ACCEL_ON | GYRO_ON; //10.标志位-"开启传感器"设置为加速计和陀螺仪 if(dmp_load_motion_driver_firmware()) //11.加载并验证DMP映像函数 {return 4;} if(dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation))) //12.推送陀螺仪和<a href="https://www.baidu.com/s?wd=%E5%8A%A0%E9%80%9F%E5%BA%A6%E8%AE%A1&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd" target="_blank">加速度计</a>的方向矩阵到DMP {return 5;} hal.dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL; //13.DMP的功能选项标志位设置,用来告诉DMP要开启的功能 if(dmp_enable_feature(hal.dmp_features)) //14.使能上述功能 {return 6;} if(dmp_set_fifo_rate(DEFAULT_MPU_HZ)) //15.配置DMP的FIFO速率 {return 7;} mpu_set_dmp_state(1); //16.开启DMP hal.dmp_on = 1; //17.标志位-"DMP状态"为开启 run_self_test(); //18.DMP的自检,就是标定现在的状态为坐标原点 return 0;
}
- 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
- DMP_欧拉角读取
short gyro[3], accel[3], sensors; unsigned char more; long quat[4]; float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f; float pitch,roll,yaw; u8 DMP_DATA_UPDATA(void) { unsigned long sensor_timestamp;
gyro_data_ready_cb(); //数据采集结束标志位 if (hal.new_gyro && hal.dmp_on) //用于计算四元数函数 { if(dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more)) {return 1;} if (!more) hal.new_gyro = 0; if(sensors & INV_WXYZ_QUAT) { q0=quat[0]/q30; q1=quat[1]/q30; q2=quat[2]/q30; q3=quat[3]/q30; pitch=asin((-2)*q1*q3+2*q0*q2)*57.3; roll=atan2(2*q2*q3+2*q0*q1,(-2)*q1*q1-2*q2*q2+1)*57.3; yaw=atan2(2*(q1*q2+q0*q3),q0*q0+q1*q1-q2*q2-q3*q3)*57.3; } } return 0;
}
- 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
-
注意事项:
-
模拟i2c的内容:
附件内有模拟I2C的代码,因为i2c内的延迟函数是通过while(time–)实现的,所以延迟长度可以通过time的值控制,为什么要考虑这个呢,因为在测试的时候发现单片机会 在“u8 DMP_Init(void) “函数中的 if(dmp_load_motion_driver_firmware()) /11.加载并验证DMP映像函数等待要很久,而这个函数的本质就是不断的通过I2C向6050收发数据,而我当时的I2C代码因为怕时钟线跳变时有延迟,所以给他每次跳变都加了很大的延迟,所以导致对于这个6050的这个函数也会延迟恒久,但是当我把软件延迟的变量变小,发现一下这个函数就通过了 -
关于mpu6050返回四元数的途径:
我们知道获取外部的数据有两种方式,一种是单片机一直通过询问标志位的方式去获得外部数据,另外一种是外部给单片机引脚一个电平跳变方式,来告诉单片机读取数据,也就是外部中断,而且第二中种效率高,但是对于6050,如果设置的dmp,他的默认中断触发是50us的高电平(应该是的),us对于单片机来说可能会出bug,所以选择巡查的方式来读出数据,所以在测试中,我用的是滴答定时器在固定的时间间隔来读取数据,因为6050产出的数据速度远远大于每次单片机去读取的时间,所以不用担心会读出空数据,但是,会有一个问题,就是如果单片机的读取时间过慢,比如说1s读一次,那么就会死机,这个好像是因为fifo的会阻塞问题把。具体的不清楚, -
编译结束时,warning和error都要关注:
有时候warning也会让程序出bug -
Keil特有的格式:
- c99的结构体无法识别,要把它该成GUI的结构体
- static _inline 关键字无法识别 要改成static __inline
-
mpu6050的功能报错:
因为它没有 accel_cfg2,lp_accel_odr,accel_intel 这三个功能,所以在inv_mpu.c内的struct gyro_reg_s 中把它注释掉
-
第一次调mpu6050,应该会有很多bug,见谅
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-7b4cdcb592.css" rel="stylesheet">
</div>
让自己别忘了大学里学的东西,那么就把它记录下下来,效率会比忘记然后重新再去找资料再重头学高的多
一开始自己死命的去网上找现成的代码,但是发现大多都是打着dmp的幌子,给的是得出原始数据的代码,或者确实是dmp的代码,但是太复杂,自己看不懂,所以果断放弃,直接去网上找dmp移植的教程,结果文字教材也是差不多的效果,不过忽然在百度上发现了一个视频教材,”与非网”上的”小马哥STM32课程系列直播-如何两个月做出自己的暴力空心杯小四轴”里面有几讲是关于mpu6050的教程的,所以就点进去看了,他的内容还挺方便的 直接教你怎么去移植修改dmp的官方代码到stm32的文件中,但是并不是很详细的讲解官方给的代码的具体含义,对我这种不给我一个字一个字翻译很难理解的人来说是相当痛苦,然后还有一些不足的就是那个视频的进度条拖动很困难,不能精确回看定位到某个点,而且视频声音有点小,还有就是看视频的时候要全程投入,一旦错过某个修改的细节,你的代码就凉凉了,而且你不是很懂代码的含义,就不知道怎么修改,然后又得重看长达5,6个小时的视频,简直痛苦,当时我看了整整两遍,然而仍然不知道代码错在哪里,所以果断放弃,不过好的是,视频给了我一个贼清晰的框架和流程,那么我接下来只要慢慢的一点去研究代码内容就ok了。
》》》》”小马哥STM32课程系列直播-如何两个月做出自己的暴力空心杯小四轴”-链接:
http://www.moore8.com/courses/1406
记录一下MPU6050的dmp代码移植的过程
-
准备四个东西
- mpu6050硬件
- mpu6050寄存器手册,
- stm32f10x单片机
- dmp固件库(我的是5.1版的)
PS:固件库只需要提取下面7个文件即可,其他文件没啥用
“inv_mpu_dmp_motion_driver.h”
“inv_mpu_dmp_motion_driver.c”
“inv_mpu.h”
“inv_mpu.c”
“dmpmap.h”
“dmpKey.h”(前6个在同一个目录下) 和“motion_driver_test.c“
把前6个文件通过keil导入文件的方式,导入的keil中。第7个文件不是代码文件,而是适用于msp430的main函数文件,我们把第七个文件当作参照,来自己写一份关于stm32的main文件即可.
-
观察它文件内容的结构
- 整体文件分析
- 在”inv_mpu.c” “inv_mpu_dmp_motion_driver.c”这两个文件里面全是大片大片的英文,但是仔细看,你会发现,这么多的英文,其实结构很清晰,都是单个的模块的函数内容定义的集合以及一些条件预定义而已,并不是什么杂乱无章的东西,。打开“motion_driver_test.c“,你也会发现也是大量的函数定义以及条件预定义和一个main函数,而这个main函数是针对MSP430的一个代码,刚好是用于读取实时的欧拉角代码,首先我们对main函数进行分析,我们知道一个main函数一般分为两部分,各个内外设的初始化,和while循环内的无限操作函数,对于我们的要求也是也一样,我们无非也就是需要两个代码,mpu6050的初始化,以及无限的读出欧拉角,刚好和main函数对应上了,所以开始分析代码,因为main上自带英文注释,咱先把它通过谷歌翻译在”inv_mpu.c” “inv_mpu_dmp_motion_driver.c”这两个文件里面全是大片大片的英文,但是仔细看,你会发现,这么多的英文,其实结构很清晰,都是单个的模块的函数内容定义的集合以及一些条件预定义而已,并不是什么杂乱无章的东西,。打开“motion_driver_test.c“,你也会发现也是大量的函数定义以及条件预定义和一个main函数,而这个main函数是针对MSP430的一个代码,刚好是用于读取实时的欧拉角代码,首先我们对main函数进行分析,我们知道一个main函数一般分为两部分,各个内外设的初始化,和while循环内的无限操作函数,对于我们的要求也是也一样,我们无非也就是需要两个代码,mpu6050的初始化,以及无限的读出欧拉角,刚好和main函数对应上了,所以开始分析代码,因为main上自带英文注释,咱先把它通过谷歌翻译
- main文件分析
- 初始化:{
1. 初始化MSP430芯片
2. 初始化mpu6050
3. 检测返回值,如果返回值>0,重启MSP430
4. 开启陀螺仪和加速计
5. 加载mpu6050内部的陀螺仪和加速计的FIFO-根据内部参数配置
6. 设置mpu6050内部采样率
7. 返回刚刚配置的内部的一系列的值
8. 数组置数函数-c语言特有,将hal数组内的所有值都置为0
9. Hal.sesors=ACCEL_ON | GYRO_ON,标志-加速计和陀螺仪都开了
10. 上报四元数
11. 加载DMP功能
12. 将陀螺仪和加速度方向矩阵推入DMP
13. 手势回调函数-和我们的意图无关手势回调函数-和我们的意图无关
14. 安卓回调函数-和我们的意图无关
15. 选择dmp要加载的功能-和这些传入参数的值有关
16. 加载已选功能
17. 设置FIFO缓存的速率
18. 开启DMP
19. hal.dmp_on = 1 标志-DMP开启
20. 开启MPS430的中断
} - While(1){
- USB相关函数-和上位机有关,和我们的意图无关-
- 获得时间戳=当时的时间,和我们的意图无关-
- 运动中断函数,和我们的意图无关-
- 控制MSP430芯片休眠函数,和我们的意图无关-
- 查询DMP开了没和是否有数据更新了(两个都要满足)-
- 向DMP的fifo读取并且计算四元数
- 再检测FIFO内是否还存在有剩余的数据-如果没有,数据更新标志位清零
- 返回四元数
}
- 初始化:{
- 整体文件分析
-
翻译”inv_mpu.c”和“motion_driver_test.c“的函数大概内容
- “inv_mpu.c”
- static int set_int_enable(unsigned char enable) 模块中断使能函数
- int mpu_reg_dump(void) 测试打印函数
- int mpu_read_reg(unsigned char reg, unsigned char *data) 3.向芯片读寄存器值,除了MEMERY和FIFO
- int mpu_init(void) MPU6050的初始化
- int mpu_lp_accel_mode(unsigned char rate) 进入低功耗模式
- int mpu_get_gyro_reg(short *data, unsigned long *timestamp) 获取新的原始陀螺仪数据
- int mpu_get_accel_reg(short *data, unsigned long *timestamp获取新的原始加速度数据
- int mpu_get_temperature(long *data, unsigned long *timestamp) 获取新的温度数据
- int mpu_set_accel_bias(const long *accel_bias) 偏差配置函数
- int mpu_reset_fifo(void) 重置FIFO函数
- int mpu_get_gyro_fsr(unsigned short *fsr) 获得陀螺仪全尺寸范围函数
- int mpu_set_gyro_fsr(unsigned short fsr) 设置陀螺仪全尺寸范围函数
- int mpu_get_accel_fsr(unsigned char *fsr) 获得加速度全尺寸范围函数
- int mpu_set_accel_fsr(unsigned char fsr) 配置加速度全尺寸范围函数
- int mpu_get_lpf(unsigned short *lpf) .获得DLPF范围函数
- int mpu_set_lpf(unsigned short lpf) 配置DLPF范围函数
- int mpu_get_sample_rate(unsigned short *rate) 获得采样频率范围函数
- int mpu_set_sample_rate(unsigned short rate) 配置采样频率范围函数
- int mpu_get_compass_sample_rate(unsigned short *rate) 获得罗盘采样频率范围函数
- int mpu_set_compass_sample_rate(unsigned short rate) 配置罗盘采样频率范围函数
- int mpu_get_gyro_sens(float *sens) 获得陀螺仪灵敏度比例因子函数
- int mpu_get_accel_sens(unsigned short *sens) 获得加速计灵敏度比例因子函数
- int mpu_get_fifo_config(unsigned char *sensors) 获得开启的FIFO通道函数
- int mpu_configure_fifo(unsigned char sensors) 配置开启FIFO通道函数
- int mpu_get_power_state(unsigned char *power_on) 获得芯片工作状态
- int mpu_set_sensors(unsigned char sensors) 配置传感器的时钟和工作状态函数
- int mpu_get_int_status(short *status).获得中断状态函数
- int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp,unsigned char *sensors, unsigned char *more) 获得FIFO数据函数
- int mpu_read_fifo_stream(unsigned short length, unsigned char *data,unsigned char *more) 获得FIFO数据长度函数
- int mpu_set_bypass(unsigned char bypass_on) 设置旁路模式函数
- int mpu_set_int_level(unsigned char active_low) 设置中断优先级函数
- int mpu_set_int_latched(unsigned char enable) 设置中断锁存函数-
- 设置自检函数
- static int get_st_biases(long *gyro, long *accel, unsigned char hw_test) 获取所有的偏差值函数
- int mpu_run_self_test(long *gyro, long *accel) 行自检值函数
- int mpu_write_mem(unsigned short mem_addr, unsigned short length,unsigned char *data) 向DMP写记忆函数
- int mpu_read_mem(unsigned short mem_addr, unsigned short length,unsigned char *data) 向DMP读记忆函数
- int mpu_load_firmware(unsigned short length, const unsigned char *firmware,unsigned short start_addr, unsigned short sample_rate) 加载并验证DMP映像函数
- int mpu_set_dmp_state(unsigned char enable) DMP状态控制函数
- int mpu_get_dmp_state(unsigned char *enabled) DMP状态读取函数
- “motion_driver_test.c“
1.*
2. static __inline unsigned short inv_row_2_scale(const signed char row) 矩阵转换方向标量函数
3. static void setup_gyro(void) 陀螺仪配置函数
4.
5.*
6. void STM32F103_Reset(void) 外部控制芯片复位函数,我们是stm32,所以重写
7. static __inline void run_self_test(void) 自检函数,用于坐标原点标定
8.*
9. static void gyro_data_ready_cb(void) 数据获得后的状态回调函数
- ”inv_mpu.c”和“inv_mpu_dmp_motion_driver.c“的文件格式的修改
-
根据“motion_driver_test.c“创建兼容STM32F10X的代码
- DMP初始化函数:
u8 DMP_Init(void) { int result; unsigned char accel_fsr; unsigned short gyro_rate, gyro_fsr; unsigned long timestamp;
result = mpu_init(); //1.6050初始化,成功=0,失败=1 if (result) { STM32F103_Reset(); //2.如果失败,重新复位stm32 return 8; } if(mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL)) //3.配置陀螺仪和加速计传感器的时钟和工作状态函数 {return 1;} if(mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL)) //4.配置陀螺仪和加速计开启FIFO通道函数 {return 2;} if(mpu_set_sample_rate(DEFAULT_MPU_HZ)) //5.配置默认的采样率 {return 3;} mpu_get_sample_rate(&gyro_rate); //6.获得陀螺仪采样频率范围函数 mpu_get_gyro_fsr(&gyro_fsr); //7.获得陀螺仪全尺寸范围函数 mpu_get_accel_fsr(&accel_fsr); //8.获得加速计全尺寸范围函数 memset(&hal, 0, sizeof(hal)); //9.数组填数函数 hal.sensors = ACCEL_ON | GYRO_ON; //10.标志位-"开启传感器"设置为加速计和陀螺仪 if(dmp_load_motion_driver_firmware()) //11.加载并验证DMP映像函数 {return 4;} if(dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation))) //12.推送陀螺仪和<a href="https://www.baidu.com/s?wd=%E5%8A%A0%E9%80%9F%E5%BA%A6%E8%AE%A1&tn=24004469_oem_dg&rsv_dl=gh_pl_sl_csd" target="_blank">加速度计</a>的方向矩阵到DMP {return 5;} hal.dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP | DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL; //13.DMP的功能选项标志位设置,用来告诉DMP要开启的功能 if(dmp_enable_feature(hal.dmp_features)) //14.使能上述功能 {return 6;} if(dmp_set_fifo_rate(DEFAULT_MPU_HZ)) //15.配置DMP的FIFO速率 {return 7;} mpu_set_dmp_state(1); //16.开启DMP hal.dmp_on = 1; //17.标志位-"DMP状态"为开启 run_self_test(); //18.DMP的自检,就是标定现在的状态为坐标原点 return 0;