在使用MPU6050时遇到的令人头疼的问题

1.整个程序在一开始运行就卡死在启动文件


首先看一下,Target设置选项下的Use MicroLIB选项是不是选上勾了。
如果这个设置也解决不了问题,那么你需要检查一下程序里,是否写了printf函数的接口函数。因为MPU6050里面有
用到了这个函数,如果你没写这个函数的接口函数,就会导致系统卡死在系统文件里。
printf函数的接口函数

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口 */USART_SendData(DEBUG_USARTx, (uint8_t) ch);/* 等待发送完毕 */while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);      return (ch);
}

2.while循环里的条件明明不满足了,程序却一致卡死在此循环里

检查一下,判断条件里的变量的类型是否正确。另外,如果这个变量在中断服务函数里面需要改变值,那么在定义这个变量的语句前应该加上关键字
volatile
volatile的具体描述参考

3.MPU6050在执行mpu_dmp_init()函数时,一直出现错误,且错误在run_self_test()

1)首先,看一下是不是因为你在程序初始化的时候,没有把MPU6050水平放置,至于为什么要水平放置呢?
因为在run_self_test()函数里面有一个mpu_run_self_test(gyro, accel)函数,这个函数上面有一个注释特别重要:

This function must be called with the device either face-up or face-down*  (z-axis is parallel to gravity).此函数必须在设备面朝上或面朝下时调用(z轴与重力平行)

2)如果照着1)的方法还是解决不了这个问题,那么请你检查一下run_self_test函数里面的具体内容是否和下面的一模一样:

//MPU6050自测试
//返回值:0,正常
//    其他,失败
u8 run_self_test(void)
{int result;//char test_packet[4] = {0};long gyro[3], accel[3]; result = mpu_run_self_test(gyro, accel);if (result == 0x3) //这个地方要的别注意,有的例程会把0X3错误的写为0X7{/* Test passed. We can trust the gyro data here, so let's push it down* to the DMP.*/float sens;unsigned short accel_sens;mpu_get_gyro_sens(&sens);gyro[0] = (long)(gyro[0] * sens);gyro[1] = (long)(gyro[1] * sens);gyro[2] = (long)(gyro[2] * sens);dmp_set_gyro_bias(gyro);mpu_get_accel_sens(&accel_sens);accel[0] *= accel_sens;accel[1] *= accel_sens;accel[2] *= accel_sens;dmp_set_accel_bias(accel);return 0;}else return 1;
}

4.mpu_dmp_get_data(&pitch,&roll,&yaw)函数的返回值不正确(一直不是0)

MPU6050读不出来数据
如果参考以上这篇文章还是无法帮助解决问题,那么不妨试一下,把模拟iic的这部分代码换一下,也许可能就是因为iic这部分程序不正确。
模拟IIC的代码:

#include "mpuiic.h"
#include "./systick/bsp_SysTick.h"
#define Soft_I2C_SDA          GPIO_Pin_3
#define Soft_I2C_SCL          GPIO_Pin_4
#define Soft_I2C_PORT     GPIOB
#define MPU6050_GPIO_CLK  RCC_APB2Periph_GPIOB
//IO方向设置  ---PB11
#define MPU_SDA_IN()  {Soft_I2C_PORT ->CRL &= 0XFFFF0FFF;Soft_I2C_PORT ->CRL |= 8<<12;}       //上拉/下拉 输入模式
#define MPU_SDA_OUT() {Soft_I2C_PORT ->CRL &= 0XFFFF0FFF;Soft_I2C_PORT ->CRL |= 7<<12;}       //开漏输出  输出模式/* 定义读写SCL和SDA的宏,已增加代码的可移植性和可阅读性 */
#if 1   /* 条件编译: 1 选择GPIO的库函数实现IO读写 */#define MPU6050_I2C_SCL_1()  GPIO_SetBits(Soft_I2C_PORT, Soft_I2C_SCL)     /* SCL = 1 */#define MPU6050_I2C_SCL_0()  GPIO_ResetBits(Soft_I2C_PORT, Soft_I2C_SCL)      /* SCL = 0 */#define MPU6050_I2C_SDA_1()  GPIO_SetBits(Soft_I2C_PORT, Soft_I2C_SDA)        /* SDA = 1 */#define MPU6050_I2C_SDA_0()  GPIO_ResetBits(Soft_I2C_PORT, Soft_I2C_SDA)      /* SDA = 0 */#define MPU6050_I2C_SDA_READ()  GPIO_ReadInputDataBit(Soft_I2C_PORT, Soft_I2C_SDA)    /* 读SDA口线状态 */
#else   /* 这个分支选择直接寄存器操作实现IO读写 *//* 注意:如下写法,在IAR最高级别优化时,会被编译器错误优化 */#define MPU6050_I2C_SCL_1()  Soft_I2C_PORT->BSRR = Soft_I2C_SCL                /* SCL = 1 */#define MPU6050_I2C_SCL_0()  Soft_I2C_PORT->BRR = Soft_I2C_SCL                /* SCL = 0 */#define MPU6050_I2C_SDA_1()  Soft_I2C_PORT->BSRR = Soft_I2C_SDA               /* SDA = 1 */#define MPU6050_I2C_SDA_0()  Soft_I2C_PORT->BRR = Soft_I2C_SDA                /* SDA = 0 */#define MPU6050_I2C_SDA_READ()  ((Soft_I2C_PORT->IDR & Soft_I2C_SDA) != 0)    /* 读SDA口线状态 */
#endif/**********************************************
函数名称:MPU_IIC_Delay
函数功能:MPU IIC延时函数,延时2ms
函数参数:无
函数返回值:无
**********************************************/
void MPU_IIC_Delay(void)
{uint8_t i;/* 下面的时间是通过逻辑分析仪测试得到的。工作条件:CPU主频72MHz ,MDK编译环境,1级优化循环次数为10时,SCL频率 = 205KHz 循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us 循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us */for (i = 0; i < 100; i++);
}/**********************************************
函数名称:MPU_IIC_Init
函数功能:MPU IIC初始化
函数参数:无
函数返回值:无
**********************************************/
void MPU_IIC_Init(void)
{                        GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd(MPU6050_GPIO_CLK|RCC_APB2Periph_AFIO,ENABLE);          //先使能外设IO PORTB时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);   GPIO_InitStructure.GPIO_Pin = Soft_I2C_SCL|Soft_I2C_SDA;     //端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;                 //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                //IO口速度为50MHzGPIO_Init(Soft_I2C_PORT , &GPIO_InitStructure);                                      //根据设定参数初始化GPIO GPIO_SetBits(Soft_I2C_PORT,Soft_I2C_SCL|Soft_I2C_SDA);                        //PB10,PB11 输出高   }//产生IIC起始信号
void MPU_IIC_Start(void)
{MPU_SDA_OUT();      //sda线输出MPU6050_I2C_SDA_1();         MPU6050_I2C_SCL_1();MPU_IIC_Delay();MPU6050_I2C_SDA_0();//START:when CLK is high,DATA change form high to low MPU_IIC_Delay();MPU6050_I2C_SCL_0();//钳住I2C总线,准备发送或接收数据
}
//产生IIC停止信号
void MPU_IIC_Stop(void)
{MPU_SDA_OUT();//sda线输出MPU6050_I2C_SCL_0();MPU6050_I2C_SDA_0();//STOP:when CLK is high DATA change form low to highMPU_IIC_Delay();MPU6050_I2C_SCL_1();  MPU6050_I2C_SDA_1();//发送I2C总线结束信号MPU_IIC_Delay();
}
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 MPU_IIC_Wait_Ack(void)
{u8 ucErrTime=0;MPU_SDA_IN();      //SDA设置为输入  MPU6050_I2C_SDA_1();MPU_IIC_Delay();       MPU6050_I2C_SCL_1();MPU_IIC_Delay();  while(MPU6050_I2C_SDA_READ()){ucErrTime++;if(ucErrTime>250){MPU_IIC_Stop();return 1;}}MPU6050_I2C_SCL_0();//时钟输出0        return 0;
}
//产生ACK应答
void MPU_IIC_Ack(void)
{MPU6050_I2C_SCL_0();MPU_SDA_OUT();MPU6050_I2C_SDA_0();MPU_IIC_Delay();MPU6050_I2C_SCL_1();MPU_IIC_Delay();MPU6050_I2C_SCL_0();
}
//不产生ACK应答
void MPU_IIC_NAck(void)
{MPU6050_I2C_SCL_0();MPU_SDA_OUT();MPU6050_I2C_SDA_1();MPU_IIC_Delay();MPU6050_I2C_SCL_1();MPU_IIC_Delay();MPU6050_I2C_SCL_0();
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void MPU_IIC_Send_Byte(u8 _ucByte)
{                        uint8_t i;MPU_SDA_OUT(); MPU6050_I2C_SCL_0();//拉低时钟开始数据传输/* 先发送字节的高位bit7 */for (i = 0; i < 8; i++){      if (_ucByte & 0x80){MPU6050_I2C_SDA_1();}else{MPU6050_I2C_SDA_0();}_ucByte <<= 1;    /* 左移一个bit */MPU6050_I2C_SCL_1();MPU_IIC_Delay();   MPU6050_I2C_SCL_0();MPU_IIC_Delay();}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 MPU_IIC_Read_Byte(unsigned char ack)
{unsigned char i,receive=0;MPU_SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){MPU6050_I2C_SCL_0(); MPU_IIC_Delay();MPU6050_I2C_SCL_1();receive<<=1;if(MPU6050_I2C_SDA_READ())receive++;   MPU_IIC_Delay(); }                   if (!ack)MPU_IIC_NAck();//发送nACKelseMPU_IIC_Ack(); //发送ACK   return receive;
}

5.读取的数据成功率低(也就是说读取10次,mpu_dmp_get_data有5次都返回1,而不是0)

1.可能是 MPU_IIC_Delay()这个函数取值不恰当,可以调整一下看看效果。
2.读取MPU6050数据卡死的总结

6.容易忽视的小问题,却恰恰最致命

例如:

STM32的PB3、PB4,分别是JTAG的JTDO和NJTRST引脚,在没关闭JTAG功能之前,在程序中是配置不了这些引脚的功能的。要配置这些引脚,首先要开启AFIO时钟,然后在AFIO的设置中,释放这些引脚。具体看STM32的参考手册中有关AFIO的部分。

RCC_APB2PeriphClockCmd(MPU6050_GPIO_CLK|RCC_APB2Periph_AFIO,ENABLE);         //先使能外设IO PORTB时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
/******************************************************************#define GPIO_Remap_SWJ_NoJTRST      ((uint32_t)0x00300100)  < Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST
#define GPIO_Remap_SWJ_JTAGDisable  ((uint32_t)0x00300200) < JTAG-DP Disabled and SW-DP Enabled
#define GPIO_Remap_SWJ_Disable      ((uint32_t)0x00300400) !< Full SWJ Disabled (JTAG-DP + SW-DP)
******************************************************************/

STM32——GPIO重映射(GPIO_PinRemapConfig)

基于STM32单片机模块练习——在使用MPU6050时遇到的令人头疼的问题相关推荐

  1. 基于STM32单片机模块练习——OLED模块

    基于STM32单片机模块练习--OLED模块 相关知识点 向OLED写一个字节 /*** @brief I2C_WriteByte,向OLED寄存器地址写一个byte的数据* @param addr: ...

  2. 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)

    本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...

  3. 最简单DIY基于STM32单片机的WIFI智能小车设计方案

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 第三篇:最简单DIY基于STM32F ...

  4. 基于STM32单片机的步数测量系统(免费开源)

    基于STM32单片机的步数测量系统 1.1设计要求 1.2设计所需器材 1.3 设计原理 1.4核心代码 1.5结果展示 1.6资源链接 1.7硬件电路图 1.1设计要求 设计一款基于STM32的步数 ...

  5. 基于STM32单片机智能RFID刷卡汽车位锁设计(论文

    基于STM32单片机智能RFID刷卡汽车位锁设计(论文) 摘要 在车位日益紧张的今天,如何避免私家车位被他人抢占,是令人头痛的事.日前面市的一种新型车位锁,不仅有效解决了这一问题,还可对车辆起到防盗作 ...

  6. 最简单DIY基于STM32单片机的蓝牙智能小车设计方案

    STM32库函数开发系列文章目录 第一篇:STM32F103ZET6单片机双串口互发程序设计与实现 第二篇:最简单DIY基于STM32单片机的蓝牙智能小车设计方案 文章目录 STM32库函数开发系列文 ...

  7. 基于STM32单片机的密码锁(Proteus仿真+程序+报告)

    3-基于STM32单片机的密码锁 功能描述如下: 由STM32F103单片机最小系统+ 4*4矩阵键盘+LCD1602液晶显示+蜂鸣器+继电器模块: 1.采用STM32F103为主控芯片. 2.通过4 ...

  8. B40 - 基于STM32单片机的电热蚊香蓝牙控制系统

    任务 本项目进行智能电热蚊香器系统的设计与开发,将STM32开发板作为一个微控制器,结合蓝牙技术,通过手机APP软件对电热蚊香器进行灵活的控制,使电热蚊香器的功能更加人性化,更加符合当代人们对家用电器 ...

  9. 9、★♥★基于STM32单片机的颜色检测仪设计♥☆

    9.★♥★基于STM32单片机的颜色检测仪设计♥☆ 文章目录 9.★♥★基于STM32单片机的颜色检测仪设计♥☆ 引言 1.系统概述 1.1.设计任务 1.2.设计要求 2.方案设计与论证 2.1.芯 ...

最新文章

  1. ap java内容_AP 计算机知识点总结
  2. java--面向接口编程
  3. influxdb 客户端工具_性能工具之Jmeter小白入门系列之六
  4. [css] 简述你对BFC规范的理解
  5. java 路径获取文件名称_java 根据文件获取文件名及路径的方法
  6. 支付宝「集五福」的阳谋
  7. 阿里二面:怎么解决MySQL死锁问题的?
  8. 打不开baidu晓得、百科等可是其他网页正常的解决方法
  9. 提交注册信息到数据库中
  10. 机器人周志_机器人制造基础学习日志
  11. 职场 软件实施工程师的地位以及发展前景
  12. 华中科技大学计算机考研信息汇总
  13. usb网卡带宽测试软件,腾达AC9与网件R6220无线性能和USB速度测试
  14. 磨刀不误砍柴工,掌握DEVC++的一些实用技巧
  15. 《JavaScript百炼成仙》 全书知识点整理
  16. 免费影视资源如何引流?如何通过分享影视资源引流
  17. 手工去除酷我音乐盒广告
  18. C51——简单的防盗报警器
  19. 记录自己学习尚硅谷javaweb2022版中遇到的一些问题
  20. 使用Go+WebSocket练习总结

热门文章

  1. 漫画:什么是 “锦标赛排序” ?
  2. iphone13和iphone14有什么区别,一图一秒看懂
  3. 在微信公众号发文件?
  4. 西风与服务器协议失败,西风vpm服务器地址
  5. Linux编码及dos2unix,unix2dos命令
  6. 预见2020|第二届中国区块链产业经济年会在国际金融博物馆召开
  7. SmartClient框架组件介绍
  8. hellxman最新突破36O的启动思路
  9. springboot 故障注入_MSHA x Chaos 容灾高可用实践
  10. spring整合JDBC 实现拦截器用户的登录和注册的案例源代码及解析