[STM32F4] 【STM32】I2C练习,HAL库读取MPU6050角度陀螺仪

[复制链接]
3304|47
 楼主| 欢乐家园 发表于 2022-5-28 17:48 | 显示全部楼层 |阅读模式
MPU6050简介
MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时间轴之差的问题,减少了大量的封装空间。当连接到三轴磁强计时,MPU-60X0提供完整的9轴运动融合输出到其主I2C或SPI端口(SPI仅在MPU-6000上可用)。
寄存器查询表格 646306291efe78e1bc.png

 楼主| 欢乐家园 发表于 2022-5-28 17:49 | 显示全部楼层
STM32CubeMx配置
配置使用外部高速时钟

26736291f034d2ab1.png
 楼主| 欢乐家园 发表于 2022-5-28 17:51 | 显示全部楼层
配置调试方式
809616291f0a316b9a.png
 楼主| 欢乐家园 发表于 2022-5-28 17:52 | 显示全部楼层
配置I2C,这里只需要选择I2C即可其余配置默认,记住自己选择的I2C引脚。

268296291f0cc1d4ae.png
 楼主| 欢乐家园 发表于 2022-5-28 17:54 | 显示全部楼层
配置时钟
827336291f147bd16d.png
878566291f13462dae.png
 楼主| 欢乐家园 发表于 2022-5-28 18:21 | 显示全部楼层
生成工程
595886291f7ba29b5f.png
 楼主| 欢乐家园 发表于 2022-5-28 18:22 | 显示全部楼层
 楼主| 欢乐家园 发表于 2022-5-28 19:35 | 显示全部楼层
 楼主| 欢乐家园 发表于 2022-5-28 19:36 | 显示全部楼层
代码文件
mpu6050.h文件
  1. #ifndef __MPU6050_H
  2. #define __MPU6050_H

  3. #include "main.h"

  4. #define SMPLRT_DIV   0x19  // 采样率分频,典型值:0x07(125Hz) */
  5. #define CONFIG       0x1A  // 低通滤波频率,典型值:0x06(5Hz) */
  6. #define GYRO_CONFIG  0x1B  // 陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s) */
  7. #define ACCEL_CONFIG 0x1C  // 加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz) */

  8. #define ACCEL_XOUT_H 0x3B  // 存储最近的X轴、Y轴、Z轴加速度感应器的测量值 */
  9. #define ACCEL_XOUT_L 0x3C
  10. #define ACCEL_YOUT_H 0x3D
  11. #define ACCEL_YOUT_L 0x3E
  12. #define ACCEL_ZOUT_H 0x3F
  13. #define ACCEL_ZOUT_L 0x40

  14. #define TEMP_OUT_H   0x41  // 存储的最近温度传感器的测量值 */
  15. #define TEMP_OUT_L   0x42

  16. #define GYRO_XOUT_H  0x43  // 存储最近的X轴、Y轴、Z轴陀螺仪感应器的测量值 */
  17. #define GYRO_XOUT_L  0x44
  18. #define GYRO_YOUT_H  0x45
  19. #define GYRO_YOUT_L  0x46
  20. #define GYRO_ZOUT_H  0x47
  21. #define GYRO_ZOUT_L  0x48

  22. #define PWR_MGMT_1   0x6B   // 电源管理,典型值:0x00(正常启用) */
  23. #define WHO_AM_I     0x75         // IIC地址寄存器(默认数值0x68,只读) */
  24. #define MPU6050_ADDR 0xD0        // MPU6050手册上的地址,这里也可以使用serch函数去搜索

  25. typedef struct{
  26.         // 角速度
  27.         float Accel_X;
  28.         float Accel_Y;
  29.         float Accel_Z;
  30.         // 角度
  31.         float Gyro_X;
  32.         float Gyro_Y;
  33.         float Gyro_Z;
  34.         // 温度
  35.         float Temp;
  36. }MPU6050DATATYPE;

  37. extern MPU6050DATATYPE Mpu6050_Data;
  38. extern I2C_HandleTypeDef hi2c1;
  39. extern I2C_HandleTypeDef hi2c2;

  40. int16_t Sensor_I2C2_Serch(void);
  41. int8_t MPU6050_Init(int16_t Addr);

  42. int8_t Sensor_I2C2_ReadOneByte(uint16_t DevAddr, uint16_t MemAddr, uint8_t *oData);
  43. int8_t Sensor_I2C2_WriteOneByte(uint16_t DevAddr, uint16_t MemAddr, uint8_t *iData);

  44. void MPU6050_Read_Accel(void);
  45. void MPU6050_Read_Gyro(void);
  46. void MPU6050_Read_Temp(void);

  47. #endif


 楼主| 欢乐家园 发表于 2022-5-28 19:39 | 显示全部楼层
mpu6050.c文件
 楼主| 欢乐家园 发表于 2022-5-28 19:40 | 显示全部楼层
  1. #include "mpu6050.h"

  2. static int16_t Mpu6050Addr = 0xD0;
  3. MPU6050DATATYPE Mpu6050_Data;

  4. int8_t Sensor_I2C2_Read(uint16_t DevAddr, uint16_t MemAddr, uint8_t *oData, uint8_t DataLen)
  5. {
  6.         return HAL_I2C_Mem_Read(&hi2c2,DevAddr,MemAddr,1,oData,DataLen,1000);
  7. }

  8. int8_t Sensor_I2C2_Write(uint16_t DevAddr, uint16_t MemAddr, uint8_t *iData, uint8_t DataLen)
  9. {
  10.         return HAL_I2C_Mem_Write(&hi2c2,DevAddr,MemAddr,1,iData,DataLen,1000);
  11. }

  12. int16_t Sensor_I2C2_Serch(void)
  13. {
  14.         for(uint8_t i = 1; i < 255; i++)
  15.         {
  16.                 if(HAL_I2C_IsDeviceReady(&hi2c2, i, 1, 1000) == HAL_OK)
  17.                 {
  18.                         Mpu6050Addr = i;
  19.                         return i;
  20.                 }
  21.         }
  22.         return 0xD1;
  23. }

  24. int8_t MPU6050_Init(int16_t Addr)
  25. {
  26.         uint8_t check;
  27.         HAL_I2C_Mem_Read(&hi2c2,Addr,WHO_AM_I,1,&check,1,1000);
  28.         if(check == 0x98) // 确认设备用 地址寄存器
  29.         {       
  30.                 check = 0x00;
  31.                 Sensor_I2C2_Write(Addr,PWR_MGMT_1,&check, 1);             // 唤醒
  32.                 check = 0x07;       
  33.                 Sensor_I2C2_Write(Addr,SMPLRT_DIV,&check, 1);            // 1Khz的速率
  34.                 check = 0x00;
  35.                 Sensor_I2C2_Write(Addr,ACCEL_CONFIG,&check, 1);                 // 加速度配置
  36.                 check = 0x00;
  37.                 Sensor_I2C2_Write(Addr,GYRO_CONFIG,&check, 1);                // 陀螺配置
  38.                 return 0;
  39.         }
  40.         return -1;
  41. }

  42. void MPU6050_Read_Accel(void)
  43. {
  44.         uint8_t Read_Buf[6];
  45.        
  46.         // 寄存器依次是加速度X高 - 加速度X低 - 加速度Y高位 - 加速度Y低位 - 加速度Z高位 - 加速度度Z低位
  47.         Sensor_I2C2_Read(Mpu6050Addr, ACCEL_XOUT_H, Read_Buf, 6);
  48.        
  49.         Mpu6050_Data.Accel_X = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
  50.         Mpu6050_Data.Accel_Y = (int16_t)(Read_Buf[2] << 8 | Read_Buf[3]);
  51.         Mpu6050_Data.Accel_Z = (int16_t)(Read_Buf[4] << 8 | Read_Buf[5]);
  52.        
  53.         Mpu6050_Data.Accel_X = Mpu6050_Data.Accel_X / 16384.0f;
  54.         Mpu6050_Data.Accel_Y = Mpu6050_Data.Accel_Y / 16384.0f;
  55.         Mpu6050_Data.Accel_Z = Mpu6050_Data.Accel_Z / 16384.0f;
  56.        
  57. }
  58. void MPU6050_Read_Gyro(void)
  59. {
  60.         uint8_t Read_Buf[6];
  61.        
  62.         // 寄存器依次是角度X高 - 角度X低 - 角度Y高位 - 角度Y低位 - 角度Z高位 - 角度Z低位
  63.         Sensor_I2C2_Read(Mpu6050Addr, GYRO_XOUT_H, Read_Buf, 6);
  64.        
  65.         Mpu6050_Data.Gyro_X = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
  66.         Mpu6050_Data.Gyro_Y = (int16_t)(Read_Buf[2] << 8 | Read_Buf[3]);
  67.         Mpu6050_Data.Gyro_Z = (int16_t)(Read_Buf[4] << 8 | Read_Buf[5]);
  68.        
  69.         Mpu6050_Data.Gyro_X = Mpu6050_Data.Gyro_X / 131.0f;
  70.         Mpu6050_Data.Gyro_Y = Mpu6050_Data.Gyro_Y / 131.0f;
  71.         Mpu6050_Data.Gyro_Z = Mpu6050_Data.Gyro_Z / 131.0f;
  72.        
  73. }
  74. void MPU6050_Read_Temp(void)
  75. {
  76.     uint8_t Read_Buf[2];
  77.        
  78.         Sensor_I2C2_Read(Mpu6050Addr, TEMP_OUT_H, Read_Buf, 2);
  79.        
  80.         Mpu6050_Data.Temp = (int16_t)(Read_Buf[0] << 8 | Read_Buf[1]);
  81.        
  82.         Mpu6050_Data.Temp = 36.53f + (Mpu6050_Data.Temp / 340.0f);
  83. }


 楼主| 欢乐家园 发表于 2022-5-28 19:41 | 显示全部楼层
main.c文件
  1. MPU6050_Init(Sensor_I2C2_Serch());
  2. while(1)
  3. {
  4.                 HAL_Delay(500);
  5.                 MPU6050_Read_Accel();
  6.                 MPU6050_Read_Gyro();
  7.                 MPU6050_Read_Temp();
  8. }
 楼主| 欢乐家园 发表于 2022-5-28 19:41 | 显示全部楼层
总结
MPU6050的数据的读取非常的简单,但是这个数据还无法直接使用,这里我只是用来联系I2C的读取,对于六轴的算法还有很多,可以转移到别的博主**进行学习参考。
macpherson 发表于 2022-6-6 13:12 | 显示全部楼层
怎样用单片机取mpu6050陀螺仪的数据用电脑显示波形
hudi008 发表于 2022-6-7 11:24 | 显示全部楼层
如何用i2c读取mpu6050
jonas222 发表于 2022-6-7 13:37 | 显示全部楼层
接上mpu6050陀螺仪后程序执行异常
hudi008 发表于 2022-6-7 14:57 | 显示全部楼层
三轴陀螺仪MPU-6050型号,如何计算航向角
sheflynn 发表于 2022-6-7 15:43 | 显示全部楼层
如何用stm32读取MPU6050模块中的WHO
fentianyou 发表于 2022-6-7 18:10 | 显示全部楼层
硬件i2c读取一次mpu6050数据大概多长时间
chenqianqian 发表于 2022-6-7 18:44 来自手机 | 显示全部楼层
IIC读取数据速度还是慢了点
您需要登录后才可以回帖 登录 | 注册

本版积分规则

114

主题

1067

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部