MPU6050读不到数据。。。折腾两天了!!

2019-07-20 23:31发布

这两天在弄mpu6050模块,system下的delay.c usart.c和sys.c,hardware中的myiic.c和led.c是copy的miniv3板的寄存器版本(板子是刚买的miniv3),但是mpu6050.c是cpoy的探索者开发板的mpu6050六轴开发板传感器实验。现在问题来了:
  硬件仿真发现iic、led初始化都没有问题,6050返回的ACK也能读到,但是mpu6050读不到device id(读这个的时候应该返回0X68),初始化不了,代码如下:
[mw_shl_code=c,true] #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "mpu6050.h" #include "myiic.h" #include "math.h" //#include "stdio.h"   保留,可能用到字符串打印函数 //头文件包含,需要用到I2C、6050、串口发送数据给上位机、数据处理、led灯 int main(void) { // u8 MPU6050_init_sign ;//6050复位成功标志 // u8 t; // u8 len; u16 times; short ax;           short ay; short az;           //三轴加速度的原始值 short gx; short gy; short gz;           //三轴角速率的原始值 // float pitch; // float roll; //// float yaw;      6050没有接磁力计,航向没有意义,先不用 // // float acc_X;        // float acc_Y; // float acc_Z;     // 经过解算的三轴加速度数据 // // float gyro_X;     //绕X旋转的角速度,定义为横滚角速率 // float gyro_Y;     //绕Y旋转的角速度,定义为俯仰角速率   // float gyro_Z;     //绕Z旋转的角速度,定义为偏航角速率   float temp;         //温度值 Stm32_Clock_Init(9); delay_init(72); uart_init(72,9600); LED_Init(); MPU_Init(); //初始化成功,返回0 while(1)     //!MPU6050_init_sign {    times++; if(times%10==0) LED0=!LED0; MPU_Get_Accelerometer(&ax,&ay,&az);   //采集到三轴加速度值 MPU_Get_Gyroscope(&gx,&gy,&gz);        //采集到三轴角速率值 temp=MPU_Get_Temperature()/100;       //采集到温度值 printf("当前温度值为:%f ",temp);         printf("当前加速度值为:%o ",ax); delay_ms(10);    } [/mw_shl_code] 个人觉得问题可能出在MPU的代码上,mpu6050.c的代码如下:

[mw_shl_code=c,true]#include "mpu6050.h" #include "sys.h" #include "delay.h" #include "usart.h" ////////////////////////////////////////////////////////////////////////////////// //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK STM32F407开发板 //MPU6050 驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2014/5/9 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved ////////////////////////////////////////////////////////////////////////////////// //初始化MPU6050 //返回值:0,成功 // 其他,错误代码 u8 MPU_Init(void) { u8 res; IIC_Init();//初始化IIC总线 MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80); //复位MPU6050 delay_ms(100); MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00); //唤醒MPU6050 MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps MPU_Set_Accel_Fsr(0); //加速度传感器,±2g MPU_Set_Rate(50); //设置采样率50Hz MPU_Write_Byte(MPU_INT_EN_REG,0X00); //关闭所有中断 MPU_Write_Byte(MPU_USER_CTRL_REG,0X00); //I2C主模式关闭 MPU_Write_Byte(MPU_FIFO_EN_REG,0X00); //关闭FIFO MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80); //INT引脚低电平有效 res=MPU_Read_Byte(MPU_DEVICE_ID_REG); if(res==MPU_ADDR)//器件ID正确 { MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01); //设置CLKSEL,PLL X轴为参考 MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00); //加速度与陀螺仪都工作 MPU_Set_Rate(50); //设置采样率为50Hz } else return 1; return 0; } //设置MPU6050陀螺仪传感器满量程范围 //fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps //返回值:0,设置成功 // 其他,设置失败 u8 MPU_Set_Gyro_Fsr(u8 fsr) { return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围 } //设置MPU6050加速度传感器满量程范围 //fsr:0,±2g;1,±4g;2,±8g;3,±16g //返回值:0,设置成功 // 其他,设置失败 u8 MPU_Set_Accel_Fsr(u8 fsr) { return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围 } //设置MPU6050的数字低通滤波器 //lpf:数字低通滤波频率(Hz) //返回值:0,设置成功 // 其他,设置失败 u8 MPU_Set_LPF(u16 lpf) { u8 data=0; if(lpf>=188)data=1; else if(lpf>=98)data=2; else if(lpf>=42)data=3; else if(lpf>=20)data=4; else if(lpf>=10)data=5; else data=6; return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器 } //设置MPU6050的采样率(假定Fs=1KHz) //rate:4~1000(Hz) //返回值:0,设置成功 // 其他,设置失败 u8 MPU_Set_Rate(u16 rate) { u8 data; if(rate>1000)rate=1000; if(rate<4)rate=4; data=1000/rate-1; data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data); //设置数字低通滤波器 return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半 } //得到温度值 //返回值:温度值(扩大了100倍) short MPU_Get_Temperature(void) { u8 buf[2]; short raw; float temp; MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); raw=((u16)buf[0]<<8)|buf[1]; temp=36.53+((double)raw)/340; return temp*100;; } //得到陀螺仪值(原始值) //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号) //返回值:0,成功 // 其他,错误代码 u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz) { u8 buf[6],res; res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf); if(res==0) { *gx=((u16)buf[0]<<8)|buf[1]; *gy=((u16)buf[2]<<8)|buf[3]; *gz=((u16)buf[4]<<8)|buf[5]; } return res;; } //得到加速度值(原始值) //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号) //返回值:0,成功 // 其他,错误代码 u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az) { u8 buf[6],res; res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf); if(res==0) { *ax=((u16)buf[0]<<8)|buf[1]; *ay=((u16)buf[2]<<8)|buf[3]; *az=((u16)buf[4]<<8)|buf[5]; } return res;; } //IIC连续写 //addr:器件地址 //reg:寄存器地址 //len:写入长度 //buf:数据区 //返回值:0,正常 // 其他,错误代码 u8 MPU_Write_Len(u8 addr,u8 reg,u8 len,u8 *buf) { u8 i; IIC_Start(); IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答 { IIC_Stop(); return 1; } IIC_Send_Byte(reg); //写寄存器地址 IIC_Wait_Ack(); //等待应答 for(i=0;i<len;i++) { IIC_Send_Byte(buf); //发送数据 if(IIC_Wait_Ack()) //等待ACK { IIC_Stop(); return 1; } } IIC_Stop(); return 0; } //IIC连续读 //addr:器件地址 //reg:要读取的寄存器地址 //len:要读取的长度 //buf:读取到的数据存储区 //返回值:0,正常 // 其他,错误代码 u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf) { IIC_Start(); IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答 { IIC_Stop(); return 1; } IIC_Send_Byte(reg); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Start(); IIC_Send_Byte((addr<<1)|1);//发送器件地址+读命令 IIC_Wait_Ack(); //等待应答 while(len) { if(len==1)*buf=IIC_Read_Byte(0);//读数据,发送nACK else *buf=IIC_Read_Byte(1); //读数据,发送ACK len--; buf++; } IIC_Stop(); //产生一个停止条件 return 0; } //IIC写一个字节 //reg:寄存器地址 //data:数据 //返回值:0,正常 // 其他,错误代码 u8 MPU_Write_Byte(u8 reg,u8 data) { IIC_Start(); IIC_Send_Byte((MPU_ADDR<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答 { IIC_Stop(); return 1; } IIC_Send_Byte(reg); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(data);//发送数据 if(IIC_Wait_Ack()) //等待ACK { IIC_Stop(); return 1; } IIC_Stop(); return 0; } //IIC读一个字节 //reg:寄存器地址 //返回值:读到的数据 u8 MPU_Read_Byte(u8 reg) { u8 res; IIC_Start(); IIC_Send_Byte(0xD0);//发送器件地址+写命令,写的时候器件地址为D0 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(reg); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Start(); IIC_Send_Byte(0xD1);//发送器件地址+读命令 读的时候器件地址为D1 IIC_Wait_Ack(); //等待应答 res=IIC_Read_Byte(0);//读取数据,发送nACK IIC_Stop(); //产生一个停止条件 return res; } [/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
38条回答
阿拓
1楼-- · 2019-07-21 00:10
问题解决了,初始化I2C总线后必须延时个几百毫秒再初始化6050,不然6050初始化不成功
wzmin
2楼-- · 2019-07-21 02:17
回复【19楼】洛奇1994:
---------------------------------
解决了,还是杜邦线惹的鬼,杜邦线最好是一整排的(包括VCC  GND  SCL   SDA),之前我的线都是散的,拿了一排整的之后就好了。太坑了
登云钓月
3楼-- · 2019-07-21 05:26
 精彩回答 2  元偷偷看……
阿拓
4楼-- · 2019-07-21 10:44
回复【2楼】登云钓月:
---------------------------------

器件地址应该不会错的,因为ack有应答
正点原子
5楼-- · 2019-07-21 14:26
貌似和你接线有问题。
用杜邦线连接MPU6050模块,容易出现读到的ID是0X6D(貌似是这个)的情况,缩短杜邦线,或者模块直接插板子,就不存在这个问题。
阿拓
6楼-- · 2019-07-21 16:25
回复【4楼】正点原子:
---------------------------------
谢谢原子哥指点,我用jtag仿真,读到的地址一直是0X00。更奇怪的是我把6050的杜邦线拔了,还是能读到ack。。。不懂了

一周热门 更多>