STM32/STM8技术论坛
直播中

sjw1716094642

10年用户 83经验值
擅长:63329
私信 关注
[资料]

【STM32F411 Nucleo试用体验】4、通过MPU6050获取小车倾斜角


S344FZYYFR798~8{ITJEKF3.png

8A_8EJT`_QU3QH37`7O@}2G.png

      MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时间轴之差的问题,减少了大量的封装空间。
      MPU-6000(6050)的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追踪快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的IC或最高达20MHz的SPI(MPU-6050没有SPI)。MPU-6000可在不同电压下工作,VDD供电电压介为2.5V±5%、3.0V±5%或3.3V±5%,逻辑接口VDDIO供电为1.8V± 5%(MPU6000仅用VDD)。MPU-6000的包装尺寸4x4x0.9mm(QFN),在业界是革命性的尺寸。其他的特征包含内建的温度感测器、包含在运作环境中仅有±1%变动的振荡器。
      MPU6050以数字输出6轴或9轴的旋转矩阵、四元数(quaternion)、欧拉角格式(Euler Angle forma)的融合演算数据。 具有131 LSBs/°/sec 敏感度与全格感测范围为±250、±500、±1000与±2000°/sec 的3轴角速度感测器(陀螺仪)。 可程式控制,且程式控制范围为±2g、±4g、±8g和±16g的3轴加速器。 移除加速器与陀螺仪轴间敏感度,降低设定给予的影响与感测器的飘移。 数字运动处理(DMP: Digital Motion Processing)引擎可减少复杂的融合演算数据、感测器同步化、姿势感应等的负荷。 运动处理数据库支持Android、Linux与Windows 内建之运作时间偏差与磁力感测器校正演算技术,免除了客户须另外进行校正的需求。 以数位输出的温度传感器 以数位输入的同步引脚(Sync pin)支援视频电子影相稳定技术与GPS 可程式控制的中断(interrupt)支援姿势识别、摇摄、画面放大缩小、滚动、快速下降中断、high-G中断、零动作感应、触击感应、摇动感应功能。 VDD供电电压为2.5V±5%、3.0V±5%、3.3V±5%;VDDIO为1.8V± 5% 陀螺仪运作电流:5mA,陀螺仪待命电流:5µA;加速器运作电流:350µA,加速器省电模式电流: 20µA@10Hz 高达400kHz快速模式的I2C,或最高至20MHz的SPI串行主机接口(serial host interface) 内建频率产生器在所有温度范围(full temperature range)仅有±1%频率变化。 使用者亲自测试 10,000 g 碰撞容忍度 为可携式产品量身订作的最小最薄包装 (4x4x0.9mm QFN) 符合RoHS及环境标准。
      这里我使用的是模拟I2C,因为使用引脚比较随意,通信效果也挺不错,所以我还是比较愿意使用模拟IC的。
MPU6050初始化及数据读取:

  1. u8 Init_MPU6050(void)
  2. {
  3.   I2C_GPIO_Config();
  4.   ysm(1);
  5.   I2C_Start();
  6.   ysm(1);
  7.   Single_Write(MPU6050_Addr,PWR_MGMT_1, 0x00);
  8.   Single_Write(MPU6050_Addr,SMPLRT_DIV, 0x02);
  9.   Single_Write(MPU6050_Addr,CONFIG, 0x02);
  10.   Single_Write(MPU6050_Addr,GYRO_CONFIG, 0x18);
  11.   Single_Write(MPU6050_Addr,ACCEL_CONFIG, 0x11);
  12.   return (Single_Read(MPU6050_Addr,WHO_AM_I));    //0X68
  13. }

  14. void READ6050_in_float(Float_mpu *data)
  15. {
  16.   u8 a,b;
  17.   a=Single_Read(MPU6050_Addr,ACCEL_XOUT_L);
  18.   b=Single_Read(MPU6050_Addr,ACCEL_XOUT_H);
  19.   data->AX=((short)(b<<8)|a)/4096.0f;

  20.   a=Single_Read(MPU6050_Addr,ACCEL_YOUT_L);
  21.   b=Single_Read(MPU6050_Addr,ACCEL_YOUT_H);
  22.   data->AY=((short)(b<<8)|a)/4096.0f;
  23.   
  24.   a=Single_Read(MPU6050_Addr,ACCEL_ZOUT_L);
  25.   b=Single_Read(MPU6050_Addr,ACCEL_ZOUT_H);
  26.   data->AZ=((short)(b<<8)|a)/4096.0f;
  27.   
  28.   a=Single_Read(MPU6050_Addr,GYRO_XOUT_L);
  29.   b=Single_Read(MPU6050_Addr,GYRO_XOUT_H);
  30.   data->GX=((short)(b<<8)|a)/16.384f;

  31.   a=Single_Read(MPU6050_Addr,GYRO_YOUT_L);
  32.   b=Single_Read(MPU6050_Addr,GYRO_YOUT_H);
  33.   data->GY=((short)(b<<8)|a)/16.384f;
  34.    
  35.   a=Single_Read(MPU6050_Addr,GYRO_ZOUT_L);
  36.   b=Single_Read(MPU6050_Addr,GYRO_ZOUT_H);
  37.   data->GZ=((short)(b<<8)|a)/16.384f;
  38.          
  39. }


数据更新:采集频率500HZ
  1. Float_mpu MPU_DATA,MPU_Final;
  2. float CAR_Dip_Angle;

  3. static float  MPU_ZREO_GX,MPU_ZREO_GY,MPU_ZREO_GZ;

  4. void TIM9_Init(void)
  5. {
  6.   RCC->APB2ENR|=0x10000;
  7.   TIM9->CR1=0;
  8.   TIM9->DIER=1;
  9.   TIM9->ARR=9999;
  10.   TIM9->PSC=19;
  11.   
  12.   NVIC->ISER[0]|=0x01U<
  13.   NVIC->IP[TIM1_BRK_TIM9_IRQn]=0x10;
  14.   
  15.   TIM9->CR1=1;
  16. }

  17. void Zreo_process(void)
  18. {
  19.   int k;
  20.   float gxtp=0,gytp=0,gztp=0;
  21.   k=100;
  22.   while(k--)
  23.   {
  24.     READ6050_in_float(&MPU_DATA);
  25.     gxtp+=MPU_DATA.GX;
  26.     gytp+=MPU_DATA.GY;
  27.     gztp+=MPU_DATA.GZ;
  28.     ysm(2);
  29.   }
  30.   MPU_ZREO_GX=gxtp/100.0f;
  31.   MPU_ZREO_GY=gytp/100.0f;
  32.   MPU_ZREO_GZ=gztp/100.0f;
  33.   CAR_Dip_Angle = atan2f(MPU_DATA.AX,MPU_DATA.AZ) * 57.3f;
  34. }

  35. void Data_UPdate_Init(void)
  36. {
  37.   Zreo_process();
  38.   TIM9_Init();
  39. }

  40. void TIM1_BRK_TIM9_IRQHandler(void)
  41. {
  42.   if(TIM9->SR&0x01)
  43.   {
  44.     READ6050_in_float(&MPU_DATA);
  45.     MPU_DATA.GX -= MPU_ZREO_GX;
  46.     MPU_DATA.GY -= MPU_ZREO_GY;
  47.     MPU_DATA.GZ -= MPU_ZREO_GZ;
  48.     MPU_Final.AX = MPU_Final.AX*0.7f + MPU_DATA.AX*0.3f;
  49.     MPU_Final.AY = MPU_Final.AY*0.7f + MPU_DATA.AY*0.3f;
  50.     MPU_Final.AZ = MPU_Final.AZ*0.7f + MPU_DATA.AZ*0.3f;
  51.     MPU_Final.GX = MPU_Final.GX*0.7f + MPU_DATA.GX*0.3f;
  52.     MPU_Final.GY = MPU_Final.GY*0.7f + MPU_DATA.GY*0.3f;
  53.     MPU_Final.GZ = MPU_Final.GZ*0.7f + MPU_DATA.GZ*0.3f;
  54.     CAR_Dip_Angle += (atan2f(MPU_Final.AX,MPU_Final.AZ) * 57.3f - CAR_Dip_Angle)*0.02f - MPU_Final.GY * 0.98f/500.0f;
  55.   }
  56.   TIM9->SR=0;
  57. }

PBFYEGY86IA[58HA34}AG1L.png

串口输出数据:
WLJ0K~VJ(GZ@JF9V]`L1[YH.png

IMG_20160723_170855.jpg

IMG_20160723_170905.jpg

谢谢阅读~
附上工程:
6、MPU6050.rar (602.1 KB)
(下载次数: 25, 2016-7-23 17:13 上传)


回帖(3)

泡芙奶昔

2016-7-25 10:14:40
不错哦!
举报

雷翌仁

2016-10-31 14:30:06
謝謝樓主分享!
举报

lee_st

2016-10-31 15:17:06
顶一下楼主,希望分享一下经验
举报

更多回帖

发帖
×
20
完善资料,
赚取积分