本帖最后由 shinykongcn 于 2015-5-6 20:40 编辑
代码两个星期前写完了,最近忙着学新东西,加之人比较懒,帖子一直没发,罪过罪过~~
上一篇帖子中实现了与MPU6050的硬件I2C通信,这里要赞一个NXP的I2C,用起来不要太爽,demo瞟一眼,立马会用了,不象之前用stmxx的时候,捣鼓半天,最后没捣鼓出来,现在还没高熟练(原谅我的智商吧)。相比来说lpc54102的I2C只要简单的初始化GPIO,设置I2C参数,发送接收数据只要填充一个机构体
ROM_I2CM_XFER_T 里的发送接收缓冲,发送接收数据大小,还有从机地址就可以了。
MPU6050是一颗6轴的运动感应器,可以感应xyz 3轴的加速度(Accelerometer加速度计)和3轴角速度大小(
Gyroscope陀螺仪)。量程和精度可调,注意这里的加速度计的单位为g,当水平静止时,由于z轴有重力,所以其输出应该为ax=0,ay=0,az=1g,陀螺仪测得的为角速度大小,单位为o/s,静止时应该gx=gy=gz=0。MPU6050同时还可以测量温度,换算方法为
好了,下面就说说怎么获取到加速度a和角速度g,通过查看mpu6050,首先需要设置传感器参数,这里主要是设置酵素的和角速度的量程,这个跟测量的结果是有关的,因为mpu6050内部adc的结果保存使用2字节16bit的空间存放,也就是2^16个数据组合,这里拿加速度为例,加速度的量程可以设置为+-2g/+-4g/+-8g/+-16g,如果设置位+-2g,则每个一个单位保存的数据大小位2^16/4 = 16384 LSB/g,即1g在寄存器中有16384个数据来表示,当量程为+-16g时, 2^16/32g = 2048LSB/g,此时1g用2048个数据表示,精度就降低了。这也是后面计算加速度大小时的算法。量程为+-4g时实际加速度值 a = regRead/(2^16/8)g。换算表可以查MPU6050寄存器
下面上点小代码,带有注释的,应该容易理解,整个MPU6050的操作就是读写寄存器,封装了一个方法用于完成这个步骤,部分代码来源网上,版权归别人所有。。。
- static void mpu_hw_init() { // 初始化
- mpu_write_reg(MPU6050_RA_PWR_MGMT_1, 0x00);
- delay_ms(200); //解除休眠后的延时要上百毫秒,否则初始化不成功
- mpu_write_reg(MPU6050_RA_PWR_MGMT_1, 0x03); //选时钟
- mpu_write_reg(MPU6050_RA_CONFIG, 0x03); //加速度44hz滤波,陀螺仪42hz滤波
- mpu_write_reg(MPU6050_RA_SMPLRT_DIV, 0x00); //陀螺仪采样率,1khz效果不错
- mpu_write_reg(MPU6050_RA_GYRO_CONFIG, 0x18); //陀螺仪最大量程 +-2000度每秒
- mpu_write_reg(MPU6050_RA_ACCEL_CONFIG, 0x08); //加速度度最大量程 +-4G
- }
复制代码寄存器值换算成实际的加速度和角速度
- uint8_t mpu_get_motion6(float m[6]) {
- int ret;
- static int16_t raw[6];
- ret = mpu_read_regs(MPU6050_RA_ACCEL_XOUT_H, mpu_read_buf, 14); // a+g+t
- if (ret == 14) {
- raw[0] = (((int16_t) mpu_read_buf[0]) << 8) | mpu_read_buf[1]; // Accel
- raw[1] = (((int16_t) mpu_read_buf[2]) << 8) | mpu_read_buf[3];
- raw[2] = (((int16_t) mpu_read_buf[4]) << 8) | mpu_read_buf[5];
- // raw[6] = (((int16_t) mpu_read_buf[6]) << 8) | mpu_read_buf[7]; // Temperature, reg0x41,reg0x42
- raw[3] = (((int16_t) mpu_read_buf[8]) << 8) | mpu_read_buf[9]; // gyro
- raw[4] = (((int16_t) mpu_read_buf[10]) << 8) | mpu_read_buf[11];
- raw[5] = (((int16_t) mpu_read_buf[12]) << 8) | mpu_read_buf[13];
- int i;
- for (i = 0; i < 3; i++)
- m[i] = (float) raw[i] / 8192.0f; // +-4g
- for (i = 3; i < 6; i++)
- m[i] = (float) raw[i] / 16.4f; // +-2000deg/s -> 16.4LSB deg/s
- // m[6] = (float) raw[6] / 340 + 36.53f; // Temperaturein degrees C = (TEMP_OUT Register Valueas a signed quantity)/340 + 36.53
- return !0;
- } else {
- return 0;
- }
- }
复制代码温度数据换算:
- float mpu_get_temperature() {
- int16_t t = 0;
- uint8_t raw[2];
- if (mpu_read_regs(MPU6050_RA_TEMP_OUT_H, raw, 2) == 2) {
- t = (int16_t) (raw[0]<<8 | raw[1]);
- return (float) t / 340 + 36.53f;
- }
- return 0;
- }
复制代码数据通过串口发送给pc,通过SerialChat现实波形,这里同时输出了温度值
- static float m[6];
- int ret = mpu_get_motion6(m);
- if (ret) {
- DEBUGOUT(/*"MPU6050 a/g: "*/"%4.3f,%4.3f,%4.3f,%4.3f,%4.3f,%4.3f"/*"\r\n"*/,
- m[0], m[1], m[2], m[3], m[4], m[5]);
- DEBUGOUT(",%2.3f\r\n", mpu_get_temperature());
- // DEBUGOUT("Temp=[%4.3f]`C\r\n", mpu_get_temperature()); //m[6]);
- } else {
- DEBUGOUT("get motion data failed, check connection again!\r\n");
- break;
- }
复制代码最后看波形,最上面亮绿色的是温度,下面有6个波形是对应加速度和角速度的,MPU6050是拿在手上的,可以明显看到抖动,哈哈。。
SerialChat网上有说怎么用,配置需要自己摸索一下,当时捣鼓了半天才搞明白,顺便把我的配置发上来,配置说明里面也有,2楼找附件哈。。