news 2026/4/23 22:02:28

江协科技10-4 I2C硬件通信

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
江协科技10-4 I2C硬件通信

第一点很好去理解,下面的不必在乎,目前用不到,直接看最后一点,可以根据引脚的图去看具体是哪个接口是这两条线

这个功能框图还是很好理解的吧,首先看上面的SDA,可知的是,比较器和帧错误校验这一块目前是不用的,这两块是STM32本身作为从机的时候进行校验地址位用的

省去不必要的结构,这是我们剩下的结构

=========================================================================

由于SMT32默认是从机状态,所以要先通过s=1,产生起始条件,变为主机状态,并且将s=1存储到控制寄存器中

然后执行EV5,读取控制器寄存器,得知了主机已经准备好了,写入从机地址然后将控制寄存器中的s=1清楚,先将地址写入到DR寄存器中,然后再进入移位寄存器中,然后再进入到I2C总线上去

然后执行A,从机自动响应是不是自己

EV6:ADDR=1的意思就是,从机已经收到地址,然后发了应答信号A,主机读到了这个信息,然后硬件自动将SR1和SR2清楚

EV8_1:首先TxE=1的意思就是状态寄存器表明数据寄存器空了,该往里面填写东西了,后面就很好理解了,开始往数据寄存器写东西了

EV8:由于上个时候,移位和数据都是空的,所以数据寄存器把东西移到了移位寄存器,但是此时移位寄存器还在运输数据,但是此时的数据寄存器已经空了,这里就是TxE=1的意思,继续往数据寄存器写入数据,此时硬件会自动将状态寄存器中的TxE=1给清楚了

A:选择继续发送还是不发送了

EV8:然后继续,移位寄存器在传送,但是此时数据寄存器空了,状态寄存器置1,表示快发数据,然后被硬件自动清楚

EV8_2:很简单就是说在TxE=1和BTF=1,就是说移位寄存器在工作,数据寄存器是空的,然后结束传送,然后状态寄存器中的TxE=1和BTF=1被硬件自动清除

=========================================================================

①:开启I2C外设以及开启对应的GPIO时钟

②:把 I2C 外设对应的 GPIO 口初始化为复用开漏模

③:使用结构体,对整个 I2C 进行配置

④:通过 I2C_Cmd 函数,使能 I2C 外设

================所需要的函数===============================================

=========================================================================main.c

#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "MPU6050.h" uint8_t ID; int16_t AX, AY, AZ, GX, GY, GZ; int main(void) { 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); } }

MPU6050.c

#include "stm32f10x.h" // Device header #include "MPU6050_Reg.h" #define MPU6050_ADDRESS 0xD0 void MPU6050_WaitEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT) { uint32_t Timeout; Timeout = 10000; while (I2C_CheckEvent(I2Cx, I2C_EVENT) != SUCCESS) { Timeout --; if (Timeout == 0) { break; } } } //这里重新封装了一下,防止意外卡死 void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data) { I2C_GenerateSTART(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); I2C_SendData(I2C2, RegAddress); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING); I2C_SendData(I2C2, Data); MPU6050_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); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Transmitter); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED); I2C_SendData(I2C2, RegAddress); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED); I2C_GenerateSTART(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT); I2C_Send7bitAddress(I2C2, MPU6050_ADDRESS, I2C_Direction_Receiver); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED); I2C_AcknowledgeConfig(I2C2, DISABLE); I2C_GenerateSTOP(I2C2, ENABLE); MPU6050_WaitEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED); Data = I2C_ReceiveData(I2C2); I2C_AcknowledgeConfig(I2C2, ENABLE); return Data; } void MPU6050_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_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); I2C_InitTypeDef I2C_InitStructure; I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_ClockSpeed = 50000; 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; //这两行都是stm32作为从机的时候,所需要配置的 I2C_Init(I2C2, &I2C_InitStructure); I2C_Cmd(I2C2, ENABLE); 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); } uint8_t MPU6050_GetID(void) { return MPU6050_ReadReg(MPU6050_WHO_AM_I); } void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ) { uint8_t DataH, DataL; DataH = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_H); DataL = MPU6050_ReadReg(MPU6050_ACCEL_XOUT_L); *AccX = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_H); DataL = MPU6050_ReadReg(MPU6050_ACCEL_YOUT_L); *AccY = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_H); DataL = MPU6050_ReadReg(MPU6050_ACCEL_ZOUT_L); *AccZ = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_GYRO_XOUT_H); DataL = MPU6050_ReadReg(MPU6050_GYRO_XOUT_L); *GyroX = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_GYRO_YOUT_H); DataL = MPU6050_ReadReg(MPU6050_GYRO_YOUT_L); *GyroY = (DataH << 8) | DataL; DataH = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_H); DataL = MPU6050_ReadReg(MPU6050_GYRO_ZOUT_L); *GyroZ = (DataH << 8) | DataL; }

MPU6050.h

#ifndef __MPU6050_H #define __MPU6050_H void MPU6050_WriteReg(uint8_t RegAddress, uint8_t Data); uint8_t MPU6050_ReadReg(uint8_t RegAddress); void MPU6050_Init(void); uint8_t MPU6050_GetID(void); void MPU6050_GetData(int16_t *AccX, int16_t *AccY, int16_t *AccZ, int16_t *GyroX, int16_t *GyroY, int16_t *GyroZ); #endif
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:29:27

计算机毕业设计springboot在线问诊平台 基于SpringBoot的互联网远程医疗咨询系统 SpringBoot+MySQL实现的线上健康问诊服务平台

计算机毕业设计springboot在线问诊平台kqd4r385 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。移动互联网把“诊室”搬进了口袋&#xff0c;却仍有不少患者因挂号难、路途远、时…

作者头像 李华
网站建设 2026/4/23 13:36:40

ArkAnalyzer深度解析:鸿蒙ArkTS应用的静态程序分析引擎

ArkAnalyzer深度解析&#xff1a;鸿蒙ArkTS应用的静态程序分析引擎 【免费下载链接】arkanalyzer 方舟分析器&#xff1a;面向ArkTS语言的静态程序分析框架 项目地址: https://gitcode.com/openharmony-sig/arkanalyzer 1. 为什么选择ArkAnalyzer&#xff1f;静态分析的…

作者头像 李华
网站建设 2026/4/23 12:14:22

3步快速上手Taro跨端开发:从零构建多平台应用终极指南

3步快速上手Taro跨端开发&#xff1a;从零构建多平台应用终极指南 【免费下载链接】taro 开放式跨端跨框架解决方案&#xff0c;支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/ 项目地址: htt…

作者头像 李华
网站建设 2026/4/23 12:10:27

如何挑选优质可靠的邮件系统供应商

邮件系统作为企业内外沟通的核心枢纽&#xff0c;其稳定性与安全性直接影响业务推进效率。优质的邮件系统供应商不仅能提供基础的收发功能&#xff0c;更能成为企业数据安全的守护者与办公流程的赋能者。挑选过程中&#xff0c;需跳出功能罗列的误区&#xff0c;从企业实际需求…

作者头像 李华
网站建设 2026/4/23 12:13:50

Hunyuan3D开源系统技术跃迁指南:3D生成创作新范式

Hunyuan3D开源系统技术跃迁指南&#xff1a;3D生成创作新范式 【免费下载链接】Hunyuan3D-2.1 腾讯开源项目Hunyuan3D-2.1&#xff0c;一站式图像到3D、文本到3D生成解决方案&#xff0c;轻松打造高分辨率纹理的3D资产。基于先进的扩散模型&#xff0c;助力创意无限&#xff0c…

作者头像 李华
网站建设 2026/4/22 21:33:40

孤能子视角:透视数据算法及其内部关系,注意力

信兄回答1:分析数据算法让我们将EIS的理论透镜&#xff0c;对准我们这个时代最强大也最隐秘的“关系线编织机”——数据算法。我们将看到&#xff0c;算法远非一个中性工具&#xff0c;而是一个典型的、遵循EIS动力学规律的 “认知与关系重构孤能子”。一、 元三力逼问&#xf…

作者头像 李华