STM32实现硬件I2C通讯,读取MPU6050的ID号

今天学习了使用硬件I2C的方式成功读取MPU6050的ID号,特此记录一下过程:

首先需要学习的是MPU6050的初始化:

第一步:打开GPIOB的时钟(因为I2C2的引脚10,11在GPIOB上)

第二步:打开I2C2的时钟

第三步:初始化GPIO。

第四步:初始化I2C2。

第五步:开启I2C2。

下面学习的就是指定MPU6050的寄存器地址写数据的函数:
第一步:行成起始条件

第二步:等待EV5事件

第三步:发送7位地址(方向:发送者)

第四步:等待EV6事件(发送完成)

第五步:发送寄存器地址

第六步:等待EV8事件(正在发送)

第七步:发送数据

第八步:等待EV8_2事件(发送完成)

第九步:行成停止条件。

再下面学习的就是指定MPU6050的寄存器地址读数据的函数:

第一步:行成起始条件

第二步:等待EV5事件

第三步:发送7位地址(方向:发送者)

第四步:等待EV6事件(发送完成)

第五步:发送寄存器地址

第六步:等待EV8事件(发送完成)

第七步:再次行成起始条件

第八步:等待EV5事件

第九步:发送7位地址(方向:接收模式)最后一位是接收模式

第十步:等待EV6事件(接收完成标志)

第十一步:应答位给非应答

第十二步:行成终止条件

第十三步: 等待EV7事件(接收完成)

第十四步:提取接收到的数据

第十五步:应答位给应答(回复默认值)

最后就是读取MPU6050的ID号了,MPU6050的ID号存在MPU650的寄存器地址为0x75,读取这个地址中的值就是ID号了。

下面把整个文件展示一下:

#include "stm32f10x.h"                  // Device header
#include "MPU6050.h"

#define MPU6050_ADDRESS                  0xD0
#define GPIO_POART                       GPIOB
#define SCL                              GPIO_Pin_10
#define SDA                              GPIO_Pin_11
#define GPIO_CLOCK                       RCC_APB2Periph_GPIOB
#define I2C_CLOCK                        RCC_APB1Periph_I2C2

void MPU6050_WriteReg(uint8_t Address, uint8_t Data)
{
	I2C_GenerateSTART(I2C2, ENABLE);                                     // 行成起始条件
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) !=SUCCESS );// 等待EV5事件
	
	I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);       // 发送7位地址(方向:发送者)
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) !=SUCCESS );// 等待EV6事件(发送完成)
	
	I2C_SendData(I2C2, Address);                                                   //发送寄存器地址
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING) !=SUCCESS );// 等待EV8事件(正在发送)
	
	I2C_SendData(I2C2, Data);                                                   //发送数据
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) !=SUCCESS );// 等待EV8_2事件(发送完成)
	
	I2C_GenerateSTOP(I2C2, ENABLE);                                        //行成停止条件
}


uint8_t MPU6050_ReadReg(uint8_t Address)
{
	uint8_t Data;
	
	I2C_GenerateSTART(I2C2, ENABLE);                                     // 行成起始条件
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) !=SUCCESS );// 等待EV5事件
	
	I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter);       // 发送7位地址(方向:发送者)
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) !=SUCCESS );// 等待EV6事件(发送完成)
	
	I2C_SendData(I2C2, Address);                                                   //发送寄存器地址
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED) !=SUCCESS );// 等待EV8事件(发送完成)
	
	I2C_GenerateSTART(I2C2, ENABLE);                                     // 行成起始条件
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT) !=SUCCESS );// 等待EV5事件
	
	I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver);       // 发送7位地址(方向:接收模式)
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) !=SUCCESS );// 等待EV6事件(接收完成标志)
	
	I2C_AcknowledgeConfig(I2C2, DISABLE);                                   // 应答位给非应答
	I2C_GenerateSTOP(I2C2, ENABLE);                                          // 行成终止条件
	
	while(I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED) !=SUCCESS );// 等待EV7事件(接收完成)
	Data = I2C_ReceiveData(I2C2);                                          //提取接收到的数据
	
	I2C_AcknowledgeConfig(I2C2, ENABLE);                                  // 应答位给应答
	
	return Data;                                                            //返回接收到的数据
}



void MPU6050_Init(void)
{
	RCC_APB2PeriphClockCmd(GPIO_CLOCK, ENABLE);  //第一步:打开GPIOB的时钟(因为I2C2的引脚10,11在GPIOB上)
	RCC_APB1PeriphClockCmd(I2C_CLOCK, ENABLE);   //第二步:打开I2C2的时钟
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_InitStruct.GPIO_Pin = SCL | SDA;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIO_POART, &GPIO_InitStruct);        // 第三步:初始化GPIO。
	
	I2C_InitTypeDef I2C_InitStruct;
	I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
	I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	I2C_InitStruct.I2C_ClockSpeed = 100000;
	I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_16_9;
	I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStruct.I2C_OwnAddress1 = 0x00;
	I2C_Init(I2C2, &I2C_InitStruct);           // 第四步:初始化I2C2。
	
	I2C_Cmd(I2C2, ENABLE);                //第五步:开启I2C2。
}

uint8_t MPU6050_GetID(void)
{
	return MPU6050_ReadReg(0x75);
}

这样就形成了最终的结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558646.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLAMA 3的测试之旅:在GPT-4的阴影下前行

Meta终于发布了他们长期期待的LLAMA 3模型,这是一个开源模型,实际上提供了一系列新的功能,使得模型在回答问题时表现得更好。这对AI社区来说是一个真正的里程碑事件。 Meta正在发布新版本的Meta AI,这是一种可以在他们的应用程序和…

用Python在PDF文档中插入单图像水印和平铺图像水印

PDF文档因其跨平台兼容性和内容保真度成为信息交换的标准载体,为应对版权侵犯、内容篡改以及未经授权的传播等风险,向PDF中插入图片水印成为一种强化文档安全性、彰显所有权及实施访问控制的有效手段。图片水印不仅能以直观的方式标示文档来源、强化版权…

Git学习笔记(三)Git分支

Git分支是Git中非常重要的一个概念,无论是个人开发还是多人协作中,分支都起着至关重要的作用。几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离 开来进行重大的Bug修改、开发新的功能,以免影响…

Discuz! X3.4 升级至 Discuz! X3.5 详细教程

第一步:从其他以前的 Discuz! X 版本升级Discuz! X3.4 请先升级到Discuz! X3.4,升级教程网上比较普遍,在此不再论述。 第二步:Discuz! X3.4 升级至 Discuz! X3.5 (Discuz 从 X3.5 以后,不在发布GBK版本&…

K8S基础概念

一、MASTER Kubernetes里的Master指的是集群控制节点,在每个Kubernetes集群里都需要有一个Master来负责整个集 群的管理和控制,基本上 Kubernetes的所有控制命令都发给它,它负责具体的执行过程,我们后 面执行的所有命 令基本都…

测试数据整理--chatgpt 构造sql语句导出数据库数据

在测试过程中,我们有时候需要准备一些测试数据,若从系统中直接导出Excel数据,数据往往庞大且需要整合,不好整理,于是我们直接去数据库中查询一些表,数据整合后直接导出结果会更方便。 我们今天就 用 chatg…

云原生Kubernetes: K8S 1.29版本 部署Jenkins

目录 一、实验 1.环境 2.K8S 1.29版本 部署Jenkins 服务 3.jenkins安装Kubernetes插件 二、问题 1.创建pod失败 2.journalctl如何查看日志信息 2.容器内如何查询jenkins初始密码 3.jenkins离线安装中文包报错 4.jenkins插件报错 一、实验 1.环境 (1&…

npm最新淘宝镜像站已经更新registry(2024-04-19)

1、npm替换地址 旧的 https://registry.npm.taobao.org 已替换为 https://registry.npmmirror.com 淘宝镜像的淘宝官方提供的方法(最新的源配置) npm config set registry https://registry.npmmirror.com 镜像站网址: npmm…

ELK日志采集系统

1.什么是ELK ELK 是一套流行的数据搜索、分析和可视化解决方案,由三个开源项目组成,每个项目的首字母合起来形成了“ELK”这一术语: Elasticsearch (ES): Elasticsearch 是一个基于 Apache Lucene 构建的分布式、实时搜索与分析引擎。它能够…

小程序AI智能名片S2B2C商城系统:做内容、造IP、玩社群打造私域流量的新营销秘籍

在数字化浪潮汹涌的新时代,小程序AI智能名片S2B2C商城系统正以其独特的魅力,引领着营销领域的新变革。这套系统不仅将人工智能与小程序技术完美结合,更通过创新的S2B2C模式,为企业打开了一扇通往成功的大门。 面对激烈的市场竞争&…

Jenkins 的构建时执行时间问题

我们希望我的项目能够在特定的时间自动执行,我们需要设定一个定时任务。 Jenkins 的定时任务是通过 Cron 任务来实现的,但是由有点不一样。 H/2 * * * * 比如说上面的设置就是每 2 分钟执行一次。 希望每分钟执行一次 Jenkins 的每分钟执行一次的设置…

c++头文件string函数的用法

目录 前言: 字符串截取 字符串插入与替换 字符串区间删除 字符串排序与相加和查找 如后续需文字描述,,请评论区告诉我,我看到后会进行添加一些文字描述。 前言: 因本人女朋友在学习c过程中在一些知识网页上学了st…

uni-app中页面生命周期与vue生命周期的执行顺序对比

应用生命周期 uni-app 支持如下应用生命周期函数: 函数名说明平台兼容onLaunch当uni-app 初始化完成时触发(全局只触发一次),参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值onShow当 uni-app 启动&#x…

09 MySQL--操作真题

1. 用一条 SQL 语句&#xff0c;查询出每门课程都大于 80 分的人。 分析&#xff1a; 去重查询出存在课程小于 80 分的人&#xff0c;设为集合A查询不在集合 A 中的人 # 第一步&#xff1a;找小于等于80分的学员姓名 select distinct name from t_student where fenshu <…

跨境电商指南:防关联浏览器和云主机有什么区别?

跨境电商的卖家分为独立站卖家和平台卖家。前者会自己开设独立站点&#xff0c;比如通过 shopify&#xff1b;后者则是入驻亚马逊或 Tiktok 等平台&#xff0c;开设商铺。其中平台卖家为了扩大收益&#xff0c;往往不止开一个店铺&#xff0c;或者有店铺代运营的供应商&#xf…

记一次中间件宕机以后持续请求导致应用OOM的排查思路(server.max-http-header-size属性配置不当的严重后果)

一、背景 最近有一次在系统并发比较高的时候&#xff0c;数据库突然发生了故障&#xff0c;导致大量请求失败&#xff0c;在数据库宕机不久&#xff0c;通过应用日志可以看到系统发生了OOM。 二、排查 初次看到这个现象的时候&#xff0c;我还是有点懵逼的&#xff0c;数据库…

解决方案ImportError: cannot import name ‘BertTokenizerFast‘ from ‘transformers‘

文章目录 一、现象二、解决方案 一、现象 从transformers 库调用该包的时候 from transformers import BertTokenizer, AdamW, BertTokenizerFast报错显示 ImportError: cannot import name ‘BertTokenizerFast’ from ‘transformers’ 二、解决方案 追溯查看transforme…

人工智能论文GPT-3(1):2020.5 Language Models are Few-Shot Learners;摘要;引言;scaling-law

摘要 近期的工作表明&#xff0c;在大量文本语料库上进行预训练&#xff0c;然后针对特定任务进行微调&#xff0c;可以在许多NLP任务和基准测试中取得实质性进展。虽然这种方法在架构上通常是与任务无关的&#xff0c;但仍然需要包含数千或数万示例的针对特定任务的微调数据集…

【解决】Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed

问题原因&#xff1a; 在Java8及高版本以上的版本在源应用程序不信任目标应用程序的证书&#xff0c;因为在源应用程序的JVM信任库中找不到该证书或证书链。也就是目标站点启用了HTTPS 而缺少安全证书时出现的异常 解决方案&#xff1a; 我使用的是忽略证书验证 public clas…

面试算法-173-二叉树的直径

题目 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,4,…
最新文章