标签:des style blog http color 使用 os io
1 #define __CPAL_I2C_TIMEOUT_DETECT ((pDevInitStruct->wCPAL_Timeout == CPAL_I2C_TIMEOUT_MIN) || 2 (pDevInitStruct->wCPAL_Timeout == CPAL_I2C_TIMEOUT_DEFAULT)) 3 4 #define __CPAL_I2C_TIMEOUT(cmd, timeout) pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_MIN + (timeout); 5 while (((cmd) == 0) && (!__CPAL_I2C_TIMEOUT_DETECT)); 6 if (__CPAL_I2C_TIMEOUT_DETECT) 7 { 8 return CPAL_I2C_Timeout (pDevInitStruct); 9 }10 pDevInitStruct->wCPAL_Timeout = CPAL_I2C_TIMEOUT_DEFAULT
也就是说,这个CPAL库需要试用最高优先级的中断,而且在最高优先级的中断里面有个while,这可是最高优先级中断好么,我其他的中断还要不要响应了?RTT的线程调度还能不能愉快的调度了?积分还能不能在正确的时间内完成了, 积分出来的数据会不会漂的更厉害?果断弃之。。
放弃CPAL库后,还有三个选择,买的板子是有写好的I2C的硬件库的,没有开源,为了快点做出来,就用他的库吧,当放进来编译好没错误后,下到板子里面运行,发现会卡死。。用不了。。当时不知道什么问题,后来想应该是没有用c99的原因,MDK默认是c89。还有两个选择,自己写硬件I2C或者用简单暴力的模拟I2C。。。折腾了好几天,进度太慢,我们首要任务是先飞起来,后面慢慢改,于是决定用模拟I2C,只要好点封装起来,后面把写好的更好的I2C放进去还是很容易的。
模拟I2C就不多说了, 说下MPU6050吧。。。MPU6050网络上的资料那是非常的多,设置什么的都比较简单,我比较懒哈,没用FIFO,懒得设置,就打算从0x3B移植读到0X48,把所有数据读出来,简单的方法就是一个byte一个byte的读出来,然后强制转换成U16格式的再进行计算就可以了,可是这真的行得通吗?用union测试了下,STM32F4的是小端模式,也就是说数据的低位保存在内存的低地址中,而数据的高位保存在内存的高地址中,可是看看MPU6050的手册,你会发现它是大端模式,数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中。如下图:
如果全部顺序读出来,LSB和MSB是反的,要转换一次。。于是又懒了,I2C连续读都已经写好了,但是不用算了,利用struct和union解决这个问题好了,用如下的方式定义一个struct和union的混合结构:
1 typedef struct 2 { 3 union 4 { 5 struct 6 { 7 u8 data_L; 8 u8 data_H; 9 } b; 10 u16 data; 11 } acce_x; 12 union 13 { 14 struct 15 { 16 u8 data_L; 17 u8 data_H; 18 } b; 19 u16 data; 20 } acce_y; 21 union 22 { 23 struct 24 { 25 u8 data_L; 26 u8 data_H; 27 } b; 28 u16 data; 29 } acce_z; 30 31 union 32 { 33 struct 34 { 35 u8 data_L; 36 u8 data_H; 37 } b; 38 u16 data; 39 } temp; 40 41 union 42 { 43 struct 44 { 45 u8 data_L; 46 u8 data_H; 47 } b; 48 u16 data; 49 } gyro_x; 50 union 51 { 52 struct 53 { 54 u8 data_L; 55 u8 data_H; 56 } b; 57 u16 data; 58 } gyro_y; 59 union 60 { 61 struct 62 { 63 u8 data_L; 64 u8 data_H; 65 } b; 66 u16 data; 67 } gyro_z; 68 69 }MPU6050_DATA_T;
读数据的时候就容易了,一个字节一个字节的读,例如读ACCX的高字节,读到mpu6050_data_t->acce_x.b.data_H中, 低字节读到mpu6050_data_t->acce_x.b.data_L中,而我们取数据的时候用mpu6050_data_t.acce_x.data就可以了,不需要进行LSB和MSB的数据转换了,哈,懒人用懒人的方法,不过这个方法毕竟效率不高,等飞机飞起来再改。。哈。。
读到的数据如下:
好像gyro_z的数据有点问题哈,后面再细看下,这些数值都是没有处理过的,裸数据,还要根据我们选的量程来进行转换才行。。
以前用过lsm303dlh算出过姿态数据的哈,就是反三角函数算,用的场合不一样,数据也没有滤波什么的,就这样算了。。这里终点是我们要用到反三角函数,M4可是带FPU的,不用白不用。。用了速度快很多。。哈。。开启FPU。。需要下面几个步骤:
在SystemIni 中有如下一句话
1 /* FPU settings ------------------------------------------------------------*/ 2 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 3 SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ 4 #endif
所以第一步需要设置这两个宏,__FPU_PRESENT,__FPU_USED,寻找一番,发现在STM32F4XX.h中
1 #define __MPU_PRESENT 1 /*!< STM32F4XX provides an MPU 2 #define __FPU_PRESENT 1 /*!< FPU present 已经定义好了
* The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder.
* - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
* - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
* - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
* - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
* - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
* - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
* - arm_cortexM0l_math.lib (Little endian on Cortex-M0)
四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法,布布扣,bubuko.com
四轴飞行器1.3 MPU6050(大端)和M4的FPU开启方法
标签:des style blog http color 使用 os io
原文地址:http://www.cnblogs.com/adfjhg/p/3901669.html