OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5274|回复: 6

为什么 mpu6050 能读出ID 但读出来的数据一直是0

[复制链接]

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
发表于 2018-11-1 15:38:48 | 显示全部楼层 |阅读模式
1金钱
#include "myiic.h"
#include "mpu6050.h"

u8 MPU_Write_Byte(u8 reg,u8 data)
{
        IIC_Start();
        IIC_Send_Byte(MPU_ADDR << 1 | WRITE_CMD);       //发送器件地址+写命令
       
        if(IIC_Wait_Ack() == False)
        {
                IIC_Stop();
                return False;
        }
       
        IIC_Send_Byte(reg);                 //写寄存器地址
        IIC_Wait_Ack();
        IIC_Send_Byte(data);                //发送数据
       
        if(IIC_Wait_Ack() == False)
        {
                IIC_Stop();
                return False;
        }
       
        IIC_Stop();
        return True;
}
//reg:寄存器地址
u8 MPU_Read_Byte(u8 reg)
{
        u8 res;
        IIC_Start();
        IIC_Send_Byte(MPU_ADDR << 1 | WRITE_CMD);
        IIC_Wait_Ack();
        IIC_Send_Byte(reg);
        IIC_Wait_Ack();
        IIC_Start();
        IIC_Send_Byte(MPU_ADDR << 1 | READ_CMD);
        IIC_Wait_Ack();
        res = IIC_Read_Byte(0);             //读取数据,发送nACK
        IIC_Stop();
        return res;
}
//reg:寄存器地址
u8 MPU_Write_Len(u8 addr ,u8 reg,u8 len, u8 *buf)
{
        u8 i;
        IIC_Start();
        IIC_Send_Byte((addr << 1) | WRITE_CMD);
        if(IIC_Wait_Ack() == False)
        {
                IIC_Stop();
                return False;
        }
        IIC_Send_Byte(reg);
        IIC_Wait_Ack();
       
        for(i = 0; i < len; i++)
        {
                IIC_Send_Byte(buf[i]);
                if(IIC_Wait_Ack() == False)
                {
                        IIC_Stop();
                        return False;
                }
        }
                IIC_Stop();
                return True;
}



u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
{
        IIC_Start();
        IIC_Send_Byte((addr<<1)|0);//发送器件地址+写命令       
        if(IIC_Wait_Ack() == False)        //等待应答
        {
                IIC_Stop();       
        printf("false\r\n");               
                return False;               
        }
    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
        printf(" buf = %d\r\n",*buf);               
                len--;
                buf++;
        }   
    IIC_Stop();        //产生一个停止条件
        return True;       
}
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
        u8 buf[6];
        u8 res;
        res = MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
        if(res == True)
        {
                *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轴的原始读数(带符号)
u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
        u8 buf[6];
        u8 res;
        res= MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
       
        if(res == True)
        {
                *ax = ((u16)buf[0] << 8) | buf[1];
                *ay = ((u16)buf[2] << 8) | buf[3];
                *az = ((u16)buf[4] << 8) | buf[5];
        }
       
        return res;
}

//得到温度值
//返回值:温度值(扩大了100倍)

short MPU_Get_temprature(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;       
}
//设置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 = 10000 / (rate - 1);
        data = MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);
        return MPU_Set_LPF(rate / 2);
       
}

u8 MPU_Init(void)
{
        u8 res;
        IICPort_Init();
        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);    //主IIC模式关闭
        MPU_Write_Byte(MPU_FIFO_EN_REG,0x00);      //关闭FIFO
        MPU_Write_Byte(MPU_INTBP_CFG_REG,0x80);    //INF引脚低电平有效
        res = MPU_Read_Byte(MPU_DEVICE_ID_REG);
        printf("ID = %X\r\n",res);
        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);
       
        }       
        else
        {
                return False;
        }
   return         True;
}



#include "stm32f10x.h"
#include "mpu6050.h"
#include "myiic.h"

int main(void)
{
          short aacx,aacy,aacz;
          short gyrox,gyroy,gyroz;
          float pitch,roll,yaw;
          u8 res;
          u8 id;
          u8 i = 1;
          delay_init();
      uart_init(115200);
          IICPort_Init();
          MPU_Init();
      while(1)
          {                  
                  if(i)
                  {
                 res = MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);
                 printf("res = %d\r\n",res);
                 printf("gyrox= %d,gyroy = %d,gyroz = %d",gyrox,gyroy,gyroz);          
                          i--;
                  }

          }                  
}



QQ截图20181101153718.png

最佳答案

查看完整内容[请看2#楼]

问题解决 了 因为 我就读一次 mpu的值 后面改成 连续读mpu6050 就行
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2018-11-1 15:38:49 | 显示全部楼层
问题解决 了  因为 我就读一次 mpu的值  后面改成 连续读mpu6050 就行
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10553
金钱
10553
注册时间
2017-2-18
在线时间
1910 小时
发表于 2018-11-1 21:12:41 | 显示全部楼层
有原子的板子可以测试不?
回复

使用道具 举报

9

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2018-7-15
在线时间
27 小时
发表于 2019-1-2 12:24:00 来自手机 | 显示全部楼层
我也是这种情况,怎么改?
回复

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2019-5-16
在线时间
11 小时
发表于 2019-5-17 09:58:45 | 显示全部楼层
怎么改成连续读的呢?可以分享下代码么?
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-5-18 21:25:34 | 显示全部楼层
z445210021 发表于 2019-5-17 09:58
怎么改成连续读的呢?可以分享下代码么?

连续 就是放在while里面
回复

使用道具 举报

6

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2018-10-13
在线时间
40 小时
 楼主| 发表于 2019-5-18 21:25:55 | 显示全部楼层
罗涛 发表于 2019-5-18 21:25
连续 就是放在while里面

你有什么问题  
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-1-31 20:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表