【STM32】I2C通信—软件模拟

【STM32】I2C通信---软件模拟

  • 一、I2C协议
    • [1.1 I2C简介](#1.1 I2C简介)
    • [1.2 硬件电路](#1.2 硬件电路)
  • 二、I2C时序基本单元
    • [2.1 起始终止](#2.1 起始终止)
    • [2.2 发送一个字节](#2.2 发送一个字节)
    • [2.3 接收一个字节](#2.3 接收一个字节)
    • [2.4 发送接收应答ACK](#2.4 发送接收应答ACK)
  • 三、I2C完整时序数据帧
    • [3.1 指定地址写](#3.1 指定地址写)
    • [3.2 当前地址读](#3.2 当前地址读)
    • [3.3 指定地址读](#3.3 指定地址读)
  • 四、MPU6050芯片
    • [4.1 MPU6050简介](#4.1 MPU6050简介)
    • [4.2 MPU6050参数](#4.2 MPU6050参数)
    • [4.3 硬件电路](#4.3 硬件电路)
    • [4.4 模块内部结构图](#4.4 模块内部结构图)
    • [4.5 数据帧](#4.5 数据帧)
    • 4.6寄存器地址
  • 五、软件模拟I2C读写MPU6050

一、I2C协议

1.1 I2C简介

I2C总线是一种通用数据总线(Inter Ic Bus)
两根通信线SCL (Serial Clack),SDA (Serial Data)
同步,半双工,带数据应答机制
(异步时序的好处省一根时钟线,缺点是对硬件电路非常依赖)
支持总线挂载多设备(一主多从,多主多从)

  • 一主多从:单片机作为主机,主导I2C总线运行,挂载在I2C总线的所有外部模块都是从机,从机只有在主机点名之后才能控制I2C总线
  • 多主多从:在总线上任何一个模块都可以主动跳出来都当主机,此时I2C协议会进行仲裁

1.2 硬件电路


所有I2C设备的SCL连接一起,SDA连在一起。
设备的SCL和SDA均要配置成开漏输出模式(这个模式有个线与的现象,只要有一个设备输出低电平,总线就处于低电平。)
SCL和SDA各添加一个上拉电阻,阻值一般为4.7kΩ左右。

为什么 I2C 必须用开漏模式?

核心原因是为了实现 I2C 的 "线与逻辑"(Wired-AND)多设备共享总线
线与逻辑 :总线上多个设备可同时驱动 SDA/SCL 线,但只有当所有设备都 "释放" 总线(输出高阻态)时,上拉电阻才能将总线拉为高电平;只要有一个设备将总线拉低,总线就会保持低电平。这确保了多个设备通信时不会因 "同时输出高电平" 导致冲突或短路。
多设备兼容 :无论总线上设备的电源电压是否一致(如 3.3V 和 5V 设备混合),开漏模式配合上拉电阻可避免高电压设备对低电压设备的损坏(只要上拉电压匹配低电压设备)。避免一个输出高电平,一个输出低电平导致正负极直接连通短路

二、I2C时序基本单元

2.1 起始终止

起始条件:SCL高电平时期,SDA从高电平切换低电平
终止条件:SCL高电平时期,SDA从低电平切换高电平

2.2 发送一个字节

发送一个字节 :SCL 低电平期间,主机将数据位依次放到 SDA 线上(高位先行 ),然后释放 SCL,从机将在 SCL高电平期间读取数据位,所有 SCL 高电平期间 SDA 不允许有数据变化,依次循环上述过程 8 次,即发送一个字节。
(在SCL低电平时,主机改变SDA,在SCL高电平时,从机读取SDA)

2.3 接收一个字节

接收一个字节 :SCL低电平期间,从机将数据位依次放到SDA线上**(高位先行),然后释放SCL,主机将在SCL高电平期间连续读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节 (主机在接收前,需释放SDA)**
区别:发送一个数据,低电平主机放数据,高电平从机读数据
接收一个数据,高电平主机放数据,低电平从机读数据

2.4 发送接收应答ACK

发送应答 :主机在接收完一个字节后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。
接收应答 :主机在接收完一个字节后,在下个时钟发送一位数据,判断从机是否应答数据0表示应答,数据1表示非应答。(主机在接收之前,需释放SDA)

三、I2C完整时序数据帧

3.1 指定地址写

指定地址写:对于指定设备(Slave Address 从机地址确定),在指定地址(reg address 内部寄存器地址)下写入指定数据

这段时序的意义:对于指定的从机地址为 1101000 的设备,在其内部 0x19 地址寄存器中,写入 0xAA 这个数据

3.2 当前地址读

当前地址读 :对于指定设备(Slave Address),在当前地址指针指示下,读取从机数据

在从机中,所有寄存器被分配到了一个线性区域中,此时会有单独的指针变量,指示其中一个寄存器,每次写入一个字节后指针会自增一次,移动到下一次

3.3 指定地址读

指定地址读:对于指定设备(slave Adress),在指定地址下,读取从机数据

先用指定地址写将指针指到想要的寄存器,再重新起始条件开始当前地址读


最开始,启动条件,发送0XD0进行寻址,读写位为0,代表写入,经过从机应答,再发送一个字节,用来指定地址,此时就写到从机的地址指针里,此时寄存器指针指向了0X19,起始条件后,重新读写,并读标志位
Sr:重复起始条件,相当于另起一个时序。

四、MPU6050芯片

4.1 MPU6050简介

本次运用I2C通信让单片机与MPU6050芯片通信,获取姿态传感器数据。以下是对MPU6050的介绍

MPU 6050 是个 6 轴姿态传感器,可以测量芯片自身的 X,Y,Z 轴的加速度、角速度参数,通过数据融合,可进一步得到姿态角(欧拉角),常用于平衡车等需要检测姿态的场景
3 轴加速度计(Accelerometer):测量 X,Y,Z 轴加速度
3 轴陀螺仪传感器:(Gynoscope)测量 X,Y,Z 轴加速度

欧拉角是飞机机身相对于初始的三个轴的夹角,飞机机头下倾/上仰,这个轴的夹角叫作俯仰,pitch。

飞机机身左翻/右翻叫作滚转,Roll,飞机机身保持水平,机头向左转或者向右转叫作偏航,Yaw。

4.2 MPU6050参数

  • 16位ADC采集传感器的模拟信号,量化范围-32768 - 32767(ADC对各个模拟参量进行量化),会分为2个字节进行存储。
  • 加速度计满量程选择:±2 ±4 ±8 ±16(g)(16位AD值达到最大时,对应的物理参量具体是多少)
    陀螺仪满量程选择:±250,±500,±1000,±2000(°/sec)(每秒旋转了多少度)
  • 可配置的数字低通滤波器(配置低通滤波,输出数据就会平缓,减少抖动)
  • 可配置的时钟源:经过分频器分频,可以为AD转换和其他电路提供时钟,控制分频系数,就可以控制AD转换的快慢了。
  • 可配置的采样频率
    I2C从机地址:1101000(AD0=0) 110 1000 → 0x68 0x68未带读写位 0xD0带读写位
    1101001(AD0=1)

4.3 硬件电路

  • Vcc、GND:电源引脚。
  • SCL、SDA:I2C 通信引脚,因内置 4.7kΩ 上拉电阻,可直接接在 GPIO 口。
  • XCL、XDA:主机 I2C 通信引脚。
  • AD0:从机地址最低位。
  • INT:中断信号输出引脚,可配置芯片内部事件(如 I2C 主机错误,以及芯片内部自带的落体检测、运动检测等)来触发该引脚跳变。

4.4 模块内部结构图

4.5 数据帧

4.6寄存器地址


所有寄存器上电默认都是0x00,除了107号寄存器上电默认为0x40(睡眠),117号寄存器为0x68

五、软件模拟I2C读写MPU6050

实现I2C通信,读写寄存器,来操纵MPU6050
在程序中配置并操作SCL和SDA对应的端口即可

以下是编写程序时要注意的点

  • 程序思路

    软件I2C只需配置GPIO的读写函数即可
    ①把SCL和SDA都初始化为开漏输出模式,此模式下可以输入,输入时,先输出1,再直接输入数据寄存器即可
    ②把SCL和SDA置为高电平,此时I2C总线处于空闲状态

    起始条件
    确保I2C总线释放,先拉低SDA,再拉低SCL
    终止条件
    先拉低SDA,再释放SCL,SDA

    发送一个字节(高位先行)
    Byte & 0x80 相当于把 Byte 的最高位取出来,写1/0
    每次定位,执行释放SCL,拉低SCL操作

    接收一个字节(高位先行)
    进来后,SCL为低电平,主机释放SDA,从机把数据位到SDA
    此时主机释放SCL,用R_SDA读取

    ReceiveAck
    函数进来时,SCL低电平,主机释放SDA,防止从机干扰
    同时从机把应答位放在SDA上,SCL高电平,主机读取应答位
    SCL低电平,进入下一个时序单元。

有关【STM32】I2C通信---软件模拟就到这,希望对你有所帮助,感谢观看!

码文不易,留个赞再走吧~

相关推荐
sheepwjl8 分钟前
《嵌入式硬件(十九):基于IMX6ULL的SPI操作》
单片机·嵌入式硬件·spi·adxl345
zhangx1234_19 分钟前
C语言题目1
c语言·开发语言·数据结构
小年糕是糕手25 分钟前
【C/C++刷题集】二叉树算法题(一)
c语言·数据结构·c++·算法·leetcode·学习方法·改行学it
GalaxySpaceX26 分钟前
STM32-音频播放
stm32·嵌入式硬件·音视频
千語萬言-10 小时前
硬件岗位基础知识
单片机·嵌入式硬件
Z22ZHaoGGGG12 小时前
verilog中数据跨时钟处理方法
单片机·嵌入式硬件·fpga开发·自动化
FanXing_zl13 小时前
基于整数MCU的FOC控制定标策略深度解析
单片机·嵌入式硬件·mcu·算法·定点运算·q15
【云轩】14 小时前
AIoT项目芯片选型指南:在性能、功耗与成本的十字路口
嵌入式硬件
憨憨崽&14 小时前
C语言、Java、Python 的选择与未来发展以及学习路线
java·c语言·python
D.....l14 小时前
STM32学习(MCU控制)(NVIC)
stm32