STM32 软件I2C读写MPU6050

接线图

代码配置

软件I2C只需要用GPIO的读写函数就行,在软件I2C初始化需要把SCL和SDA都初始化为开漏输出模式,还需要把SCL和SDA置高电平

1.配置初始化函数

cs 复制代码
//MyI2C初始化函数
void MyI2C_Init(void)
{
	//配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIO B族时钟
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//配置为开漏输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10;//配置引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速率
	
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB, GPIO_Pin_11 | GPIO_Pin_10);//将GPIO置高电平
}

功能函数

cs 复制代码
//写SCL函数
void MyI2C_W_SCL(uint8_t BitValue)
{
	
	GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)BitValue);
	Delay_us(10);
}
//写SDA函数
void MyI2C_W_SDA(uint8_t BitValue)
{
	
	GPIO_WriteBit(GPIOB, GPIO_Pin_11, (BitAction)BitValue);
	Delay_us(10);
}
//读SDA函数
uint8_t MyI2C_R_SDA(void)
{
	uint8_t BitValue;
	BitValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11);
	return BitValue;
}

配置I2C时序基本单元

cs 复制代码
//起始条件
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)
{
	//MyI2C_W_SDA(Byte & 0x80);//取出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 i, Byte = 0x00;
	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;
}

MPU6050配置

cs 复制代码
#include "MPU6050.h"

//指定地址写时序
void MPU6050_WriteReg(uint8_t RegAddRess, uint8_t Data)
{
	MyI2C_Start();
	MyI2C_SendByte(0xD0);
	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(0xD0);
	MyI2C_ReceiveACK();
	MyI2C_SendByte(RegAddRess);
	MyI2C_ReceiveACK();
	
	MyI2C_Start();
	MyI2C_SendByte(0xD0 | 0x01);
	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);
}

void MPU6050_GetData(int16_t* AccX, int16_t* AccY, int16_t* AccZ,
											int16_t* GyroX, int16_t* GyroY, int16_t* GyroZ)
{
	uint8_t Data_H, Data_L;
	Data_H = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H);
	Data_L = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L);
	*AccX = (Data_H << 8) | Data_L;
	
	Data_H = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H);
	Data_L = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L);
	*AccY = (Data_H << 8) | Data_L;
	
	Data_H = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H);
	Data_L = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L);
	*AccZ = (Data_H << 8) | Data_L;
	
	Data_H = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H);
	Data_L = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L);
	*GyroX = (Data_H << 8) | Data_L;
	
	Data_H = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H);
	Data_L = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L);
	*GyroY = (Data_H << 8) | Data_L;
	
	Data_H = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H);
	Data_L = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L);
	*GyroZ = (Data_H << 8) | Data_L;
}

uint8_t MPU6050_GetID(void)
{
	
	return MPU6050_ReadReg(MPU6050_WHO_AM_I);
	
}

头文件

cs 复制代码
#ifndef __MPU6050_H
#define __MPU6050_H

#include "stm32f10x.h"        
#include "MyI2C.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






void MPU6050_Init(void);
void MPU6050_WriteReg(uint8_t RegAddRess, uint8_t Data);
uint8_t MPU6050_ReadReg(uint8_t RegAddRess);
void MPU6050_GetData(int16_t* AccX, int16_t* AccY, int16_t* AccZ,
											int16_t* GyroX, int16_t* GyroY, int16_t* GyroZ);
uint8_t MPU6050_GetID(void);
#endif

主函数

cs 复制代码
#include "MyI2C.h"
#include "MPU6050.h"
int main(void)
{
	int16_t AX, AY, AZ, GX, GY, GZ;
	uint8_t ID;
	OLED_Init();
	MPU6050_Init();

	OLED_ShowString(1, 1, "ID:");
	ID = MPU6050_GetID();
	OLED_ShowHexNum(1, 4, ID, 2);
	while(1)
	{
		MPU6050_GetData(&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, 8, GX, 5);
		OLED_ShowSignedNum(3, 8, GY, 5);
		OLED_ShowSignedNum(4, 8, GZ, 5);
		
		
	}
	
	
}
相关推荐
星辰pid6 小时前
STM32控制四自由度机械臂(SG90舵机)(硬件篇)(简单易复刻)
stm32·单片机·嵌入式硬件·机械臂
威桑7 小时前
STM32 专有名词缩写整合
stm32·单片机·嵌入式硬件
星源~8 小时前
tree 命令集成到 Git Bash:可视化目录结构的指南
git·单片机·物联网·嵌入式·项目开发
SKYDROID云卓小助手9 小时前
无人设备遥控器之自动调整编码技术篇
人工智能·嵌入式硬件·算法·自动化·信号处理
所念皆星海9119 小时前
图灵完备之路(数电学习三分钟)----数据选择器与总线
嵌入式硬件·通信·数电
智者知已应修善业11 小时前
【51单片机节日彩灯控制器设计】2022-6-11
c语言·经验分享·笔记·单片机·嵌入式硬件·51单片机
开-悟11 小时前
嵌入式编程-使用AI查找BUG的启发
c语言·人工智能·嵌入式硬件·bug
Wangshanjie_9813 小时前
【STM32】-串口通讯
stm32
许白掰13 小时前
【stm32】HAL库开发——CubeMX配置RTC,单片机工作模式和看门狗
stm32·单片机·嵌入式硬件·学习·实时音视频
DIY机器人工房14 小时前
0.96寸OLED显示屏 江协科技学习笔记(36个知识点)
笔记·科技·stm32·单片机·嵌入式硬件·学习·江协科技