目录
MPU6050简介:
6轴传感器,可测量X,Y,Z三轴的加速度和角速度。
3轴加速度计(Acce):测量X,Y,Z轴的加速度
3轴陀螺仪传感器(Gyro):测量X,Y,Z轴的角速度。
VCC、GND:电源
SCL、SDA:I2C通信引脚(MPU6050作从机)
XCL、XDA:主机I2C通信引脚(MPU6050作主机)
AD0:从机地址最低位
INT:中断信号输出
代码:
软件I2C读写MPU6050:
MyI2C.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
void MyI2C_W_SCL(uint8_t BitValue)//SCL引脚连接PB10,写PB10的电平
{
GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);
Delay_us(10);
}
void MyI2C_W_SDA(uint8_t BitValue)//SDA引脚连接PB11,写PB11的电平
{
GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);
Delay_us(10);
}
uint8_t MyI2C_R_SDA(void)//读SDA
{
uint8_t BitValue;
BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
Delay_us(10);
return BitValue;
}
void MyI2C_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;//GPIO初始化
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);//PB10,PB11都置高电平
}
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));
//取最高位,次高位,第三位。。。将一个字节一位一位地放到SDA上。
MyI2C_W_SCL(1);
MyI2C_W_SCL(0);
}
}
uint8_t MyI2C_ReceiveByte(void)//接收一个字节
{
uint8_t i, Byte = 0x00;
MyI2C_W_SDA(1);
for (i = 0; i < 8; i ++)
{
MyI2C_W_SCL(1);
if (MyI2C_R_SDA())
{
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_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" // Device header
#include "MyI2C.h"
#include "MPU6050_Reg.h"
#define MPU6050_ADDRESS 0xD0 //
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data)
{//指定地址写寄存器 (写一个字节)
MyI2C_Start(); //开始时序
MyI2C_SendByte(MPU6050_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(MPU6050_ADDRESS);
MyI2C_ReceiveAck();
MyI2C_SendByte(RegAddress);
MyI2C_ReceiveAck();
MyI2C_Start();
MyI2C_SendByte(MPU6050_ADDRESS | 0x01);
//将1101 0000或0000 0001,将读写位变成1(读)
MyI2C_ReceiveAck();
Data = MyI2C_ReceiveByte();//将从机发送的字节引出
MyI2C_SendAck(1);//不给从机应答
MyI2C_Stop();
return Data;
}
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);
}
uint8_t MPU6050_ReadID(void)//获取ID号
{
return MPU6050_ReadReg(MPU6050_WHO_AM_I);
}
void MPU6050_ReadData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ)
{//获取数据(6个int16_t的数据)
*AccX = (MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H) << 8)
| MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
*AccY = (MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H) << 8)
| MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
*AccZ = (MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H) << 8)
| MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
*GyroX = (MPU6050_ReadReg(MPU6050_GYRO_XOUT_H) << 8)
| MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
*GyroY = (MPU6050_ReadReg(MPU6050_GYRO_YOUT_H) << 8)
| MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
*GyroZ = (MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H) << 8)
| MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
}
MPU6050.h
#ifndef __MPU6050_H
#define __MPU6050_H
void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddress);
void MPU6050_Init(void);
uint8_t MPU6050_ReadID(void);
void MPU6050_ReadData(int16_t *AccX, int16_t *AccY, int16_t *AccZ,
int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ);
#endif
MPU6050_Reg.h
#ifndef __MPU6050_REG_H
#define __MPU6050_REG_H
#define MPU6050_SMPLRT_DIV 0x19
#define MPU6050_CONFIG 0x1A
#define MPU6050_GYRO_CONFIG 0x1B
#define MPU6050_ACCEL_CONFIG 0x1C
#define MPU6050_ACCEL_XOUT_H 0x3B
#define MPU6050_ACCEL_XOUT_L 0x3C
#define MPU6050_ACCEL_YOUT_H 0x3D
#define MPU6050_ACCEL_YOUT_L 0x3E
#define MPU6050_ACCEL_ZOUT_H 0x3F
#define MPU6050_ACCEL_ZOUT_L 0x40
#define MPU6050_TEMP_OUT_H 0x41
#define MPU6050_TEMP_OUT_L 0x42
#define MPU6050_GYRO_XOUT_H 0x43
#define MPU6050_GYRO_XOUT_L 0x44
#define MPU6050_GYRO_YOUT_H 0x45
#define MPU6050_GYRO_YOUT_L 0x46
#define MPU6050_GYRO_ZOUT_H 0x47
#define MPU6050_GYRO_ZOUT_L 0x48
#define MPU6050_PWR_MGMT_1 0x6B //电源管理
#define MPU6050_PWR_MGMT_2 0x6C //电源管理
#define MPU6050_WHO_AM_I 0x75 //ID寄存器(默认数值0x68,只读)
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MPU6050.h"
#include "Serial.h"
uint8_t ID;
int16_t AX, AY, AZ, GX, GY, GZ;
int main(void)
{
OLED_Init();
MPU6050_Init();
Serial_Init();
OLED_ShowString(1, 1, "ID:");
ID = MPU6050_ReadID();
OLED_ShowHexNum(1, 4, ID, 2);
Serial_SendByte(0x41);
while (1)
{
MPU6050_ReadData(&AX, &AY, &AZ, &GX, &GY, &GZ);
OLED_ShowSignedNum(2, 1, AX, 5);
OLED_ShowSignedNum(3, 1, AY, 5);
OLED_ShowSignedNum(4, 1, AZ, 5);
OLED_ShowSignedNum(2, 9, GX, 5);
OLED_ShowSignedNum(3, 9, GY, 5);
OLED_ShowSignedNum(4, 9, GZ, 5);
Serial_SendByte(AX);
Serial_SendByte(AY);
Serial_SendByte(AZ);
Serial_SendByte(GX);
Serial_SendByte(GY);
Serial_SendByte(GZ);
Serial_SendString("11111111111111111111");
Delay_ms(5000);
}
}