软件I2C读写MPU6050

本文为个人学习笔记,不喜勿喷。

学习目标:在熟知I2C通信协议的基础上,以MPU6050为例子,学习使用I2C通信协议实现获取外部设备的信息。

主要内容即通过I2C的读、写获取MPU6050寄存器的各个参数。

通过下图的时序,先进行写操作,写操作时,从机是得知道指定寄存器的,而读寄存器却不需要,利用这个特点,先假装要写,骗从机指向要写入的寄存器,寄存器已锁定,下次进行读操作时,会从当前寄存器往下读取。

首先访问MPU6050的地址,再访问MPU6050的寄存器地址,这样指针就指向该地址,下次执行读寄存器操作时,可以直接读该寄存器的值。相当于你可以指定到哪个寄存器里写数据,但当你读数据时,你发送第一个地址时,从机知道了你想要读数据,便会从指针指定的寄存器读给你。

写入寄存器的代码

相当于为读操作铺路

void MPU6050_WriteReg(uint8_t RegAddress,uint8_t Data )
{
    MyIC2_Start();
    MyIC2_SendByte(MPU6050_Address);
    MyIC2_ReceiveAck();
    MyIC2_SendByte(RegAddress);
    MyIC2_ReceiveAck();
    MyIC2_SendByte(Data);
    MyIC2_ReceiveAck();
    MyIC2_Stop();
}

读寄存器的代码

uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
    uint8_t Data;
    MyIC2_Start();
    MyIC2_SendByte(MPU6050_Address);
    MyIC2_ReceiveAck();
    MyIC2_SendByte(RegAddress);
    MyIC2_ReceiveAck();
    
    //重复起始
    MyIC2_Start();
    //读指令
    MyIC2_SendByte(MPU6050_Address | 0X01);
    MyIC2_ReceiveAck();
    Data=MyIC2_ReceiveByte();
    //练习:读多个字节
    MyIC2_SendAck(1);
    MyIC2_Stop();
    return Data;
}

MPU6050的寄存器配置

自己翻文档,巴拉巴拉

void MPU6050_Init(void)
{
    MyIC2_Init();
    //电源管理寄存器1
    MPU6050_WriteReg(MPU6050_PWR_MGMT_1,0X01);
    //电源管理寄存器2
    MPU6050_WriteReg(MPU6050_PWR_MGMT_2,0X00);
    //采样率分频寄存器
    MPU6050_WriteReg(MPU6050_SMPLRT_DIV,0X09);
    //配置寄存器
    MPU6050_WriteReg(MPU6050_CONFIG,0X06);
    //陀螺仪配置寄存器
    MPU6050_WriteReg(MPU6050_GYRO_CONFIG,0x18);
    //加速度计配置寄存器
    MPU6050_WriteReg(MPU6050_ACCEL_CONFIG,0X18);
}

//主要知识,C语言一次只能返回一个值,使用指针能返回多个值
void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
                       int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
    uint8_t DataH,DataL;
    //加速度寄存器X轴的高八位
    DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
    //加速度寄存器X的低八位
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
    *AccX = (DataH << 8) | DataL;
    
    //加速度寄存器Y轴的高八位
    DataH=MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
    //加速度寄存器Y的低八位
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
    *AccY = (DataH << 8) | DataL;
    
    //加速度寄存器Z轴的高八位
    DataH=MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
    //加速度寄存器Z的低八位
    DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
    *AccZ = (DataH << 8) | DataL;
    
    //陀螺仪寄存器X轴的高八位
    DataH=MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
    //陀螺仪寄存器X的低八位
    DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
    *GyroX = (DataH << 8) | DataL;
    
    //陀螺仪寄存器Y轴的高八位
    DataH=MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
    //陀螺仪寄存器Y的低八位
    DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
    *GyroY = (DataH << 8) | DataL;
    
    //陀螺仪寄存器Z轴的高八位
    DataH=MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
    //陀螺仪寄存器Z的低八位
    DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
    *GyroZ = (DataH << 8) | DataL;
    
}

另外一个写法

void MPU6050_ReadRegs(uint8_t RegAddress,uint8_t *pData,uint16_t Size)
{
    MyIC2_Start();
    MyIC2_SendByte(MPU6050_Address);
    MyIC2_ReceiveAck();
    MyIC2_SendByte(RegAddress);
    MyIC2_ReceiveAck();
    MyIC2_Start();
    MyIC2_SendByte(MPU6050_Address | 0x01);
    MyIC2_ReceiveAck();
    
    while(Size--)
    {
        *pData++ = MyIC2_ReceiveByte();
        if(Size != 0)
        {
            MyIC2_SendAck(0);
        }
        else{
            MyIC2_SendAck(1);
        }
    }
    MyIC2_Stop();
}

void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
                       int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
    uint8_t buf[14];
    MPU6050_ReadRegs(MPU6050_ACCEL_XOUT_H,buf,14);
    *AccX = (buf[0] << 8) + buf[1];
    *AccY = (buf[2] << 8) + buf[3];
    *AccZ = (buf[4] << 8) + buf[5];
    *GyroX = (buf[6] << 8) + buf[7];
    *GyroY = (buf[8] << 8) + buf[9];
    *GyroZ = (buf[10] << 8) + buf[11];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值