一、I2C原理
I2C是同步通信,方便使用软件模拟,对时间要求不严格,对硬件电路不依赖。但是需要一根时钟线。异步通信节省硬件资源,无需使用时钟线,但是对硬件要求严格,对时钟频率要求严格,依赖硬件电路。
MPU6050陀螺仪、加速度传感器。
OLED显示屏
AT24C02存储器模块
DS3231实时时钟模块
I2C对从设备一般具有id号。
I2C特点:
半双工、具有应答机制、可一主多从(单片机和任意模块通信,其他模块未经同意不会干扰总线,总线上其他所有设备都是从设备)和多主多从(总线冲突时协议会进行仲裁、时钟线 主机控制、多主机需要时钟同步)、同步通信。
I2C引脚:
SCL(时钟线)、SDA(数据线)、VCC(供电+)、GND(地)
I2C协议电路规定(一主多从):
主机权力:主机可以对SCL完全控制 ,在空闲状态下,主机可以主动发起对SDA的控制,只有在从机发送数据和从机应答的时候,主机才会转交SDA的控制权给从机。
从机权力:对于SCL时钟线,在任何时刻都只能被动读取。从机不允许控制SCL线。只有在主机发送读取从机的命令后或者从机应答的时候,从机才能短暂的取得SDA的控制权。
若无上拉电阻:主机完全控制SCL,所以可以配置为推挽输出模式。从机SCL配置为浮空输入或者上拉输入。数据流向为主机发送,所有从机接收。
主机和从机都可以控制SDA,若总线SDA时序错误,主从机控制冲突会发生断路状态,应该极力避免。为了避免这个问题,I2C禁止所有设备在SDA输出强上拉的高电平。采用外置弱上拉电阻和 加开漏输出的电路结构。
总结为设备的SCL和SDA均要配置为开漏输出模式。SCL和SDA各添加上拉电阻,约4.7KΩ。当主机和从机冲突时也是一个强下拉,一个弱上拉,总线为下拉状态。
开漏输出优点:
1、避免了总线短路的情况。有一个输出低电平,总线就为低电平。
2、开漏加弱上拉模式,同时兼具了输入和输出的功能。输出时可以自由控制低电平输出。输入则可以直接放手(不输出或者输出高电平,输入前可以保持输出高电平,不需要在切换成输入模式)直接观察总线状态即可。
3、具有线与特性,有一个输出低电平,总线就为低电平。可以通过这个特性执行多主机模式下的时钟同步和总线仲裁。
I2C时序单元:
起始时:SCL高电平期间,SDA进行低电平转换。从机捕获到SCL高电平、SDA下降沿的信号,会进行复位,等待主机的操作。然后主机拉低SCL,开始进行数据的发送(拼接时序单元)和时钟信号的控制。
结束时:SCL先高电平,后SDA置高电平,回归等待状态。
起始和终止条件类似于串口的起始位和终止位。I2C起始终止都有主机产生。
主机发送一个字节,在起始条件后,控制在SCL低电平期间改变电平状态对应数据位(高位先行),从机会在SCL高电平(主机释放)期间读取该数据。
主机接收一个字节:主机控制SCL低电平期间,从机将数据位放在SDA(高位先行),SCL高电平(主机释放)期间,主机读取SDA数据。在SCL高电平期间不允许主从机对SDA的控制。
应答设计:
I2C时序:指定地址写
I2C中使用一主多从模式时,每次主机发送指定从机的设备地址(相当于从机的名字),对应的从机响应主机的读写操作。在一个I2C总线上挂在的从设备地址需要不一样,否则会有多个设备响应。从机地址分为7bit和10bit,此处我们实例为7bit(可在厂商手册中看到),使用广泛并且简单。比如MPU6050地址为1101000,AT24C02地址为1010000。若模块地址相同,则需要使用模块Ax-Ax+n引脚可变地址,高电平为1,低电平为0,可确定I2C地址的低几bit。
1、主机发送7bit(从机地址)+R/W(0为写,1为读),主机发送完1byte,需要释放SDA接收1bit从机的应答位,从机返回0为接收到,返回1为未接收。整个过程是,SCL低电平时改变SDA电平,SCL高电平从机获取主机发送的SDA,主机发送完7bit(从机地址)+R/W(0为写,1为读),释放SDA,从机控制SDA置应答bit。
然后从机在应答的下一时钟的下降沿快速释放SDA(给主机在低电平变换SDA的时间,接着下一字节操作),所以此处SDA上升沿和SCL下降沿几乎一起。---高位先行
2、然后紧接着便是主机发送需要读写的地址,此处SCL、SDA波形和前段原理相同。---高位先行
3、然后紧接着便是主机在该地址需要写入的数据,波形原理相同,在RA(从机应答bit)后,主机在下一时钟SCL低电平拉低SDA。然后在下一SCL高电平拉高SDA发送结束信号。
I2C时序:当前地址读
1、起始条件,主机控制
2、主机SCL低电平写入SDA,高电平从机读取SDA,发送从机地址7bit和1bit读写,1为读。然后从机返回应答bit。
3、读取当前从机指针(从机内存为线性地址,有一个地址指针,指向内存地址,每次读写都会自增,默认上电指针为0)指向地址的数据,此时主机释放SDA,SCL高电平期间从机改变SDA,SCL低电平期间主机获取SDA。
例如使用指定地址写1byte,0x19地址,那么下一次若使用当前地址读1byte,则为0x1A地址的数据。
4、停止条件,主机控制
I2C时序:指定地址读
1、指定地址写,0x19地址。但是不写数据。
2、使用重复起始条件Sr(在下一SCL低电平,SDA释放为高电平。下下次SCL高电平期间,SDA拉低)。
3、紧接着使用当前地址读操作,进行数据读取。
4、在读取的最后一字节,停止接收反馈应答。主机控制停止信号
也可以进行起始+指定地址写+结束+起始+当前低地址读+读取数据+结束。上面时序为官方时序。
多次读写操作:
从设备地址指针会自动自增,在指定地址读和指定地址写和当前地址读中,若读写完成后不进行停止操作,继续进行数据读写时序操作(无需指定操作和地址),会对连续的地址进行写入。
连续读操作时,在从机返回SDA数据完成后,若想停止从机返回数据,需要停止最后一字节的主机应答,即返回从机1的SDA,这样从机就会停止返回数据。
若使用主机返回应答0,然后控制SDA进行停止时序操作,可能会和从机SDA数据冲突,导致不能停止。
STM32硬件I2C外设:
I2C做为同步通信,软件控制更加可靠,但是硬件控制能够节省软件资源,,且硬件功能强大,能够完成多主机通信、时序波形规整、通信速率快。
一般设备地址前五位为11010表示后面10bit都为寻址位。不会再7bit地址下出现。
前五位为11110表示为地址为,7bit寻址。
I2C常用于内存设备中,使用DMA可以快速读写设备信息。
SMBus是系统管理总线,是基于I2C改进的协议,常用于电源管理系统。
STM32通信结构图
SMBALERT为SMBus协议内容。
DATA REGISTER为数据寄存器,将数据放入DATA REGISTER,数据会通过数据移位寄存器进行发出。一但移位寄存器完成数据转移,会置TXE=1表示发送寄存器空,可以立即将新数据放入DATA REGISTER.
当数据从SDA接收到,会通过数据移位寄存器转移到DATA REGISTER,当数据转移完成会置RXNE=1,表示接收寄存器非空,可以进行数据读取。
比较器和地址寄存器都是从机模式使用的,STM32的I2C是基于可变多主机进行的,STM32不进行通信的时候就是从机,作为从机的地址通过自身地址寄存器指定。当受到主机召唤就会响应(双地址表示可以有两个从机地址,可能为2路I2C原因)。
硬件I2C有CRC硬件校验电路会自己校验。同串口奇偶校验相同。
I2C通信可以请求中断,进行中断处理。可以使用DMA。
简化图:
使用复用开漏输出/复用输入
STM32F103C8T6的I2C外设引脚
硬件I2C的操作流程
主机发送:
s:
EV5:STM32切换主模式,读取SR1后,在写数据寄存器后,SB会自动清除,所以一般无需自己清除
写从机地址,到数据寄存器DR中。
EV6: 判断从机地址是否发送结束
EV8_1:初始发送数据时TXE=1,移位寄存器和数据寄存器都为空,需要向DR寄存器进行写入数据。
EV8:初始发送写入数据后,数据转入移位寄存器, 移位寄存器仍非空TXE=1,DR仍然为空,若需要连续写入需要继续进行DR写入数据操作。
EV8_2:移位寄存器空