当前位置: 首页 > news >正文

江协科技STM32学习- P35 硬件I2C读写MPU6050

        🚀write in front🚀  
🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 

💬本系列哔哩哔哩江科大STM32的视频为主以及自己的总结梳理📚 

🚀Projeet source code🚀   

💾工程代码放在了本人的Gitee仓库:iPickCan (iPickCan) - Gitee.com

引用:

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

Keil5 MDK版 下载与安装教程(STM32单片机编程软件)_mdk528-CSDN博客

STM32之Keil5 MDK的安装与下载_keil5下载程序到单片机stm32-CSDN博客

0. 江协科技/江科大-STM32入门教程-各章节详细笔记-查阅传送门-STM32标准库开发_江协科技stm32笔记-CSDN博客

【STM32】江科大STM32学习笔记汇总(已完结)_stm32江科大笔记-CSDN博客

江科大STM32学习笔记(上)_stm32博客-CSDN博客

STM32学习笔记一(基于标准库学习)_电平输出推免-CSDN博客

STM32 MCU学习资源-CSDN博客

stm32学习笔记-作者: Vera工程师养成记

stem32江科大自学笔记-CSDN博客

术语:

英文缩写描述
GPIO:General Purpose Input Onuput通用输入输出
AFIO:Alternate Function Input Output复用输入输出
AO:Analog Output模拟输出
DO:Digital Output数字输出
内部时钟源 CK_INT:Clock Internal内部时钟源
外部时钟源 ETR:External Trigger 时钟源 External 触发
外部时钟源 ETR:External Trigger mode 1外部时钟源 External 触发 时钟模式1
外部时钟源 ETR:External Trigger mode 2外部时钟源 External 触发 时钟模式2
外部时钟源 ITRx:Internal Trigger inputs外部时钟源,ITRx (Internal trigger inputs)内部触发输入
外部时钟源 TIx:exTernal Input pin 外部时钟源 TIx (external input pin)外部输入引脚
CCR:Capture/Comapre Register捕获/比较寄存器
OC:Output Compare输出比较
IC:Input Capture输入捕获
TI1FP1:TI1 Filter Polarity 1Extern Input 1 Filter Polarity 1,外部输入1滤波极性1
TI1FP2:TI1 Filter Polarity 2Extern Input 1 Filter Polarity 2,外部输入1滤波极性2
DMA:Direct Memory Access直接存储器存取

正文:

0. 概述

从 2024/06/12 定下计划开始学习下江协科技STM32课程,接下来将会按照哔站上江协科技STM32的教学视频来学习入门STM32 开发,本文是视频教程 P2 STM32简介一讲的笔记。

1.🚚I2C硬件库函数

stm32中I2C库函数介绍(stm32f10x_i2c.h) 

下面这些是关于I2C的库函数,这里我会挑选最常见的以及本期要用到的来去进行详细讲解。

1.初始化

在学过前面这么多结构体初始化的函数,对于结构体的初始化我们已经再属性不过了,下面是I2C外设的结构体初始化的函数。

void I2C_DeInit(I2C_TypeDef* I2Cx);
void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);

一般情况我们都是自己去定义配置结构体再初始化的,下面我们看一个定义好结构体初始化的示例:

I2C_InitTypeDef I2C_initstruct;I2C_initstruct.I2C_Mode = I2C_Mode_I2C; //选择模式,这里选定使用I2C模式I2C_initstruct.I2C_ClockSpeed = 100000; //选择时钟的频率,不得大于400kHzI2C_initstruct.I2C_DutyCycle = I2C_DutyCycle_2;//占空比选择,低电平:高电平,如果当前是标准速度的话,这个是没用的的,如果在快速时钟的时候,这个才会起作用I2C_initstruct.I2C_Ack = I2C_Ack_Enable; //选择是否给应答I2C_initstruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//stm32作为从机的时候的响应地址位数I2C_initstruct.I2C_OwnAddress1 = 0x01;   //stm32作为从机的时候地址,我们这里是主机,所以这里随便设一个就行了I2C_Init(I2C2, &I2C_initstruct);
2.使能操作

我们本期不需要用DMA到使能,所以这里就不过多讲解。

void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
3.生成起始位和结束位标志
void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);

手册解释如下:

4.发送I2C从机地址

下面这个函数其实就是前面学习软件I2C的“点名”操作,硬件也是一样的,同样都是需要进行点名指定的I2C从机来进行通讯。如果有多个从机,主机会执行下面这个函数后会给每一个从机发送Address的数据,然后从机接收到了后就对比自己的IP数据,如果一样的话那么就开始跟主机通讯,其他从机保持沉默。

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

5.发送数据和接收数据

下面这个是发送数据:

void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);

下面可以看到把数据放入到数据寄存器DR的操作后,然后剩下就是进入到发送数据的流程。 

下面这个是接受数据:

uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);

我们可以看到这个函数的返回值是DR寄存器里面的数据。 

6.发送应答位

下面这个函数是用来发送应答位的,当主机接收到了数据之后会向从机发送应答情况,如果应答位是ENABLE表示接收完成返回一个应答反之就是无应答返回 ,手册解释如下

void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);

7.状态检测

下面这个函数是用来检测每次操作一个步骤之后的状态的,比如发送了一个字节后的数据,然后就会进入一个EVx的状态,这里就需要去执行这个状态是否完成,然后再执行下一步,这是一种缓冲机制以保证数据收发的准确性。在上一期我们也是详细讲解过了这个过程了的。

ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);

下面是这个函数的相关参数: 

2.🚚硬件I2C读取MPU6050

实验现象如下,其实跟前面软件I2C读取MPU6050现象是一样的,只是方法不同。(软件I2C读取MPU6050链接:stm32入门-----软件I2C读写MPU6050-CSDN博客)

1.电路连线图

查STM32F102T8C6引脚定义表,看到I2C1 PB6, PB7引脚已经给 OLED液晶显示屏使用,本节我们使用I2C2的PB10,PB11引脚。

2.主要工程文件 
主要工程文件如下,这里我们就没有像软件那部分一样需要建立一个MyI2C的文件来去执行收发数据的底层,这里我们是使用硬件外设配置库函数来去实现I2C通讯的,底层是由硬件来自动执行的,所以就不需要MyI2C这个文件了。

其中MPU6050.c文件是用来配置I2C外设以及MPU6050相关模块的文件,MPU6050_reg.h文件是存放MPU6050相关寄存器数据的文件

 MPU6050_reg.h文件数据如下:

#ifndef __MP6050_REG_H__
#define __MP6050_REG_H__#define MP6050_SMPLRT_DIV		0x19
#define MP6050_CONFIG			0x1A
#define MP6050_GYRO_CONFIG		0x1B
#define MP6050_ACCEL_CONFIG		0x1C#define MP6050_ACCEL_XOUT_H		0x3B
#define MP6050_ACCEL_XOUT_L		0x3C
#define MP6050_ACCEL_YOUT_H		0x3D	
#define MP6050_ACCEL_YOUT_L		0x3E
#define MP6050_ACCEL_ZOUT_H		0x3F
#define MP6050_ACCEL_ZOUT_L		0x40
#define MP6050_TEMP_OUT_H		0x41
#define MP6050_TEMP_OUT_L		0x42
#define MP6050_GYRO_XOUT_H		0x43
#define MP6050_GYRO_XOUT_L		0x44
#define MP6050_GYRO_YOUT_H		0x45
#define MP6050_GYRO_YOUT_L		0x46
#define MP6050_GYRO_ZOUT_H		0x47
#define MP6050_GYRO_ZOUT_L		0x48#define MP6050_PWM_MGMT_1		0x6B
#define MP6050_PWM_MGMT_2		0x6C
#define MP6050_WHO_AM_I			0x75
#endif

这里我们主要去讲解MPU6050.c这个文件里面的内容,这个是配置I2C外设的主要文件。

3.MPU6050.c代码剖析
(1)检测步骤超时操作

在进入到检测状态的函数的时候,难免会出现意外超时的情况,这里我们就需要去对这个bug进行处理,比如如果超时的情况就放弃这个字节读取或写入的操作。

//检测事件后的超时操作
void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) {uint32_t time_out = 100000;while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS) {time_out--;if (!time_out) {break;} }
}
(2)指定地址写

代码是对应下面这个序列图进行写的,序列图跟代码的步骤是一样的,我们这里使用的是7位。

(3)指定地址读

(4)初始化配置
(5)获取MPU6050寄存器数据
4.主函数代码

这部分其实跟软件I2C读写MPU6050的是一样的。

 


http://www.mrgr.cn/news/65606.html

相关文章:

  • ORACLE 删除archivelog日志
  • 智慧汇聚:十款企业培训工具打造学习型企业
  • 15分钟学 Go 第 35 天:Go的性能调优 (7000字详细教程)
  • 【力扣热题100】[Java版] 刷题笔记-121. 买卖股票的最佳时机
  • 2024.10.4校招 实习 内推 面经
  • MDA模型驱动开发
  • 信息安全工程师(74)网络安全风险评估技术方法与工具
  • 633. 平方数之和 中等
  • 总结拓展十五:SAP物料分割评估
  • MATLAB绘图基础10:MATLAB极坐标相关图形
  • NRF52832学习笔记(41)——添加串口库libuarte
  • 【ACM出版,EI稳定检索】2024年人工智能、数字媒体技术与交互设计国际学术会议(ICADI 2024,11月29-12月1日)
  • clickhouse配置用户角色与权限
  • VScode插件:前端每日一题
  • 西门子1200PLC输入/输出的源漏型解释
  • gozero--环境安装和api语法
  • Dify 中的 Bearer Token 与 API-Key 鉴权方式
  • flutter 专题七 Flutter面试之渲染流程
  • 易灵思fpga pwm生成报错
  • 004-Kotlin界面开发快速入水之TicTacToe
  • 数论——约数
  • 时间序列预测(十七)——滑动窗口的使用
  • TypeScript中的类型注解、Interface接口、泛型
  • Linux设置openfile
  • WPF+MVVM案例实战(二十二)- 制作一个侧边弹窗栏(CD类)
  • 把握人工智能行业脉搏!全球最值得关注的7大AI资讯平台