OpenEdv-开源电子网

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

MPU6050读数一直是257或771

[复制链接]

1

主题

8

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-3-13
在线时间
9 小时
发表于 2020-9-1 16:57:07 | 显示全部楼层 |阅读模式
4金钱
准备自己画板做个小四轴,先用原子的探索者(STM32F4)学学各个模块,自己接了MPU6050和oled,想着把MPU6050读出来的数据显示在oled上,但是一直读出来数据都是257或者771,不然就是65565和00000。不知道有没有遇到过相同问题的朋友,知不知道怎么解决,源码放下面
#ifndef __MPU_H
#define __MPU_H


#include "sys.h"
#include "stdlib.h"       
#include "delay.h"


#define MPU_SCLK_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_4)//SCL
#define MPU_SCLK_Set() GPIO_SetBits(GPIOB,GPIO_Pin_4)


#define MPU_SDIN_Clr() GPIO_ResetBits(GPIOB,GPIO_Pin_5)//DIN
#define MPU_SDIN_Set() GPIO_SetBits(GPIOB,GPIO_Pin_5)


//****************************************
#define        SMPLRT_DIV                0x19        //陀螺仪采样率,典型值:0x07(125Hz)
#define        CONFIG                          0x1A        //低通滤波频率,典型值:0x06(5Hz)
#define        GYRO_CONFIG                0x1B        //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define        ACCEL_CONFIG        0x1C        //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define        ACCEL_XOUT_H        0x3B
#define        ACCEL_XOUT_L        0x3C
#define        ACCEL_YOUT_H        0x3D
#define        ACCEL_YOUT_L        0x3E
#define        ACCEL_ZOUT_H        0x3F
#define        ACCEL_ZOUT_L        0x40
#define        TEMP_OUT_H                0x41
#define        TEMP_OUT_L                0x42
#define        GYRO_XOUT_H                0x43
#define        GYRO_XOUT_L                0x44       
#define        GYRO_YOUT_H                0x45
#define        GYRO_YOUT_L                0x46
#define        GYRO_ZOUT_H                0x47
#define        GYRO_ZOUT_L                0x48
#define        PWR_MGMT_1                0x6B        //电源管理,典型值:0x00(正常启用)
#define        WHO_AM_I                        0x75        //IIC地址寄存器(默认数值0x68,只读)
#define        SlaveAddress        0xD0        //IIC写入时的地址字节数据,+1为读取


void MPU_Init(void);
void MPU_IN(void);
void MPU_OUT(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_SendACK(u8 ack);
u8 I2C_RecvACK(void);
u8 IIC_Wait_Ack(void);
void I2C_SendByte(u8 dat);
u8 I2C_RecvByte(u8 ack);
u8 Single_WriteI2C(u8 REG_Address,u8 REG_data);
u8 Single_ReadI2C(u8 REG_Address);
void InitMPU6050(void);
int GetData(u8 REG_Address);




#endif


#include "mpu.h"
void MPU_Init()
{
        GPIO_InitTypeDef  GPIO_InitStructure;


  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOF时钟


  //GPIOB4,B5初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化


}


void MPU_IN()
{
        GPIO_InitTypeDef  GPIO_InitStructure;


  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOF时钟


  //GPIOB4,B5初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化


}
void MPU_OUT()
{
        GPIO_InitTypeDef  GPIO_InitStructure;


  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOF时钟


  //GPIOB4,B5初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输入模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化


}
//**************************************
//I2C起始信号
//**************************************
void I2C_Start()
{
    MPU_SDIN_Set();                    //拉高数据线
    MPU_SCLK_Set();                    //拉高时钟线
    delay_us(5);                       //延时
    MPU_SDIN_Clr();                    //产生下降沿
    delay_us(5);                       //延时
    MPU_SCLK_Clr();                    //拉低时钟线
}
//**************************************
//I2C停止信号
//**************************************
void I2C_Stop()
{
          MPU_SCLK_Clr();                    //拉低时钟线
    MPU_SDIN_Clr();                    //拉低数据线
          delay_us(5);                       //延时
    MPU_SCLK_Set();                    //拉高时钟线
    MPU_SDIN_Set();                    //产生上升沿
    delay_us(5);                       //延时
}
//**************************************
//I2C发送应答信号
//入口参数:ack (0:ACK 1:NAK)
//**************************************
void I2C_SendACK(u8 ack)
{
          MPU_SCLK_Clr();                    //拉低时钟线
        if(ack)
    MPU_SDIN_Set();        //写应答信号
        else
                MPU_SDIN_Clr();
          delay_us(5);                 //延时
    MPU_SCLK_Set();                    //拉高时钟线
    delay_us(5);                 //延时
    MPU_SCLK_Clr();                    //拉低时钟线
    delay_us(5);                 //延时
}
//**************************************
//I2C接收应答信号
//**************************************
u8 I2C_RecvACK()
{
        u8 CY;
        MPU_IN();
    MPU_SCLK_Set();                    //拉高时钟线
    delay_us(5);                 //延时
    CY = PBin(5);                   //读应答信号
    MPU_SCLK_Clr();                    //拉低时钟线
    delay_us(5);                 //延时
        MPU_OUT();
    return CY;
}
//**************************************************
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
//**************************************************
u8 IIC_Wait_Ack(void)
{
        u16 ucErrTime=0;       
        MPU_SDIN_Set();delay_us(5);          
        MPU_SCLK_Set();delay_us(5);
        MPU_IN();      //SDA设置为输入
  delay_us(5);        
        while(PBin(5))
        {
                ucErrTime++;
                if(ucErrTime>2500)
                {                       
                        MPU_OUT();
                        I2C_Stop();
                        return 1;
                }
        }
        MPU_SCLK_Clr();//时钟输出0
  MPU_OUT();       
        return 0;  
}
//**************************************
//向I2C总线发送一个字节数据
//**************************************
void I2C_SendByte(u8 dat)
{
    u8 i;
          MPU_SCLK_Clr();                //拉低时钟线
    for (i=0; i<8; i++)         //8位计数器
    {
                        if(dat&0x80)
        MPU_SDIN_Set();               //送数据口
                        else
                                MPU_SDIN_Clr();
                          dat <<= 1;              //移出数据的最高位
                          delay_us(5);
        MPU_SCLK_Set();                //拉高时钟线
        delay_us(5);             //延时
        MPU_SCLK_Clr();                //拉低时钟线
        delay_us(5);             //延时
    }
//    I2C_RecvACK();
//                IIC_Wait_Ack();
}
//**************************************
//从I2C总线接收一个字节数据
//**************************************
u8 I2C_RecvByte(u8 ack)
{
    u8 i;
    u8 dat = 0;
          MPU_IN();
    for (i=0; i<8; i++)         //8位计数器
    {
                          MPU_SCLK_Clr();                //拉低时钟线
        delay_us(5);             //延时
        dat <<= 1;
        MPU_SCLK_Set();                //拉高时钟线
        delay_us(5);             //延时
                        if(PBin(5))dat++;
//        dat |= PBin(5);             //读数据               
              delay_us(5);             //延时
    }
                MPU_OUT();
                I2C_SendACK(!ack);
    return dat;
}
//**************************************
//向I2C设备写入一个字节数据
//**************************************
u8 Single_WriteI2C(u8 REG_Address,u8 REG_data)
{
    I2C_Start();                  //起始信号
    I2C_SendByte(SlaveAddress);   //发送设备地址+写信号
                if(IIC_Wait_Ack())        //等待应答
        {
//                I2C_Stop();                 
                return 1;               
        }
    I2C_SendByte(REG_Address);    //内部寄存器地址,
                IIC_Wait_Ack();
    I2C_SendByte(REG_data);       //内部寄存器数据,
                        if(IIC_Wait_Ack())        //等待应答
        {
//                I2C_Stop();                 
                return 1;               
        }
    I2C_Stop();                   //发送停止信号
        return 0;
}
//**************************************
//从I2C设备读取一个字节数据
//**************************************
u8 Single_ReadI2C(u8 REG_Address)
{
        u8 REG_data;
        I2C_Start();                   //起始信号
        I2C_SendByte(SlaveAddress);    //发送设备地址+写信号
        IIC_Wait_Ack();
        I2C_SendByte(REG_Address);     //发送存储单元地址,从0开始       
        IIC_Wait_Ack();
        I2C_Start();                   //起始信号
        I2C_SendByte(SlaveAddress+1);  //发送设备地址+读信号
        IIC_Wait_Ack();
        REG_data=I2C_RecvByte(0);       //读出寄存器数据
        I2C_Stop();                    //停止信号
        return REG_data;
}
//**************************************
//初始化MPU6050
//**************************************
void InitMPU6050()
{
        Single_WriteI2C(PWR_MGMT_1, 0x80);        //复位
  delay_ms(500);
        Single_WriteI2C(PWR_MGMT_1, 0x00);        //解除休眠状态
        Single_WriteI2C(SMPLRT_DIV, 0x07);
        Single_WriteI2C(CONFIG, 0x06);
        Single_WriteI2C(GYRO_CONFIG, 0x18);
        Single_WriteI2C(ACCEL_CONFIG, 0x01);
}
//**************************************
//合成数据
//**************************************
int GetData(u8 REG_Address)
{
        char H,L;
        H=Single_ReadI2C(REG_Address);
        L=Single_ReadI2C(REG_Address+1);
        return (H<<8)+L;   //合成数据
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-3-13
在线时间
9 小时
 楼主| 发表于 2020-9-1 16:58:03 | 显示全部楼层
又出来新的示数了,65280,就是ff00
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-3-13
在线时间
9 小时
 楼主| 发表于 2020-9-1 17:03:26 | 显示全部楼层
主函数就
int main(void)
{
        delay_init(168);
        delay_ms(1000);
        LED_Init();                                        //初始化LED
        OLED_Init();                                //初始化OLED
  MPU_Init();
        delay_ms(1000);
        InitMPU6050();  //初始化MPU6050
        delay_ms(1000);
        LED0=0;
        delay_ms(1000);
        while(1)
        {
                     OLED_ShowNum(16,16,GetData(ACCEL_XOUT_H),5,16);


                OLED_ShowChar(0,16,'X',16);
                OLED_ShowChar(0,32,'Y',16);
                OLED_ShowChar(0,48,'Z',16);
                OLED_Refresh();
        }
}



回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-3-13
在线时间
9 小时
 楼主| 发表于 2020-9-5 13:59:18 | 显示全部楼层
没人???自顶
回复

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2020-3-13
在线时间
9 小时
 楼主| 发表于 2020-9-10 10:03:09 | 显示全部楼层
不是吧这么冷清
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2021-10-29
在线时间
9 小时
发表于 2022-5-22 22:42:38 | 显示全部楼层
帮顶帮顶
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-22 16:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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