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

江协科技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
http://www.cnnetsun.cn/news/22399.html

相关文章:

  • ChatPPT:国内综合实力最强的AI PPT工具
  • 测试经验,自动化测试的痛点+发展趋势,一篇带你上高速...
  • NetGuard实战指南:告别流量焦虑,让Android网络管理如此简单
  • 大厂已经不用人干活了?“AI中台+Agent”正在重塑商业规则
  • Qwen2.5-Omni全模态大模型:70亿参数重构人机交互范式
  • Morisawa BIZ UDGothic 字体使用指南:让文字表达更专业优雅
  • 量子化学:材料的电子态密度
  • 零基础也能做!用Qoder快速开发“技能五子棋”蹭热点项目
  • GitHub加速终极方案:告别龟速访问,体验丝滑编程
  • 【总结】【计组】【OS】页号、页框号、虚拟地址、物理地址、地址
  • 超细整理,性能测试如何做?怎么做?性能压力负载(汇总三)
  • 国外代理IP怎么选?4大标准帮你避坑选优
  • 艾体宝洞察 | 当供应链恶意代码会“二次来袭”:Shai-Hulud 事件下,为什么必须重新审视你的应用安全体系?
  • OpenHarmony环境搭建——02-JDK17安装教程
  • 艾体宝干货 |【Redis实用技巧#4】Redis分布式锁真的安全吗?可靠性深度剖析(Part 2)
  • 21-4. PLC的基本逻辑指令(置位,复位指令)
  • VueScan Pro:专业扫描仪增强软件,支持多品牌设备与高质量OCR识别
  • Kali 必备!Burp Suite 超全教程 网安新手必看
  • 60、深入理解与配置 SSH:安全远程访问的全面指南
  • 视频生成大模型Wan2.2开源:MoE架构重构创作生态,消费级显卡实现电影级视频生成
  • [HNCTF 2022 Week1]easync
  • Ultravox终极指南:10个步骤掌握AI音频生成技术
  • 虎贲等考 AI 科研工具:大学生 / 科研人必备!用 AI 高效搞定学术研究
  • 学习 Python,用哪个编辑器比较好?
  • 如何高效地分析问卷调查的数据?
  • nginx部署前端vue项目(非常详细)零基础入门到精通,收藏这篇就够了
  • 何为前端工程化?一文给你说透前端工程化,收藏这篇就够了
  • 免费学习资源|谷歌 5天AI Agents 强化课程|十一月开课
  • 前端及其技术栈,零基础入门到精通,收藏这篇就够了
  • vscode 前端常用插件推荐,零基础入门到精通,收藏这篇就够了