也就是说,这个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的混合结构:
View Code
读数据的时候就容易了,一个字节一个字节的读,例如读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的数据转换了,哈,懒人用懒人的方法,不过这个方法毕竟效率不高,等飞机飞起来再改。。哈。。
读到的数据如下:
这些数值都是没有处理过的,裸数据,还要校正和根据我们选的量程来进行转换才行。。
加速读我们选的是+-4G,陀螺仪选的量程是+-2000度每秒,他们每个数值的寄存器都是16位的,对应的满量程数值为65536,65536/8 = 8192,计算出来的数值和手册上刚好是对应的哈,我们只要将读到的数据除以8192,再乘当地的重力加速度,就可以的到实际的加速度值了,总所周知,虽然M4带FPU,我们也开启了FPU,但是做乘法比做除法快,所以我们不除8192,而是乘以8192的倒数0.0001220703125,然后再乘9.81就好了。
陀螺仪是一样的哈,+-2000度每秒 对应的LSB Sensitivity是16.4,16.4的倒数是0.0609756097560976,读出来的值乘这个数,不过我们只取了小数点的后八位。
温度的话手册上有个公式,除以340+36.5就得出实际温度了。转换后的图如下: