STM32 硬件I2C读写MPU6050

news/2025/2/12 18:16:14/

接线图

 函数介绍

生成起始条件

void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);

生成终止条件

void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

配置在收到一个字节后,是否给从机应答(配置ACK位)

void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);

发送数据,就是把Data这个数据直接写入到DR寄存器

void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);

读取DR的数据

uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

发送7位地址的专用函数

void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);

代码配置

配置硬件I2C读写初始化函数

1.定义结构体变量

//定义结构体变量
GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量
I2C_InitTypeDef  I2C_InitStructure;//定义I2C结构体变量

2.开启时钟

//开启时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);//开启I2C2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIO B族的时钟

3.配置GPIO

//配置GPIOGPIO_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);

4.初始化I2C2外设

//配置I2C2I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;							//I2C模式
I2C_InitStructure.I2C_ClockSpeed = 50000; 							//配置SCL的时钟频率
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;			//时钟占空比
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;							//应答位配置
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//从机响应几位地址的配置
I2C_InitStructure.I2C_OwnAddress1 = 0x00;								//自身地址1
I2C_Init(I2C2, &I2C_InitStructure);

使能I2C

//使能I2C2
I2C_Cmd(I2C2, ENABLE);

整体代码

//------------------------------硬件I2C读写--------------------------------------void I2C_Init2(void)
{//定义结构体变量GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量I2C_InitTypeDef  I2C_InitStructure;//定义I2C结构体变量//开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);//开启I2C2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//开启GPIO B族的时钟//配置GPIOGPIO_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);//配置I2C2I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;							//I2C模式I2C_InitStructure.I2C_ClockSpeed = 50000; 							//配置SCL的时钟频率I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;			//时钟占空比I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;							//应答位配置I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//从机响应几位地址的配置I2C_InitStructure.I2C_OwnAddress1 = 0x00;								//自身地址1I2C_Init(I2C2, &I2C_InitStructure);//使能I2C2I2C_Cmd(I2C2, ENABLE);}//------------------------------硬件I2C读写--------------------------------------

MPU6050配置

//从机地址
#define MPU6050_ADDRESS    0xD0
void MPU6050_Init(void)
{I2C_Init2();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_WriteReg(uint8_t RegAddRess, uint8_t Data)
{//生成起始条件I2C_GenerateSTART(I2C2, ENABLE);//等待EV5事件到来,检查EV5事件while (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);//发送从机地址 方向为发送I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//等待事件 EV6while (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);//写入DR,发送数据I2C_SendData(I2C2, RegAddRess);//等待事件 EV8while (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) != SUCCESS);//发送数据I2C_SendData(I2C2, Data);//等待事件 EV8_2while (I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS);//终止条件I2C_GenerateSTOP(I2C2, ENABLE);
}

指定地址读时序

//指定地址读时序
uint8_t MPU6050_ReadReg(uint8_t RegAddRess)
{uint8_t Data;//起始条件I2C_GenerateSTART(I2C2, ENABLE);//等待事件 EV5while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);//发送从机地址 方向为发送I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//等待事件 EV6while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) != SUCCESS);//发送寄存器地址I2C_SendData(I2C2, RegAddRess);//等待事件 EV8_2while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) != SUCCESS);//重复起始条件I2C_GenerateSTART(I2C2, ENABLE);//等待事件 EV5while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS);//发送从机地址 方向为接收I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);//等待事件 EV6while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) != SUCCESS);//配置ACK位I2C_AcknowledgeConfig(I2C2, DISABLE);//终止条件I2C_GenerateSTOP(I2C2, ENABLE);//等待事件 EV7while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) != SUCCESS);//读取DRData = I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2, ENABLE);return Data;}

主函数

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

优化死循环

超时退出机制,防止卡死

void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
{uint32_t TimeOut = 10000;while(I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS){TimeOut--;if(TimeOut == 0){break;}}
}

将读写时序函数里的while全部替换

//指定地址写时序
void MPU6050_WriteReg(uint8_t RegAddRess, uint8_t Data)
{//生成起始条件I2C_GenerateSTART(I2C2, ENABLE);//等待EV5事件到来,检查EV5事件MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//发送从机地址 方向为发送I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//等待事件 EV6MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//写入DR,发送数据I2C_SendData(I2C2, RegAddRess);//等待事件 EV8MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING);//发送数据I2C_SendData(I2C2, Data);//等待事件 EV8_2MPU6050_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);//等待事件 EV5MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//发送从机地址 方向为发送I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);//等待事件 EV6MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//发送寄存器地址I2C_SendData(I2C2, RegAddRess);//等待事件 EV8_2MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED);//重复起始条件I2C_GenerateSTART(I2C2, ENABLE);//等待事件 EV5MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT);//发送从机地址 方向为接收I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);//等待事件 EV6MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);//配置ACK位I2C_AcknowledgeConfig(I2C2, DISABLE);//终止条件I2C_GenerateSTOP(I2C2, ENABLE);//等待事件 EV7MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED);//读取DRData = I2C_ReceiveData(I2C2);I2C_AcknowledgeConfig(I2C2, ENABLE);return Data;}


http://www.ppmy.cn/news/1571491.html

相关文章

rebase和merge

rebase 和merge区别: rebase变基,改变基底:rebase会抹去提交记录。 git pull 默认merge,git pull --rebase 变基 rebase C、D提交属于feature分支,是基于master分支,在B提交额外拉出来的,当…

docker环境下部署face-search开源人脸识别模型

由于我们是直接将face-search部署在docker容器中的,所以,在部署之前一定要检查一下自己的docker环境,要不然部署过程中会出现各种各样的问题 我这里的docker环境是 一、安装docker环境 如果docker版本比较低或者docker-compose的版本比较低的情况下,部署的时候docker的yml…

LabVIEW商业软件开发

在商业软件开发和仪器自动测试领域,LabVIEW以其图形化编程方式、高效的数据采集能力和强大的硬件集成优势,成为众多工程项目的核心开发工具。然而,商业软件的开发远不止编写代码和实现功能那么简单,尤其是在仪器自动测试领域&…

【Elasticsearch】Bucket Count K-S Test 聚合

Bucket Count K-S Test是 Elasticsearch 中的一种兄弟管道聚合(sibling pipeline aggregation),用于执行双样本柯尔莫哥洛夫-斯米尔诺夫检验(Kolmogorov-Smirnov Test,简称 K-S 检验)。这种聚合主要用于比较…

【DeepSeek】DeepSeek的横向扩展使用② | 制作PPT

本文的主要内容是使用DeepSeek KIMI 制作PPT,效率飞起。 目录 如何使用DeepSeek制作PPT? ①利用 DeepSeek 生成 PPT 内容。 ②使用 Kimi 转换生成 PPT DeepSeek官网:DeepSeek 点击“开始对话”,进入交互页面。 Chat&#x…

c语言样式主题 清爽风格 代码色彩 keil风格 适合单片机开发GD32 STM32等 cursor或者vscode 的settings.json文件

c语言样式主题 清爽风格 代码色彩 keil风格 适合单片机开发GD32 STM32等 cursor或者vscode 的settings.json文件 如上图,是不是和keil mdk很相近。 代码色彩,简单,配合 // 设置工作台主题为 Visual Studio 2017 Light - C 主题使用&#xf…

Cursor 编辑器详细介绍与使用

Cursor 编辑器详细介绍与使用 一、简介 Cursor 是一款 AI 驱动的代码编辑器,集成了先进的大型语言模型(如 GPT-4、Claude 3.5),旨在提升开发者的编程效率和代码质量。它基于 Visual Studio Code (VS Code) 开发,因此继…

Unity使用iTextSharp导出PDF-01准备dll

资料 使用iTextSharp在Asp.Net中操作PDF系列文章 目录 iText 中文教程(含代码).PDF 环境 Unity版本: 2019.4.40f1c1 Scripting Backend:Mono Api Compatibility Level*:.NET 4.x 平台:PC 提取DLL 使用VS2022创建一个控制台应用(.NET Fra…