学习-I2C-MPU6050

tips:随手记一些写程序时遇到的小问题,主要内容看纸质笔记。

目标:将MPU6050挂载到I2C上实现控制。

一、I2C模块

1.硬件电路

        为了避免总线没协调好,导致电源短路,I2C禁止所有设备输出强上拉的高电平。因此使用外置弱上拉电阻(通常4.7K)加开漏输出结构(指SCL、SDA)也正是因为通信线高电平驱动能力比较弱,导致由上升沿耗时比较长,限制了I2C的最大通信速度。

2.软件时序

        六个模块:起始、终止、发送一个字节、接收一个字节、发送应答、接收应答。

需要注意的地方:

(1)发送一个字节:SCL低时,主机将数据位依次放到SDA上,高位先行。释放SCL,从机在SCL高时读数据位,此时SDA不允许变。放一位读一位。控制权都在主机,从机只能被动读取。

(2)接收一个字节:SCL低时,从机将数据为依次放到SDA上,高位先行。释放SCL,主机在SCL高时读数据位,此时SDA不允许变。放一位读一位。主机在接收前,需要释放SDA,此时控制权在从机

(3)接收应答:接收前要释放SDA

3.程序实现

(1)发送一个字节/发送应答:

强制转换类型BitAction

GPIO_WriteBit(GPIOB, MyI2C_SDA, (BitAction)(Byte & (0x80>>i)));

(2)取某位/写某位

写程序的时候站的是主机视角,GPIO口的配置、输入输出都是以主机的态度写。

if(GPIO_ReadInputDataBit(GPIOB, MyI2C_SDA) == 1)    //Input
{
	Byte |= (0x80 >> i);        //接收一位,用或写
}
/////////
GPIO_WriteBit(GPIOB, MyI2C_SDA, (BitAction)(Byte & (0x80>>i)));    //写一位,用与

 二、MPU6050模块

1.初始化

(1)首先另存一个文件MPU6050_Reg.h用来放各种功能的寄存器以及对应的地址

//采样率分频寄存器
#define MPU6050_SMPLRT_DIV 			0x19
//配置寄存器,是否平滑滤波
#define MPU6050_CONFIG 				0x1A 
//陀螺仪配置寄存器,前面三位是自测使能
#define MPU6050_GYRO_CONFIG 		0x1B 
//加速度计配置寄存器,前面三位是自测使能
#define MPU6050_ACCEL_CONFIG 		0x1C 
//配置电源管理寄存器
#define MPU6050_PWR_MGMT_1 			0x6B 
#define MPU6050_PWR_MGMT_2 			0x6C 
//加速度计
#define MPU6050_ACCEL_XOUT_H 		0x3B 
#define MPU6050_ACCEL_XOUT_L 		0x3C 
//轴
#define MPU6050_GYRO_XOUT_H 		0x43
#define MPU6050_GYRO_XOUT_L 		0x44

(2)编写读寄存器和写寄存器MPU6050_WriteReg()和MPU6050_ReadReg()

        使用MyI2C时序。流程都是:起始 -> 发送MPU6050地址 -> 接收应答 -> 发寄存器地址 ->接收应答 -> (发数据 -> 接收应答 -> 终止)(起始 -> MPU6050地址最低位置1后发送字节 -> 接收应答 -> 接收字节 -> 发送应答 -> 终止)

        划线处因为此时总线控制权交到从机手中,而程序是主机视角,所以是接收。

(3)用写好的读写寄存器函数进行配置

#define MPU6050_ADDRESS	0xD0
void MPU6050_Init(void)
{
   MyI2C_Init();
   //基础配置,配置好以后,获取到的数据存在对应寄存器里
   //配置电源管理寄存器
   MPU6050_WriteReg(MPU6050_PWR_MGMT_1, 0x01);
   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);
}

(4)读取存在寄存器里的数据 

void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
						int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{
   uint16_t DataH, DataL;
   DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
   DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
   *AccX = (DataH<<8) | DataL;
    //......剩下的复制粘贴复制粘贴贴贴贴
}

        用MPU6050_Reg.h里define好的代号读数据。MPU6050里分高低位存储,需要分别读出来,然后高位左移八位或上低位,得到完整的数据。 

        有多个需要返回的数据,可以用指针分别传递,也可以写一个结构体传送,或者定义一个数组传送。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值