赞
踩
控制寄存器用于配置硬件电路
状态寄存器可以读取电路的信息
SR2
时钟控制寄存器用于配置时钟信号
根据主机发送和主机接收的时序图重写 MPU6050_WriteReg()
和MPU6050_ReadReg()
I2C的配置结构体意义见注释
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
void I2C_GenerateSTART(I2C_TypeDef I2Cx, FunctionalState NewState);*
void I2C_GenerateSTOP(I2C_TypeDef I2Cx, FunctionalState NewState);*
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
void I2C_SendData(I2C_TypeDef I2Cx, uint8_t Data);*
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
ErrorStatus I2C_CheckEvent(I2C_TypeDef I2Cx, uint32_t I2C_EVENT)*
FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
#include "stm32f10x.h" #include "delay.h" #include "OLED.h" #include "MPU6050.h" uint8_t ID; int main(void) { OLED_Init(); MPU6050_Init(); OLED_ShowString(1, 1, "ID:"); ID = MPU6050_GetID(); OLED_ShowHexNum(1, 4, ID, 2); MPU6050_DataTypeDef MPU6050_DataStructure; while(1) { // 读取数据 MPU6050_GetData(&MPU6050_DataStructure); // 显示数据 OLED_ShowSignedNum(2, 1, MPU6050_DataStructure.AccX, 5); OLED_ShowSignedNum(3, 1, MPU6050_DataStructure.AccY, 5); OLED_ShowSignedNum(4, 1, MPU6050_DataStructure.AccZ, 5); OLED_ShowSignedNum(2, 8, MPU6050_DataStructure.GyroX, 5); OLED_ShowSignedNum(3, 8, MPU6050_DataStructure.GyroY, 5); OLED_ShowSignedNum(4, 8, MPU6050_DataStructure.GyroZ, 5); } }
#include "stm32f10x.h" #include "MPU6050_SEG.h" #define MPU_ADDRESS 0xD0 /* * 等待事件 带超时退出机制 * 将while与I2C_CheckEvent封装在一起 */ void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) { uint32_t Timeout=50000; while(Timeout && (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS)) { Timeout --; } } /* * 往指定地址写入指定数据 */ void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data) { // 起始条件 I2C_GenerateSTART(I2C2, ENABLE); // 等待 EV5 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); // 呼叫设备(MPU6050) I2C_Send7bitAddress(I2C2, MPU_ADDRESS, I2C_Direction_Transmitter); // 等待 EV6 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 寻找写入地址 I2C_SendData(I2C2, RegAddress); // 等待EV8 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING); // 写入数据 I2C_SendData(I2C2, Data); // 等待EV8_2 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); // 终止条件 I2C_GenerateSTOP(I2C2, ENABLE); } /* * 从指定地址读取数据 */ uint8_t MPU6050_ReadReg(uint8_t RegAddress) { uint8_t Data; // 起始条件 I2C_GenerateSTART(I2C2, ENABLE); // 起始条件 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); // 等待 EV5 I2C_Send7bitAddress(I2C2, MPU_ADDRESS, I2C_Direction_Transmitter); //呼叫设备 写 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); // 等待 EV6 I2C_SendData(I2C2, RegAddress); // 寻找读取地址 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); // 等待EV8_2 I2C_GenerateSTART(I2C2, ENABLE); // 再次产生起始条件 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); // 等待 EV5 I2C_Send7bitAddress(I2C2, MPU_ADDRESS, I2C_Direction_Receiver); // 呼叫设备 读 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); // 等待 EV6 I2C_AcknowledgeConfig(I2C2, DISABLE); // 关闭应答 I2C_GenerateSTOP(I2C2, ENABLE); // 终止条件 MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED); // 等待EV7 Data = I2C_ReceiveData(I2C2); // 接收数据 I2C_AcknowledgeConfig(I2C2, ENABLE); // 开启应答 return Data; } /* * 配置MPU6050 */ void MPU6050_Init(void) { // I2C初始化 RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_OD; // 复用开漏 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // I2C I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Ack=I2C_Ack_Enable; // 有应答 I2C_InitStructure.I2C_ClockSpeed=50000; // 400 kHz以下 100 kHz以上为快速通讯 I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2; // 低电平比高电平2:1 仅在快速通讯生效 I2C_InitStructure.I2C_Mode=I2C_Mode_I2C; I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit; // 从模式下 stm32作为从机的地址所占位数 I2C_InitStructure.I2C_OwnAddress1=0x00; // 从模式下stm32作为从机的地址 I2C_Init(I2C2, &I2C_InitStructure); // 开启I2C2 I2C_Cmd(I2C2, ENABLE); MPU6050_WriteReg(PWR_MGMT_1, 0x01); MPU6050_WriteReg(PWR_MGMT_2, 0x00); MPU6050_WriteReg(SMPLRT_DIV, 0x09); MPU6050_WriteReg(CONFIG, 0x06); MPU6050_WriteReg(GYRO_CONFIG, 0x18); MPU6050_WriteReg(ACCEL_CONFIG, 0x18); } /* * 获取ID号 */ uint8_t MPU6050_GetID(void) { return MPU6050_ReadReg(WHO_AM_I); } /* * 获取MPU6050数据 */ void MPU6050_GetData(MPU6050_DataTypeDef * MPU_DataStructure) { uint16_t Data_H, Data_L; // 高位数据和低位数据 Data_H = MPU6050_ReadReg(ACCEL_XOUT_H); Data_L = MPU6050_ReadReg(ACCEL_XOUT_L); MPU_DataStructure->AccX=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(ACCEL_YOUT_H); Data_L = MPU6050_ReadReg(ACCEL_YOUT_L); MPU_DataStructure->AccY=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(ACCEL_ZOUT_H); Data_L = MPU6050_ReadReg(ACCEL_ZOUT_L); MPU_DataStructure->AccZ=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(GYRO_XOUT_H); Data_L = MPU6050_ReadReg(GYRO_XOUT_L); MPU_DataStructure->GyroX=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(GYRO_YOUT_H); Data_L = MPU6050_ReadReg(GYRO_YOUT_L); MPU_DataStructure->GyroY=(Data_H<<8) | Data_L; Data_H = MPU6050_ReadReg(GYRO_ZOUT_H); Data_L = MPU6050_ReadReg(GYRO_ZOUT_L); MPU_DataStructure->GyroZ=(Data_H<<8) | Data_L; }
#ifndef __MPU6050_H
#define __MPU6050_H
#include "MPU6050_REG.h"
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_Init(void);
uint8_t MPU6050_GetID(void);
void MPU6050_GetData(MPU6050_DataTypeDef * MPU_DataStructure);
#endif
#ifndef __MPU6050_REG_H #define __MPU6050_REG_H // 寄存器地址 #define SMPLRT_DIV 0x19 #define CONFIG 0x1A #define GYRO_CONFIG 0x1B #define ACCEL_CONFIG 0x1C #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 #define PWR_MGMT_2 0x6C #define WHO_AM_I 0x75 /* * MPU6050数据结构体 */ typedef struct { int16_t AccX; int16_t AccY; int16_t AccZ; int16_t GyroX; int16_t GyroY; int16_t GyroZ; } MPU6050_DataTypeDef; #endif
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。