回答

收藏

[评测分享] 【正点原子F103精英板试用】初探IIC之MPU6050

#板卡评测 #板卡评测 2050 人阅读 | 0 人回复 | 2022-05-25

鸽鸽鸽王来了
学校校赛+期末考试
忙到起飞

今天还是试试给MPU6050用IIC协议读取他的数据
和以前一样,配置IIC (楼主电脑被重置了所以只能用keil了)首先看看6050的数据手册看看有什么需要配置的

首先可以看到 在使用IIC协议时 他的通讯速率有400K,这一点切记
要不然到DMP设置的时候会超级慢(DMP的使用那是后话)


IIC时序图和6050与6000对比
(个人更加对推荐ICM20602和ICM20600,毕竟都2022年了ADXL345都快消失了)


典型电路


这里描述了MPU6050的从机地址主要取决于AD0的连接 有0X69和0x68两种

6050的寄存器宏定义
  1. #define MPU_SELF_TESTX_REG                0X0D        //自检寄存器X
  2. #define MPU_SELF_TESTY_REG                0X0E        //自检寄存器Y
  3. #define MPU_SELF_TESTZ_REG                0X0F        //自检寄存器Z
  4. #define MPU_SELF_TESTA_REG                0X10        //自检寄存器A
  5. #define MPU_SAMPLE_RATE_REG                0X19        //采样频率分频器
  6. #define MPU_CFG_REG                        0X1A        //配置寄存器
  7. #define MPU_GYRO_CFG_REG                0X1B        //陀螺仪配置寄存器
  8. #define MPU_ACCEL_CFG_REG                0X1C        //加速度计配置寄存器
  9. #define MPU_MOTION_DET_REG                0X1F        //运动检测阀值设置寄存器
  10. #define MPU_FIFO_EN_REG                        0X23        //FIFO使能寄存器
  11. #define MPU_I2CMST_CTRL_REG                0X24        //IIC主机控制寄存器
  12. #define MPU_I2CSLV0_ADDR_REG                0X25        //IIC从机0器件地址寄存器
  13. #define MPU_I2CSLV0_REG                        0X26        //IIC从机0数据地址寄存器
  14. #define MPU_I2CSLV0_CTRL_REG                0X27        //IIC从机0控制寄存器
  15. #define MPU_I2CSLV1_ADDR_REG                0X28        //IIC从机1器件地址寄存器
  16. #define MPU_I2CSLV1_REG                        0X29        //IIC从机1数据地址寄存器
  17. #define MPU_I2CSLV1_CTRL_REG                0X2A        //IIC从机1控制寄存器
  18. #define MPU_I2CSLV2_ADDR_REG                0X2B        //IIC从机2器件地址寄存器
  19. #define MPU_I2CSLV2_REG                        0X2C        //IIC从机2数据地址寄存器
  20. #define MPU_I2CSLV2_CTRL_REG                0X2D        //IIC从机2控制寄存器
  21. #define MPU_I2CSLV3_ADDR_REG                0X2E        //IIC从机3器件地址寄存器
  22. #define MPU_I2CSLV3_REG                        0X2F        //IIC从机3数据地址寄存器
  23. #define MPU_I2CSLV3_CTRL_REG                0X30        //IIC从机3控制寄存器
  24. #define MPU_I2CSLV4_ADDR_REG                0X31        //IIC从机4器件地址寄存器
  25. #define MPU_I2CSLV4_REG                        0X32        //IIC从机4数据地址寄存器
  26. #define MPU_I2CSLV4_DO_REG                0X33        //IIC从机4写数据寄存器
  27. #define MPU_I2CSLV4_CTRL_REG                0X34        //IIC从机4控制寄存器
  28. #define MPU_I2CSLV4_DI_REG                0X35        //IIC从机4读数据寄存器

  29. #define MPU_I2CMST_STA_REG                0X36        //IIC主机状态寄存器
  30. #define MPU_INTBP_CFG_REG                0X37        //中断/旁路设置寄存器
  31. #define MPU_INT_EN_REG                        0X38        //中断使能寄存器
  32. #define MPU_INT_STA_REG                        0X3A        //中断状态寄存器

  33. #define MPU_ACCEL_XOUTH_REG                0X3B        //加速度值,X轴高8位寄存器
  34. #define MPU_ACCEL_XOUTL_REG                0X3C        //加速度值,X轴低8位寄存器
  35. #define MPU_ACCEL_YOUTH_REG                0X3D        //加速度值,Y轴高8位寄存器
  36. #define MPU_ACCEL_YOUTL_REG                0X3E        //加速度值,Y轴低8位寄存器
  37. #define MPU_ACCEL_ZOUTH_REG                0X3F        //加速度值,Z轴高8位寄存器
  38. #define MPU_ACCEL_ZOUTL_REG                0X40        //加速度值,Z轴低8位寄存器

  39. #define MPU_TEMP_OUTH_REG                0X41        //温度值高八位寄存器
  40. #define MPU_TEMP_OUTL_REG                0X42        //温度值低8位寄存器

  41. #define MPU_GYRO_XOUTH_REG                0X43        //陀螺仪值,X轴高8位寄存器
  42. #define MPU_GYRO_XOUTL_REG                0X44        //陀螺仪值,X轴低8位寄存器
  43. #define MPU_GYRO_YOUTH_REG                0X45        //陀螺仪值,Y轴高8位寄存器
  44. #define MPU_GYRO_YOUTL_REG                0X46        //陀螺仪值,Y轴低8位寄存器
  45. #define MPU_GYRO_ZOUTH_REG                0X47        //陀螺仪值,Z轴高8位寄存器
  46. #define MPU_GYRO_ZOUTL_REG                0X48        //陀螺仪值,Z轴低8位寄存器

  47. #define MPU_I2CSLV0_DO_REG                0X63        //IIC从机0数据寄存器
  48. #define MPU_I2CSLV1_DO_REG                0X64        //IIC从机1数据寄存器
  49. #define MPU_I2CSLV2_DO_REG                0X65        //IIC从机2数据寄存器
  50. #define MPU_I2CSLV3_DO_REG                0X66        //IIC从机3数据寄存器

  51. #define MPU_I2CMST_DELAY_REG                0X67        //IIC主机延时管理寄存器
  52. #define MPU_SIGPATH_RST_REG                0X68        //信号通道复位寄存器
  53. #define MPU_MDETECT_CTRL_REG                0X69        //运动检测控制寄存器
  54. #define MPU_USER_CTRL_REG                0X6A        //用户控制寄存器
  55. #define MPU_PWR_MGMT1_REG                0X6B        //电源管理寄存器1
  56. #define MPU_PWR_MGMT2_REG                0X6C        //电源管理寄存器2
  57. #define MPU_FIFO_CNTH_REG                0X72        //FIFO计数寄存器高八位
  58. #define MPU_FIFO_CNTL_REG                0X73        //FIFO计数寄存器低八位
  59. #define MPU_FIFO_RW_REG                        0X74        //FIFO读写寄存器
  60. #define MPU_DEVICE_ID_REG                0X75        //器件ID寄存器
复制代码


首先先初始化传感器
这里重新定义了一个MPU6050_Write函数方便开发
  1. uint8_t MPU_Init(void)
  2. {
  3.   uint8_t res;
  4.   extern I2C_HandleTypeDef hi2c1;
  5.   HAL_I2C_Init(&hi2c1);
  6.   MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);        //复位MPU6050
  7.   MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);        //唤醒MPU6050
  8.   MPU_Set_Gyro_Fsr(3);                                        //陀螺仪传感器,±2000dps
  9.   MPU_Set_Accel_Fsr(0);                                        //加速度传感器,±2g
  10.   MPU_Set_Rate(50);                                                //设置采样率50Hz
  11.   MPU_Write_Byte(MPU_INT_EN_REG,0X00);        //关闭所有中断
  12.   MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);        //I2C主模式关闭
  13.   MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);        //关闭FIFO
  14.   MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);        //INT引脚低电平有效
  15.   res=MPU_Read_Byte(MPU_DEVICE_ID_REG);
  16.   if(res==MPU_ADDR)//器件ID正确
  17.   {
  18.     MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);        //设置CLKSEL,PLL X轴为参考
  19.     MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);        //加速度与陀螺仪都工作
  20.     MPU_Set_Rate(50);                                                //设置采样率为50Hz
  21.   }else return 1;
  22.   return 0;
  23. }
复制代码
  1. uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr)
  2. {
  3.         return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  
  4. }
  5. //设置MPU6050加速度传感器满量程范围
  6. //fsr:0,±2g;1,±4g;2,±8g;3,±16g
  7. //返回值:0,设置成功
  8. //    其他,设置失败
  9. uint8_t MPU_Set_Accel_Fsr(uint8_t fsr)
  10. {
  11.         return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  
  12. }
  13. //设置MPU6050的数字低通滤波器
  14. //lpf:数字低通滤波频率(Hz)
  15. //返回值:0,设置成功
  16. //    其他,设置失败
  17. uint8_t MPU_Set_LPF(uint16_t lpf)
  18. {
  19.         uint8_t data=0;
  20.         if(lpf>=188)data=1;
  21.         else if(lpf>=98)data=2;
  22.         else if(lpf>=42)data=3;
  23.         else if(lpf>=20)data=4;
  24.         else if(lpf>=10)data=5;
  25.         else data=6;
  26.         return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  
  27. }
  28. //设置MPU6050的采样率(假定Fs=1KHz)
  29. //rate:4~1000(Hz)
  30. //返回值:0,设置成功
  31. //    其他,设置失败
  32. uint8_t MPU_Set_Rate(uint16_t rate)
  33. {
  34.         uint8_t data;
  35.         if(rate>1000)rate=1000;
  36.         if(rate<4)rate=4;
  37.         data=1000/rate-1;
  38.         data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);        //设置数字低通滤波器
  39.         return MPU_Set_LPF(rate/2);        //自动设置LPF为采样率的一半
  40. }

  41. //得到温度值
  42. //返回值:温度值(扩大了100倍)
  43. float MPU_Get_Temperature(void)
  44. {
  45.   unsigned char  buf[2];
  46.   short raw;
  47.   float temp;
  48.   
  49.   MPU_Read_Len(MPU_TEMP_OUTH_REG,2,buf);
  50.   raw=(buf[0]<<8)| buf[1];  
  51.   temp=(36.53+((double)raw)/340)*100;  
  52. //  temp = (long)((35 + (raw / 340)) * 65536L);
  53.   return temp/100.0f;
  54. }
  55. //得到陀螺仪值(原始值)
  56. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  57. //返回值:0,成功
  58. //    其他,错误代码
  59. uint8_t MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
  60. {
  61.     uint8_t buf[6],res;  
  62.         res=MPU_Read_Len(MPU_GYRO_XOUTH_REG,6,buf);
  63.         if(res==0)
  64.         {
  65.                 *gx=((uint16_t)buf[0]<<8)|buf[1];  
  66.                 *gy=((uint16_t)buf[2]<<8)|buf[3];  
  67.                 *gz=((uint16_t)buf[4]<<8)|buf[5];
  68.         }        
  69.     return res;
  70. }
  71. //得到加速度值(原始值)
  72. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  73. //返回值:0,成功
  74. //    其他,错误代码
  75. uint8_t MPU_Get_Accelerometer(short *ax,short *ay,short *az)
  76. {
  77.     uint8_t buf[6],res;  
  78.         res=MPU_Read_Len(MPU_ACCEL_XOUTH_REG,6,buf);
  79.         if(res==0)
  80.         {
  81.                 *ax=((uint16_t)buf[0]<<8)|buf[1];  
  82.                 *ay=((uint16_t)buf[2]<<8)|buf[3];  
  83.                 *az=((uint16_t)buf[4]<<8)|buf[5];
  84.         }        
  85.     return res;;
  86. }


  87. //IIC连续写
  88. uint8_t MPU_Write_Len(uint8_t reg,uint8_t len,uint8_t *buf)
  89. {
  90.   extern I2C_HandleTypeDef hi2c1;
  91.   HAL_I2C_Mem_Write(&hi2c1, MPU_WRITE, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff);
  92.   HAL_Delay(100);
  93.   
  94.   return 0;
  95. }
  96. //IIC连续读
  97. //addr:器件地址
  98. //reg:要读取的寄存器地址
  99. //len:要读取的长度
  100. //buf:读取到的数据存储区
  101. //返回值:0,正常
  102. //    其他,错误代码
  103. uint8_t MPU_Read_Len(uint8_t reg,uint8_t len,uint8_t *buf)
  104. {
  105.   extern I2C_HandleTypeDef hi2c1;
  106.   HAL_I2C_Mem_Read(&hi2c1, MPU_READ, reg, I2C_MEMADD_SIZE_8BIT, buf, len, 0xfff);
  107.   HAL_Delay(100);
  108.   
  109.   return 0;       
  110. }
  111. //IIC写一个字节
  112. //reg:寄存器地址
  113. //data:数据
  114. //返回值:0,正常
  115. //    其他,错误代码
  116. uint8_t MPU_Write_Byte(uint8_t reg,uint8_t data)                                  
  117. {
  118.   extern I2C_HandleTypeDef hi2c1;
  119.   unsigned char W_Data=0;

  120.   W_Data = data;
  121.   HAL_I2C_Mem_Write(&hi2c1, MPU_WRITE, reg, I2C_MEMADD_SIZE_8BIT, &W_Data, 1, 0xfff);
  122.   HAL_Delay(100);
  123.   
  124.   return 0;
  125. }
  126. //IIC读一个字节
  127. //reg:寄存器地址
  128. //返回值:读到的数据
  129. uint8_t MPU_Read_Byte(uint8_t reg)
  130. {
  131.   extern I2C_HandleTypeDef hi2c1;
  132.   unsigned char R_Data=0;
  133.   
  134.   HAL_I2C_Mem_Read(&hi2c1, MPU_READ, reg, I2C_MEMADD_SIZE_8BIT, &R_Data, 1, 0xfff);
  135.   HAL_Delay(100);
  136.   
  137.   return R_Data;               
  138. }
复制代码
在main.c里初始化器件后在调用GET函数就可以正常读取数据了;
至于读取后的数据如何解算待后期分解

分享到:
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条