软件I2C读写MPU6050
程序架构

主要程序
main.c
#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);
}
}
MyI2C.c
#include "stm32f10x.h"
#include "Delay.h"
#define I2CPORT GPIOB
#define I2CSCL_PIN GPIO_Pin_10
#define I2CSDA_PIN GPIO_Pin_11
void MyI2C_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=I2CSCL_PIN|I2CSDA_PIN;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(I2CPORT, I2CSCL_PIN|I2CSDA_PIN);
}
void MyI2C_W_SCL(uint8_t BitValue)
{
GPIO_WriteBit(I2CPORT, I2CSCL_PIN, (BitAction) BitValue);
Delay_us(10);
}
void MyI2C_W_SDA(uint8_t BitValue)
{
GPIO_WriteBit(I2CPORT, I2CSDA_PIN, (BitAction) BitValue);\
Delay_us(10);
}
uint8_t MyI2C_R_SDA(void)
{
uint8_t BitValue;
BitValue = GPIO_ReadInputDataBit(I2CPORT, I2CSDA_PIN);
Delay_us(10);
return BitValue;
}
void MyI2C_Start(void)
{
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
MyI2C_W_SDA(0);
MyI2C_W_SCL(0);
}
void MyI2C_Stop(void)
{
MyI2C_W_SDA(0);
MyI2C_W_SCL(1);
MyI2C_W_SDA(1);
}
void MyI2C_SendByte(uint8_t Byte)
{
uint8_t i;
for(i=0; i<8; ++i)
{
MyI2C_W_SDA(Byte & (0x80 >> i));
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
}
uint8_t MyI2C_ReceiveByte(void)
{
uint8_t Byte = 0x00;
uint8_t i;
MyI2C_W_SDA(1);
for(i=0; i<8; ++i)
{
MyI2C_W_SCL(1);
if(MyI2C_R_SDA() == 1)
Byte |= (0x80 >> i);
MyI2C_W_SCL(0);
}
return Byte;
}
void MyI2C_SendAck(uint8_t AckBit)
{
MyI2C_W_SDA(AckBit);
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
uint8_t MyI2C_ReceiveACK(void)
{
uint8_t AckBit;
MyI2C_W_SDA(1);
MyI2C_W_SCL(1);
AckBit = MyI2C_R_SDA();
MyI2C_W_SCL(0);
return AckBit;
}
MyI2C.h
#ifndef __MYI2C_H
#define __MYI2C_H
void MyI2C_Init(void);
void MyI2C_W_SCL(uint8_t BitValue);
void MyI2C_W_SDA(uint8_t BitValue);
uint8_t MyI2C_R_SDA(void);
void MyI2C_Start(void);
void MyI2C_Stop(void);
void MyI2C_SendByte(uint8_t Byte);
uint8_t MyI2C_ReceiveByte(void);
void MyI2C_SendAck(uint8_t AckBit);
uint8_t MyI2C_ReceiveACK(void);
#endif
MPU6050.c
#include "stm32f10x.h"
#include "MyI2C.h"
#include "MPU6050_REG.h"
#define MPU_ADDRESS 0xD0
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{
MyI2C_Start();
MyI2C_SendByte(MPU_ADDRESS);
MyI2C_ReceiveACK();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveACK();
MyI2C_SendByte(Data);
MyI2C_ReceiveACK();
MyI2C_Stop();
}
uint8_t MPU6050_ReadReg(uint8_t RegAddress)
{
uint8_t Data;
MyI2C_Start();
MyI2C_SendByte(MPU_ADDRESS);
MyI2C_ReceiveACK();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveACK();
MyI2C_Start();
MyI2C_SendByte(MPU_ADDRESS | 0x01);
MyI2C_ReceiveACK();
Data = MyI2C_ReceiveByte();
MyI2C_SendAck(1);
MyI2C_Stop();
return Data;
}
void MPU6050_Init(void)
{
MyI2C_Init();
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);
}
uint8_t MPU6050_GetID(void)
{
return MPU6050_ReadReg(WHO_AM_I);
}
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;
}
MPU6050.h
#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
MPU6050_REG.h
#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
typedef struct
{
int16_t AccX;
int16_t AccY;
int16_t AccZ;
int16_t GyroX;
int16_t GyroY;
int16_t GyroZ;
} MPU6050_DataTypeDef;
#endif
参考资料
【STM32入门教程-2023持续更新中】