STM32中iic驱动mpu6050例程

一、mpu6050寄存器相关知识
1.本机地址
可在寄存器使用手册查找
STM32中iic驱动mpu6050例程_第1张图片
mpu6050在iic中是七位地址,Bit6~Bit1是他的前六位地址,默认是110100,末位由AD0引脚的值确定,并不是该寄存器的Bit0位。
若AD0引脚置0,则mpu6050的本机地址是1101000,十六进制为0x68。

2.复位mpu6050
需要配置的是0x6B寄存器的Bit7位。
STM32中iic驱动mpu6050例程_第2张图片
设置为1时,该位​​会将所有内部寄存器重置为其默认值。复位完成后,该位自动清除为0。需要延时100ms。

3.时钟源配置
需要配置的是0x6B寄存器的Bit2~Bit0位。
STM32中iic驱动mpu6050例程_第3张图片
STM32中iic驱动mpu6050例程_第4张图片

上电时,时钟源默认为内部振荡器。手册中建议将设备配置为使用陀螺仪之一(或外部时钟)作为时钟参考,可以提高稳定性。也就是1~5任选。

4.设置MPU6050工作模式
需要配置的是0x6B寄存器的Bit6位。
STM32中iic驱动mpu6050例程_第5张图片
SLEEP设置为1为睡眠模式,设置为0为工作模式。

5.设置输出三轴陀螺仪和三轴加速度数据
需要配置的是0x6C寄存器的Bit6~Bit0位。
STM32中iic驱动mpu6050例程_第6张图片
设置为1时,加速度计和陀螺仪置于待机模式。置0时,加速度计和陀螺仪置于开启状态。

6.禁止中断
需要配置的是0x38寄存器的Bit0位。
STM32中iic驱动mpu6050例程_第7张图片
置1开启中断模式,置0关闭中断模式。

7.设置采样频率
需要配置的是0x38寄存器。
STM32中iic驱动mpu6050例程_第8张图片
采样率=陀螺仪输出率/(1 + SMPLRT_DIV)

9.关闭辅助IIC模块
需要配置的是0x6A寄存器的Bit5位。
STM32中iic驱动mpu6050例程_第9张图片
当I2C_MST_EN设置为1时,将启用IIC主模式;当该位清除时为0时,辅助IIC总线线路(AUX_DA和AUX_CL)由主IIC总线逻辑驱动(SDA和SCL)。

10.启动旁路多路复用器
需要配置的是0x37寄存器的Bit1位。
STM32中iic驱动mpu6050例程_第10张图片
当I2C_BYPASS_EN等于1并且I2C_MST_EN(0x6A寄存器)等于0时,主机应用处理器将能够直接访问MPU-60X0的辅助I2C总线。 当该位等于0时,不管I2C_MST_EN的状态如何,主机应用处理器将无法直接访问MPU-60X0的辅助I2C总线。

11.配置陀螺仪的满量程范围
需要配置的是0x1B寄存器的Bit4~Bit3位。
STM32中iic驱动mpu6050例程_第11张图片
STM32中iic驱动mpu6050例程_第12张图片
有四个量程可供选择。

12.配置加速度计的满量程范围
需要配置的是0x1C寄存器的Bit4~Bit3位。
STM32中iic驱动mpu6050例程_第13张图片
STM32中iic驱动mpu6050例程_第14张图片
有四个量程可供选择。

8.加速度计数据寄存器
STM32中iic驱动mpu6050例程_第15张图片
这里需要注意的是他的数据格式
STM32中iic驱动mpu6050例程_第16张图片
翻译过来就是:存储格式是16位二进制的补码值,小于32768的数都是正数,大于32768的数都是负数,假设十进制读数为40000,则他的读出的数是40000-65536=(-25536)。也就是读数的范围为[-32768,32767)。
接下来,MPU6050并不会以 g 单位输出,我们需要在读完后进行转换。先来看看各个量程对应的灵敏度。
STM32中iic驱动mpu6050例程_第17张图片
不同的量程范围对应着不同的灵敏度。以量程为±2g为例,假设补码转换后的数据是1000,从上表中得知在±2g下的灵敏度为16384LSB/g,得出的加速度值应该为1000÷16384=0.061g。

9.陀螺仪数据寄存器
数据存储格式和加速度计一样,都是16位2的补码值,也有对应的灵敏度转换。
STM32中iic驱动mpu6050例程_第18张图片
STM32中iic驱动mpu6050例程_第19张图片
STM32中iic驱动mpu6050例程_第20张图片
二、代码实现;
mpu6050.c代码

#include "mpu6050.h"

uint8_t buffer[14];

void MPU6050_setClockSource(uint8_t source){
    MPU_IICwriteBits(0x68, 0x6B, 2, 3, source);
}

void MPU6050_setFullScaleGyroRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x1B, 4, 2, range);
}

void MPU6050_setFullScaleAccelRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x1C, 4, 2, range);
}


void MPU6050_resetEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x6B, 7, enabled);
	Delay_ms(100);
}


void MPU6050_set_Gyro_Accel_outRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x6C, 5, 6, range);
}

void MPU6050_set_SMPRT_DIV(uint8_t range) {
	  MPU_IICwriteByte(0x68,0x19,range);
}

void MPU6050_set_Gyro_DLPF_outRange(uint8_t range) {
    MPU_IICwriteBits(0x68, 0x1A, 2, 3, range);
}


void MPU6050_INT_Disabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x38, 0, enabled);
}


void MPU6050_setSleepEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x6B, 6, enabled);
}


void MPU6050_testConnection(void) {
	
   while(buffer[0] != 0x68){
			MPU_IICreadBytes(0x68, 0x75, 1, buffer);
	 };  
}

void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x6A, 5, enabled);
}

void MPU6050_setI2CBypassEnabled(uint8_t enabled) {
    MPU_IICwriteBit(0x68, 0x37, 1, enabled);
}


void MPU6050_initialize(void) {
	MPU_IIC_Init();             //IIC初始化
	MPU6050_testConnection();     //检测MPU6050 是否已经连接
	MPU6050_resetEnabled(1);   //复位mpu6050  需延时100ms
    MPU6050_setClockSource(2); //设置时钟
	MPU6050_set_Gyro_Accel_outRange(0);  // 设置输出三轴陀螺仪和三轴加速度数据
	MPU6050_INT_Disabled(0);    //禁止中断
	MPU6050_set_SMPRT_DIV(0);   //采样分频
    MPU6050_setFullScaleGyroRange(3);//陀螺仪最大量程 +-1000度每秒
    MPU6050_setFullScaleAccelRange(0);	//加速度度最大量程 +-2G
  	MPU6050_set_Gyro_DLPF_outRange(2);  //设置陀螺仪和加速度计的低通滤波器
    MPU6050_setSleepEnabled(0); //进入工作状态
	MPU6050_setI2CMasterModeEnabled(0);	 //不让MPU6050 控制AUXI2C
	MPU6050_setI2CBypassEnabled(1);	 //主控制器的I2C与	MPU6050的AUXI2C	直通。控制器可以直接访问HMC5883L
}

测试代码

float Accel_Y,Gyro_Y;
Gyro_Y=(MPU_I2C_ReadOneByte(0x68,0x45)<<8)+MPU_I2C_ReadOneByte(0x68,0x46);
if(Gyro_Y>32767)  Gyro_Y-=65536;  
Gyro_Y=Gyro_Y/16.4; 
		
Accel_Y=(MPU_I2C_ReadOneByte(0x68,0x3D)<<8)+MPU_I2C_ReadOneByte(0x68,0x3E);
if(Accel_Y>32767) Accel_Y-=65536;
Accel_Y=Accel_Y/16384;

printf("Gyro_Y : %f    Accel_Y  : %f \n",Gyro_Y, Accel_Y);

运行效果
STM32中iic驱动mpu6050例程_第21张图片

你可能感兴趣的:(stm32,stm32,单片机,嵌入式)