OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6030|回复: 2

MPU9250使用MASTER模式来控制磁力计,无法正常读取磁力计原始数据

[复制链接]

1

主题

2

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2019-11-4
在线时间
5 小时
发表于 2019-12-19 15:06:44 | 显示全部楼层 |阅读模式
1金钱
    首先我使用了CubeMX成功配置了I2C,并且能够顺利读取 写入数据到MOU9250中。然后我继续移植了正点原子的九轴飞行器的DMP的内容。重新编写了MPU9250.h和MPU9250.c
    然后使用BYPASS模式时,可以顺利读取速度 加速度 和 磁力计的数据。
    但是一旦使用DMP库内的mpu_get_compass_reg函数来读取磁力计时,就读不到任何信息。

    如下是我的初始化函数,和原子哥代码中的初始化过程一模一样:如下:
  1. uint8_t mpu_dmp_init(void)
  2. {
  3.         printf("\r\n0\r\n");
  4.         uint8_t res=0;
  5.     struct int_param_s int_param;
  6.     unsigned char accel_fsr;
  7.     unsigned short gyro_rate, gyro_fsr;
  8.     unsigned short compass_fsr;
  9.         if(mpu_init(&int_param)==0)        //初始化MPU9250
  10.         {         
  11.          res=inv_init_mpl();     //初始化MPL
  12.          if(res)return 1;
  13.          inv_enable_quaternion();
  14.          inv_enable_9x_sensor_fusion();
  15.          inv_enable_fast_nomot();
  16.          inv_enable_gyro_tc();
  17.          inv_enable_vector_compass_cal();
  18.          inv_enable_magnetic_disturbance();
  19.          inv_enable_eMPL_outputs();
  20.          res=inv_start_mpl();    //开启MPL
  21.          if(res)return 1;
  22.                 res=mpu_set_sensors(INV_XYZ_GYRO|INV_XYZ_ACCEL|INV_XYZ_COMPASS);//设置所需要的传感器
  23.                 if(res)return 2;
  24.                 res=mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL);   //设置FIFO
  25.                 if(res)return 3;
  26.                 res=mpu_set_sample_rate(DEFAULT_MPU_HZ);                    //设置采样率
  27.                 if(res)return 4;
  28.          res=mpu_set_compass_sample_rate(1000/COMPASS_READ_MS);  //设置磁力计采样率
  29.          if(res)return 5;
  30.          mpu_get_sample_rate(&gyro_rate);
  31.          mpu_get_gyro_fsr(&gyro_fsr);
  32.          mpu_get_accel_fsr(&accel_fsr);
  33.          mpu_get_compass_fsr(&compass_fsr);
  34.          inv_set_gyro_sample_rate(1000000L/gyro_rate);
  35.          inv_set_accel_sample_rate(1000000L/gyro_rate);
  36.          inv_set_compass_sample_rate(COMPASS_READ_MS*1000L);
  37.          inv_set_gyro_orientation_and_scale(
  38.              inv_orientation_matrix_to_scalar(gyro_orientation),(long)gyro_fsr<<15);
  39.          inv_set_accel_orientation_and_scale(
  40.              inv_orientation_matrix_to_scalar(gyro_orientation),(long)accel_fsr<<15);
  41.          inv_set_compass_orientation_and_scale(
  42.              inv_orientation_matrix_to_scalar(comp_orientation),(long)compass_fsr<<15);
  43.             
  44.                 res=dmp_load_motion_driver_firmware();                             //加载dmp固件
  45.                 if(res)return 6;
  46.                 res=dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation));//设置陀螺仪方向
  47.                 if(res)return 7;
  48.                 res=dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT|DMP_FEATURE_TAP|                    //设置dmp功能
  49.                     DMP_FEATURE_ANDROID_ORIENT|DMP_FEATURE_SEND_RAW_ACCEL|DMP_FEATURE_SEND_CAL_GYRO|
  50.                     DMP_FEATURE_GYRO_CAL);
  51.                 if(res)return 8;
  52.                 res=dmp_set_fifo_rate(DEFAULT_MPU_HZ);        //设置DMP输出速率(最大不超过200Hz)
  53.                 if(res)return 9;   
  54.                 res=run_self_test();                //自检
  55.                 if(res)return 10;   
  56.                 res=mpu_set_dmp_state(1);        //使能DMP
  57.                 if(res)return 11;   
  58.         }
  59.         return 0;
  60. }
复制代码
初始化后,main.c里这么调用的:
  1.   while (1)
  2.   {
  3.           printf("\r\n初始化-------\r\n");
  4.           recv = mpu_dmp_init();
  5.           if (recv == 0)
  6.           {
  7.                   break;
  8.           }
  9.           else
  10.           {
  11.                   printf("\r\n初始化失败\r\n");
  12.           }
  13.   }
复制代码
  1. while (1)
  2.   {
  3.     /* USER CODE END WHILE */

  4.     /* USER CODE BEGIN 3 */
  5.           printf("\r\n******************************************\r\n");
  6.           if ((recv = mpu_get_gyro_reg(gyro, 0)) != 0)
  7.           {
  8.                   printf("\r\nGet speed wrong\r\n");
  9.           }
  10.           if ((recv = mpu_get_accel_reg(accel, 0)) != 0)
  11.           {
  12.                   printf("\r\nGet accel wrong\r\n");
  13.           }
  14.           if ((recv = mpu_get_compass_reg(magnet, 0)) != 0)
  15.           {
  16.                   printf("\r\nGet magnet wrong\r\n");
  17.           }

  18.           printf("\r\nThis is speed:vx=%d,vy=%d,vz=%d\r\n", gyro[X], gyro[Y], gyro[Z]);
  19.           printf("\r\nThis is accel:ax=%d,ay=%d,az=%d\r\n", accel[X], accel[Y], accel[Z]);
  20.           printf("\r\nThis is magnet:mx=%d,my=%d,mz=%d\r\n", magnet[X], magnet[Y], magnet[Z]);
  21.           printf("\r\n******************************************\r\n");
  22.           HAL_Delay(100);
  23.          
  24.   }
复制代码
无法读出磁力计数据

但是用bypass可以读出:
  1. if ((recv = MPU_Get_Magnetometer(&magnet[0], &magnet[1], &magnet[2])) != 0)
  2.           {
  3.                   printf("\r\nGet magnet wrong\r\n");
  4.           }
复制代码
  1. int8_t MPU_Get_Magnetometer(short *mx, short *my, short *mz)
  2. {
  3.         uint8_t buf[6];
  4.         int8_t res;
  5.         mpu_set_bypass(1);
  6.         if ((res = MPU_Read_Bytes(AK8963_ADDR, MAG_XOUT_L, 6, buf)) != 0)
  7.         {
  8.                 return res;
  9.         }
  10.         HAL_Delay(100);
  11.         if (res == 0)
  12.         {
  13.                 *mx = ((uint16_t)buf[1] << 8) | buf[0];
  14.                 *my = ((uint16_t)buf[3] << 8) | buf[2];
  15.                 *mz = ((uint16_t)buf[5] << 8) | buf[4];
  16.         }
  17.         if ((res = MPU_Write_Byte(AK8963_ADDR, MAG_CNTL1, 0X11)) != 0)
  18.         {
  19.                 return res;
  20.         }
  21.         mpu_set_bypass(0);
  22.         HAL_Delay(100);

  23.         return res;
  24. }
复制代码
最后发现确实是MASTER 模式没有成功。因为我在主函数中写了一小段测试代码:
  1. int8_t recv = 0;

  2.         uint8_t uc = 0X20;
  3.         MPU_Write_Bytes(0XD0, 0X6A, 1, &uc);

  4.         uint8_t mstctrol = 0X0D;
  5.         MPU_Write_Bytes(0XD0,0X24 , 1, &mstctrol);

  6.         uint8_t m0 = 255;
  7.         MPU_Read_Bytes(0XD0, 0X24, 1, &m0);
  8.         printf("\r\nM0 = %d\r\n", m0);

  9.         uint8_t u0 = 255;
  10.         MPU_Read_Bytes(0XD0, 0X6A, 1, &u0);
  11.         printf("\r\nU0= %d\r\n", u0);

  12.         mpu_set_bypass(1);
  13.         uint8_t c1 = 255;
  14.         MPU_Read_Bytes(0X18, 0X0A, 1, &c1);
  15.         printf("\r\nC1 = %d\r\n", c1);
  16.         mpu_set_bypass(0);

  17.         uint8_t addddr = 0X18;//0X0C两个都试了
  18.         recv = MPU_Write_Bytes(0XD0, 0X28, 1, &addddr);
  19.         uint8_t control_reg = 0X0A;
  20.         recv = MPU_Write_Bytes(0XD0, 0X29, 1, &control_reg);
  21.         uint8_t CONBIT = 0X80 | 1;
  22.         recv = MPU_Write_Bytes(0XD0, 0X30, 1, &CONBIT);
  23.         uint8_t modechoice = 0X11;
  24.         recv = MPU_Write_Bytes(0XD0, 0X64, 1, &modechoice);
  25.         uint8_t delyamode = 0X03;
  26.         recv = MPU_Write_Bytes(0XD0, 0X67, 1, &delyamode);
  27.         HAL_Delay(1000);
  28.         mpu_set_bypass(1);
  29.         c1 = 255;
  30.         MPU_Read_Bytes(0X18, 0X0A, 1, &c1);
  31.         printf("\r\nC1 2222 = %d\r\n", c1);
  32.         mpu_set_bypass(0);
复制代码
就是先把磁力计CONTROL1和SLAVE1联系在一起。然后给SLAVE1_d0写入0X11,再用bypass模式读取磁力计CONTROL1寄存器。发现根本没有成功。MASTER模式下的写入失败!!!!!!。我基本上快疯了。这个问题搞了我两天没有一点点头绪。有咩有大佬知道原因?帮助我解决一下,如果大佬帮我解决了。马上支付宝100元红包(学生党 么得钱 哎 见谅)。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2019-11-4
在线时间
5 小时
 楼主| 发表于 2019-12-19 19:11:35 | 显示全部楼层
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2019-12-20 02:27:50 | 显示全部楼层
不用cube,直接移植我们例程,成功么?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 17:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表