STM32 软件I2C读写MPU6050

ops/2025/2/12 8:45:20/

接线图

代码配置

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

1.配置初始化函数

//MyI2C初始化函数
void MyI2C_Init(void)
{//配置GPIOGPIO_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置高电平
}

功能函数

//写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时序基本单元

//起始条件
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配置

#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);}

头文件

#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		0x75void 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

主函数

#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);}}


http://www.ppmy.cn/ops/157135.html

相关文章

mac下生成.icns图标

笔记原因&#xff1a; 今日需要在mac下开发涉及图标文件的使用及icons文件的生成&#xff0c;所以记录一下。 网络上都是一堆命令行需要打印太麻烦了&#xff0c;写一个一键脚本。 步骤一 将需要生成的png格式文件重命名为“pic.png” mv xxxx.png pic.png 步骤二 下载我…

实在RPA案例|视源股份:驱动20+核心场景数字化升级,组织效能提升超80%

广州视源电子科技股份有限公司&#xff08;以下简称 “视源股份”&#xff0c;股票代码&#xff1a;002841.SZ&#xff09;是广东省大型上市企业&#xff0c;旗下产品常年占据全国份额第一&#xff0c;成功孵出 “液晶电视主控板卡、希沃&#xff08;seewo&#xff09;教育交互…

Vue的Diff算法与React的Diff算法有何不同?

Vue 的 Diff 算法与 React 的 Diff 算法的区别 在前端开发中,Diff 算法是虚拟 DOM 的核心,负责比较新旧虚拟 DOM 的差异,以便高效地更新真实 DOM。虽然 Vue 和 React 都使用虚拟 DOM 技术,但它们的 Diff 算法在实现和策略上有显著的不同。本文将详细探讨这两者的主要区别。…

通过STM32实现外设控制应用案例

1.GPIO控制LED闪烁 功能描述:使用STM32的GPIO引脚控制LED的亮灭,实现LED的闪烁效果。 代码示例(基于HAL库): #include “main.h”#include “stm32f4xx_hal.h” void SystemClock_Config(void);static void MX_GPIO_Init(void); int main(void){HAL_Init(); SystemClock_…

【Android】Android开发应用如何开启任务栏消息通知

Android开发应用如何开启任务栏消息通知 1. 获取通知权限2.编写通知工具类3. 进行任务栏消息通知 1. 获取通知权限 在 AndroidManifest.xml 里加上权限配置&#xff0c;如下。 <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android…

保姆级教程Docker部署KRaft模式的Kafka官方镜像

目录 一、安装Docker及可视化工具 二、单节点部署 1、创建挂载目录 2、运行Kafka容器 3、Compose运行Kafka容器 4、查看Kafka运行状态 三、集群部署 四、部署可视化工具 1、创建挂载目录 2、运行Kafka-ui容器 3、Compose运行Kafka-ui容器 4、查看Kafka-ui运行状态 …

集合类不安全问题

ArrayList不是线程安全类&#xff0c;在多线程同时写的情况下&#xff0c;会抛出java.util.ConcurrentModificationException异常 解决办法&#xff1a; 1.使用Vector&#xff08;ArrayList所有方法加synchronized&#xff0c;太重&#xff09; 2.使用Collections.synchronized…

python学opencv|读取图像(五十八)使用cv2.erode()函数实现图像腐蚀处理

【1】引言 前序学习过程中&#xff0c;已经掌握了对图像的阈值处理、按位叠加、滤波操作等技巧&#xff0c;相关文章链接包括且不限于&#xff1a; python学opencv|读取图像&#xff08;五十&#xff09;使用addWeighted()函数实现图像加权叠加效果-CSDN博客 python学opencv…