一、实物图(型号:MPU6050

二、原理图

编号 名称 功能
1 VCC 电源正
2 GND 电源地
3 SCL 串行时钟输入
4 SDA 串行地址和数据输入/输出
5 XDA 外部从设备串行地址和数据输入/输出
6 XCL 外部从设备串行时钟输入
7 AD0 IIC地址控制引脚(接GND,地址为0X68,接VCC,地址为0X69)
8 INT 中断引脚

三、简介

MPU6050是一个6轴运动处理传感器。它集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),可用外部IIC接口连接一个第三方的数字传感器,比如磁力计,扩展之后就可以输出一个9轴信号。

MPU6050对陀螺仪和加速度计分别用了三个16位ADC,将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的。

陀螺仪的可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。

四、内部框图

其中,SCL 和 SDA 是连接 MCU 的 IIC 接口,MCU 通过这个 IIC 接口来控制 MPU6050, 另外还有一个 IIC 接口:AUX_CL 和 AUX_DA,这个接口可用来连接外部从设备,比如磁 传感器,这样就可以组成一个九轴传感器。VLOGIC 是 IO 口电压,该引脚最低可以到 1.8V, 我们一般直接接 VDD 即可。AD0 是从 IIC 接口(接 MCU)的地址控制引脚,该引脚控制 IIC 地址的最低位。如果接 GND,则 MPU6050 的 IIC 地址是:0X68,如果接 VDD,则是

0X69,注意:这里的地址是不包含数据传输的最低位的(最低位用来表示读写)

五、通信协议(I2C通信)

1、I2C总线介绍

<1>I2C总线(Inter IC bus)是由Philips公司开发的一种通用数据总线。

<2>两根通信线:SCL(Serial Clock串行时钟线)、SDA(Serial Data串行数据线)。

<3>同步、半双工,带数据应答。

*注:同步(因为它有单独的时钟线)、半双工(SDA只有一根线,并且还要来回通信)

<4>通用的I2C总线,可以使各种设备的通信标准统一,对于厂家来说,使用成熟的方案可以缩短芯片设计周期、提高稳定性,对于应用者来说,使用通用的通信协议可以避免学习各种各样的自定义协议,降低了学习和应用的难度。

2、I2C电路规范

<1>所有I2C设备的SCL连在一起,SDA连在一起

<2>设备的SCL和SDA均要配置成开漏输出模式(硬件IIC)

*开漏输出模式——断开时引脚成浮空状态(电路断开,电压不稳定)

<3>SCL和SDA各添加一个上拉电阻,阻值一般为4.7K~10K左右

<4>开漏输出和上拉电阻的共同作用实现了“线与”的功能,此设计主要是为了解决多机通信互相干扰的问题。

3、时序结构

起始信号:SCL高电平期间,SDA从高电平切换到低电平

停止信号:SCL高电平期间,SDA从低电平切换到高电平

代码如下:

/****

*******I2C总线启动信号

*****/

void MPU6050_IIC_Start(void)

{

   MPU6050_SDA = 1;

   MPU6050_SCL = 1;

   MPU6050_IIC_Delay(DELAY_TIME);

   MPU6050_SDA = 0;

   MPU6050_IIC_Delay(DELAY_TIME);

   MPU6050_SCL = 0;

}

 

/****

*******I2C总线停止信号

*****/

void MPU6050_IIC_Stop(void)

{

   MPU6050_SDA = 0;

   MPU6050_SCL = 1;

   MPU6050_IIC_Delay(DELAY_TIME);

   MPU6050_SDA = 1;

   MPU6050_IIC_Delay(DELAY_TIME);

}

发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。

接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)。

代码如下:

/****

*******发送应答或非应答信号

*****/

void MPU6050_IIC_SendAck(bit ackbit)

{

   MPU6050_SCL = 0;

   MPU6050_SDA = ackbit;

   MPU6050_IIC_Delay(DELAY_TIME);

   MPU6050_SCL = 1;

   MPU6050_IIC_Delay(DELAY_TIME);

   MPU6050_SCL = 0;

   MPU6050_SDA = 1;

   MPU6050_IIC_Delay(DELAY_TIME);

}

 

/****

*******等待应答信号

*****/

bit MPU6050_IIC_WaitAck(void)

{

   bit ackbit;

   MPU6050_SDA = 1;

   MPU6050_SCL = 1;

   MPU6050_IIC_Delay(DELAY_TIME);

   ackbit = MPU6050_SDA;

   MPU6050_SCL = 0;

   MPU6050_IIC_Delay(DELAY_TIME);

   return ackbit;

}

发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节。

代码如下:

/****

*******I2C总线发送一个字节数据

*****/

void MPU6050_IIC_SendByte(uchar byte)

{

   uchar i;

   MPU6050_SCL = 0;

   for(i=0; i<8; i++)

   {

      if(byte & 0x80)

      MPU6050_SDA = 1;

      else

      MPU6050_SDA = 0;

      MPU6050_IIC_Delay(DELAY_TIME);

      MPU6050_SCL = 1;

      MPU6050_IIC_Delay(DELAY_TIME);

      MPU6050_SCL = 0;

      MPU6050_IIC_Delay(DELAY_TIME);

      byte <<= 1;

   }

   MPU6050_IIC_WaitAck();

}

接收一个字节:SCL低电平期间,从机将数据位依次放到SDA总线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)

代码如下:

/****

*******I2C总线接收一个字节数据

*****/

uchar MPU6050_IIC_RecByte(bit ackbit)

{

   uchar i, dat;

   MPU6050_SDA = 1;

   for(i=0; i<8; i++)

   {

      MPU6050_SCL = 1;

      MPU6050_IIC_Delay(DELAY_TIME);

      dat <<= 1;

      if(MPU6050_SDA)

      dat |= 1;

      MPU6050_SCL = 0;

      MPU6050_IIC_Delay(DELAY_TIME);

   }

   MPU6050_IIC_SendAck(ackbit);

   return dat;

}

4、MPU6050数据帧

字节写:在“字地址”处写入“数据”

代码如下:

/****

*******向MPU6050的地址address中写入一个字节的数据

*****/

void MPU6050_Write_Data(uchar address,uchar dat)

{

   MPU6050_IIC_Start();

   MPU6050_IIC_SendByte(MPU6050_SlaveAddress);

   MPU6050_IIC_SendByte(address);

   MPU6050_IIC_SendByte(dat);

   MPU6050_IIC_Stop();

}

随机读:读出在“字地址”处的“数据”

代码如下:

/****

*******从MPU6050的地址address中读取一个字节的数据

*****/

uchar MPU6050_Read_Data(uchar address)

{

   uchar dat;

   MPU6050_IIC_Start();

   MPU6050_IIC_SendByte(MPU6050_SlaveAddress);

   MPU6050_IIC_SendByte(address);

   MPU6050_IIC_Start();

   MPU6050_IIC_SendByte(MPU6050_SlaveAddress + 1);

   dat = MPU6050_IIC_RecByte(MPU6050_ACK);

   MPU6050_IIC_Stop();

   return(dat);

}

六、流程设计

首先初始化引脚,然后发送起始位,再发送从机设备地址写,接下来发送命令地址,重新发送一次起始位,再发送从机设备地址读,然后先读取高字节数据,再读取低字节数据,将读取的高字节数据和低字节数据整合为一个数据进行返回。

发表评论

后才能评论