你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【HAL库每天一例】第084例:MPU6050陀螺仪

[复制链接]
haohao663 提问时间:2016-8-5 08:53 /
【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。

例程下载:
资料包括程序、相关说明资料以及软件使用截图

百度云盘:https://pan.baidu.com/s/1slN8rIt 密码:u6m1
360云盘:http://yunpan.cn/OcPiRp3wEcA92u密码 cfb6
(硬石YS-F1Pro开发板HAL库例程持续更新\2. 软件设计之高级裸机例程(HAL库版本)\YSF1_HAL-118. MPU6050陀螺仪
/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: 1. MPU6050陀螺仪(软件I2C)
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:硬石电子社区
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
  I2C总线是飞利浦公司开发的两线式串行总线。用于连接微控制器和外围设备。它是同步通信的一
种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。通过串行数据
(SDA)线和串行时钟 (SCL)线在连接到总线的器件间传递信息。每个器件都有一个唯一的地址识
别,而且都可以作为一个发送器或接收器。
MPU- 6000为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时之
轴间差的问题,减少了大量的包装空间。MPU-6000整合了3轴陀螺仪、3轴加速器,并含可藉由第二个
I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion
Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合演算技术
InvenSense的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,
并为应用开发提供架构化的API。

【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
【3】操作及现象
使用开发板配套的MINI USB线连接到开发板标示“调试串口”字样的MIMI USB接口(需要安装驱动),
在电脑端打开串口调试助手工具,设置参数为115200 8-N-1。下载完程序之后,将MPU6050接入I2C的
接口,在串口助手即可观察到各个值的变化

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/


软件模拟I2C
CubeMX_1.jpg
CubeMX_2.jpg

mpu6050.c文件内容
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: main.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: MPU6050驱动程序
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:http://www.ing10bbs.com
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include "mpu6050/mpu6050.h"
  19. #include "usart/bsp_debug_usart.h"
  20. #include "i2c/bsp_i2c.h"
  21. /* 私有类型定义 --------------------------------------------------------------*/
  22. /* 私有宏定义 ----------------------------------------------------------------*/
  23. /* 私有变量 ------------------------------------------------------------------*/
  24. /* 扩展变量 ------------------------------------------------------------------*/
  25. /* 私有函数原形 --------------------------------------------------------------*/
  26. /* 函数体 --------------------------------------------------------------------*/

  27. /**
  28.   * 函数功能: 写数据到MPU6050寄存器
  29.   * 输入参数: 无
  30.   * 返 回 值: 无
  31.   * 说    明: 无
  32.   */
  33. void MPU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat)
  34. {
  35.         I2C_Start();
  36.         I2C_SendByte(MPU6050_SLAVE_ADDRESS);
  37.         I2C_WaitAck();
  38.         I2C_SendByte(reg_add);
  39.         I2C_WaitAck();
  40.         I2C_SendByte(reg_dat);
  41.         I2C_WaitAck();
  42.         I2C_Stop();
  43. }

  44. /**
  45.   * 函数功能: 从MPU6050寄存器读取数据
  46.   * 输入参数: 无
  47.   * 返 回 值: 无
  48.   * 说    明: 无
  49.   */
  50. void MPU6050_ReadData(uint8_t reg_add,unsigned char *Read,uint8_t num)
  51. {
  52.         unsigned char i;
  53.         
  54.         I2C_Start();
  55.         I2C_SendByte(MPU6050_SLAVE_ADDRESS);
  56.         I2C_WaitAck();
  57.         I2C_SendByte(reg_add);
  58.         I2C_WaitAck();
  59.         
  60.         I2C_Start();
  61.         I2C_SendByte(MPU6050_SLAVE_ADDRESS+1);
  62.         I2C_WaitAck();
  63.         
  64.         for(i=0;i<(num-1);i++){
  65.                 *Read=I2C_ReadByte(1);
  66.                 Read++;
  67.         }
  68.         *Read=I2C_ReadByte(0);
  69.         I2C_Stop();
  70. }

  71. /**
  72.   * 函数功能: 初始化MPU6050芯片
  73.   * 输入参数: 无
  74.   * 返 回 值: 无
  75.   * 说    明: 无
  76.   */
  77. void MPU6050_Init(void)
  78. {
  79.   int i=0,j=0;
  80.   //在初始化之前要延时一段时间,若没有延时,则断电后再上电数据可能会出错
  81.   for(i=0;i<1000;i++)
  82.   {
  83.     for(j=0;j<1000;j++)
  84.     {
  85.       ;
  86.     }
  87.   }
  88.         MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);            //解除休眠状态
  89.         MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);            //陀螺仪采样率,1KHz
  90.         MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);                //低通滤波器的设置,截止频率是1K,带宽是5K
  91.         MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);          //配置加速度传感器工作在2G模式,不自检
  92.         MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
  93. }

  94. /**
  95.   * 函数功能: 读取MPU6050的ID
  96.   * 输入参数: 无
  97.   * 返 回 值: 无
  98.   * 说    明: 无
  99.   */
  100. uint8_t MPU6050ReadID(void)
  101. {
  102.         unsigned char Re = 0;
  103.     MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //读器件地址
  104.         if(Re != 0x68)
  105.         {
  106.                 printf("MPU6050 dectected error!\r\n检测不到MPU6050模块,请检查模块与开发板的接线");
  107.                 return 0;
  108.         }
  109.         else
  110.         {
  111.                 printf("MPU6050 ID = %d\r\n",Re);
  112.                 return 1;
  113.         }
  114.                
  115. }

  116. /**
  117.   * 函数功能: 读取MPU6050的加速度数据
  118.   * 输入参数: 无
  119.   * 返 回 值: 无
  120.   * 说    明: 无
  121.   */
  122. void MPU6050ReadAcc(short *accData)
  123. {
  124.     uint8_t buf[6];
  125.     MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6);
  126.     accData[0] = (buf[0] << 8) | buf[1];
  127.     accData[1] = (buf[2] << 8) | buf[3];
  128.     accData[2] = (buf[4] << 8) | buf[5];
  129. }

  130. /**
  131.   * 函数功能: 读取MPU6050的角速度数据
  132.   * 输入参数: 无
  133.   * 返 回 值: 无
  134.   * 说    明: 无
  135.   */
  136. void MPU6050ReadGyro(short *gyroData)
  137. {
  138.     uint8_t buf[6];
  139.     MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
  140.     gyroData[0] = (buf[0] << 8) | buf[1];
  141.     gyroData[1] = (buf[2] << 8) | buf[3];
  142.     gyroData[2] = (buf[4] << 8) | buf[5];
  143. }

  144. /**
  145.   * 函数功能: 读取MPU6050的原始温度数据
  146.   * 输入参数: 无
  147.   * 返 回 值: 无
  148.   * 说    明: 无
  149.   */
  150. void MPU6050ReadTemp(short *tempData)
  151. {
  152.         uint8_t buf[2];
  153.     MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
  154.     *tempData = (buf[0] << 8) | buf[1];
  155. }

  156. /**
  157.   * 函数功能: 读取MPU6050的温度数据,转化成摄氏度
  158.   * 输入参数: 无
  159.   * 返 回 值: 无
  160.   * 说    明: 无
  161.   */
  162. void MPU6050_ReturnTemp(short*Temperature)
  163. {
  164.         short temp3;
  165.         uint8_t buf[2];
  166.         
  167.         MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
  168.   temp3= (buf[0] << 8) | buf[1];
  169.         *Temperature=(((double) (temp3 + 13200)) / 280)-13;
  170. }

  171. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

复制代码
串口调试助手数据.jpg

硬件I2C
CubeMX_1.jpg
CubeMX_2.jpg
mpu6050.c文件内容
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: mpu6050.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: MPU6050驱动程序
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:http://www.ing10bbs.com
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include "mpu6050/mpu6050.h"
  19. #include "usart/bsp_debug_usart.h"
  20. #include "i2c/bsp_i2c.h"
  21. /* 私有类型定义 --------------------------------------------------------------*/
  22. /* 私有宏定义 ----------------------------------------------------------------*/
  23. /* 私有变量 ------------------------------------------------------------------*/
  24. /* 扩展变量 ------------------------------------------------------------------*/
  25. /* 私有函数原形 --------------------------------------------------------------*/
  26. /* 函数体 --------------------------------------------------------------------*/

  27. /**
  28.   * 函数功能: 写数据到MPU6050寄存器
  29.   * 输入参数: 无
  30.   * 返 回 值: 无
  31.   * 说    明: 无
  32.   */
  33. void MPU6050_WriteReg(uint8_t reg_add,uint8_t reg_dat)
  34. {
  35.   I2C_MPU6050_WriteData(MPU6050_SLAVE_ADDRESS,reg_add,reg_dat);
  36. }

  37. /**
  38.   * 函数功能: 从MPU6050寄存器读取数据
  39.   * 输入参数: 无
  40.   * 返 回 值: 无
  41.   * 说    明: 无
  42.   */
  43. void MPU6050_ReadData(uint8_t reg_add,unsigned char *Read,uint8_t num)
  44. {
  45.   I2C_MPU6050_ReadBuffer(MPU6050_SLAVE_ADDRESS,reg_add,I2C_MEMADD_SIZE_8BIT,Read,num);
  46. }

  47. /**
  48.   * 函数功能: 初始化MPU6050芯片
  49.   * 输入参数: 无
  50.   * 返 回 值: 无
  51.   * 说    明: 无
  52.   */
  53. void MPU6050_Init(void)
  54. {
  55.   int i=0,j=0;
  56.   //在初始化之前要延时一段时间,若没有延时,则断电后再上电数据可能会出错
  57.   for(i=0;i<1000;i++)
  58.   {
  59.     for(j=0;j<1000;j++)
  60.     {
  61.       ;
  62.     }
  63.   }
  64.         MPU6050_WriteReg(MPU6050_RA_PWR_MGMT_1, 0x00);            //解除休眠状态
  65.         MPU6050_WriteReg(MPU6050_RA_SMPLRT_DIV , 0x07);            //陀螺仪采样率,1KHz
  66.         MPU6050_WriteReg(MPU6050_RA_CONFIG , 0x06);                //低通滤波器的设置,截止频率是1K,带宽是5K
  67.         MPU6050_WriteReg(MPU6050_RA_ACCEL_CONFIG , 0x00);          //配置加速度传感器工作在2G模式,不自检
  68.         MPU6050_WriteReg(MPU6050_RA_GYRO_CONFIG, 0x18);     //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
  69. }

  70. /**
  71.   * 函数功能: 读取MPU6050的ID
  72.   * 输入参数: 无
  73.   * 返 回 值: 无
  74.   * 说    明: 无
  75.   */
  76. uint8_t MPU6050ReadID(void)
  77. {
  78.         unsigned char Re = 0;
  79.     MPU6050_ReadData(MPU6050_RA_WHO_AM_I,&Re,1);    //读器件地址
  80.         if(Re != 0x68)
  81.         {
  82.                 printf("MPU6050 dectected error!\r\n检测不到MPU6050模块,请检查模块与开发板的接线");
  83.                 return 0;
  84.         }
  85.         else
  86.         {
  87.                 printf("MPU6050 ID = %d\r\n",Re);
  88.                 return 1;
  89.         }
  90.                
  91. }

  92. /**
  93.   * 函数功能: 读取MPU6050的加速度数据
  94.   * 输入参数: 无
  95.   * 返 回 值: 无
  96.   * 说    明: 无
  97.   */
  98. void MPU6050ReadAcc(short *accData)
  99. {
  100.     uint8_t buf[6];
  101.     MPU6050_ReadData(MPU6050_ACC_OUT, buf, 6);
  102.     accData[0] = (buf[0] << 8) | buf[1];
  103.     accData[1] = (buf[2] << 8) | buf[3];
  104.     accData[2] = (buf[4] << 8) | buf[5];
  105. }

  106. /**
  107.   * 函数功能: 读取MPU6050的角速度数据
  108.   * 输入参数: 无
  109.   * 返 回 值: 无
  110.   * 说    明: 无
  111.   */
  112. void MPU6050ReadGyro(short *gyroData)
  113. {
  114.     uint8_t buf[6];
  115.     MPU6050_ReadData(MPU6050_GYRO_OUT,buf,6);
  116.     gyroData[0] = (buf[0] << 8) | buf[1];
  117.     gyroData[1] = (buf[2] << 8) | buf[3];
  118.     gyroData[2] = (buf[4] << 8) | buf[5];
  119. }

  120. /**
  121.   * 函数功能: 读取MPU6050的原始温度数据
  122.   * 输入参数: 无
  123.   * 返 回 值: 无
  124.   * 说    明: 无
  125.   */
  126. void MPU6050ReadTemp(short *tempData)
  127. {
  128.         uint8_t buf[2];
  129.     MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
  130.     *tempData = (buf[0] << 8) | buf[1];
  131. }

  132. /**
  133.   * 函数功能: 读取MPU6050的温度数据,转化成摄氏度
  134.   * 输入参数: 无
  135.   * 返 回 值: 无
  136.   * 说    明: 无
  137.   */
  138. void MPU6050_ReturnTemp(short*Temperature)
  139. {
  140.         short temp3;
  141.         uint8_t buf[2];
  142.         
  143.         MPU6050_ReadData(MPU6050_RA_TEMP_OUT_H,buf,2);     //读取温度值
  144.   temp3= (buf[0] << 8) | buf[1];
  145.         *Temperature=(((double) (temp3 + 13200)) / 280)-13;
  146. }

  147. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

复制代码
串口调试助手数据.jpg


收藏 评论16 发布时间:2016-8-5 08:53

举报

16个回答
Glenxu 回答时间:2020-3-30 09:32:09
很多人提到STM32的IIC库函数不好用、不稳定,由于我对C的编程知识起步,
所以只能用函数做,并且也不希望自己建"PROJECT"和“INIT”,在这样的基
础下,经过反复试验,最终发现MX   HAL建立工程、初始化非常好用。
出现的问题和众多码农相同,最大的问题就是能收到地址“0X68”,所有其它数据为零不变!
最终经对比发现,程序没有问题,主要问题是IIC的初始化中不能随意增加延时,很多帖子和
MPU6050说明中提到要由足够的延时,其实这就是个坑,因为延时后6050又进入了休眠,
所以读出的值全为零。结论是该加延时的加,比该加的不要画蛇添足!
由于100K的IIC通讯速度很快,所以只在上电初始化和有复位操作后各加500mS延时,其它豆不需要,
除非你强制运行在很低的CPU时钟,否则IIC的初始化和读写没有跟不上速度的问题,不需要延时。
试验发现STM32F103和STM32F030对HAL库函数的IIC操作都很问题。
haohao663 回答时间:2019-4-23 09:04:32
ikraos 发表于 2019-4-3 22:32
楼主还有资源吗,需要.h文件呜呜呜

硬石开源资料下载链接(该帖总是最新资料)
http://www.ing10bbs.com/forum.ph ... =1458&fromuid=4
(出处: 硬石社区)
vickyineefocus 回答时间:2019-1-3 16:28:31
这是个很棒的分享,但是mpu6050.c的代码重复了,我想楼主应该是想放mpu6050.h的文件吧???
gameng 回答时间:2016-8-5 09:12:26
感谢分享!
jinzhifeng 回答时间:2016-8-5 09:29:40
学习了,,,
逍遥李 回答时间:2016-8-5 10:32:08
不错的分享啊
欧阳阳 回答时间:2019-3-24 11:51:41
请问可以发一下源代码吗? 我调试好久都没调试成功。谢谢大佬。
yindongli 回答时间:2019-3-24 16:41:27
好资料,要学习
ikraos 回答时间:2019-4-3 22:32:31
楼主还有资源吗,需要.h文件呜呜呜
zxcv1ddd 回答时间:2019-4-23 23:39:50
谢谢分享
frank171 回答时间:2019-6-24 09:17:33
好贴,谢谢分享
willy926234097 回答时间:2019-6-24 09:58:26
感谢分享!学习中
Ian-392967 回答时间:2019-6-24 18:54:35

楼主还有资源吗
heikewang1219 回答时间:2019-6-28 10:42:46
谢谢分享
12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版