首页 » 互联网 » 14 玩转STM32之IIC通信(软件模拟篇)_暗记_旗子

14 玩转STM32之IIC通信(软件模拟篇)_暗记_旗子

落叶飘零 2024-10-17 17:29:39 0

扫一扫用手机浏览

文章目录 [+]

个中:SDA:用于数据传输(传输办法:大端传输(MSB),一次8bit,即1字节)SCL:用于数据同步收发

IIC支持多主控,任何韶光点都只有一个主控。
每个连接到总线的设备都只有一个独立的地址,共7bit(也有10bit的,不过用的少点而已)主机正式利用该地址对设备进行访问。
先来看个图:IIC中SDA和SCL引脚是开开泄电路形式,以是SDA和SCL都要接上拉电阻,当总线空闲,SDA和SCL都是高电平。

14 玩转STM32之IIC通信(软件模拟篇)_暗记_旗子 互联网

a.只哀求两条总线线路,一条是串行数据线SDA,一条是串行时钟线SCL。
(IIC是半双工,而不是全双工)。
b.每个连接到总线的器件都可以通过唯一的地址和其它器件通信,主机/从机角色和地址可配置,主机可以作为主机发送器和主机吸收器。
c.IIC是真正的多主机总线,(而类似的SPI总线协议在每次通信前都须要把主机定去世,IIC可以在通讯过程中,改变主机),如果两个或更多的主机同时要求总线,可以通过冲突检测和仲裁防止总线数据被毁坏。
但是任意时候只能有一个主机。
d.传输速率在标准模式下可以达到100kb/s,快速模式下可以达到400kb/s。
e.连接到总线的IIC设备数量只是受到总线的最大负载电容400pf限定。

14.2.1 I2C协议层

一个完全的IIC数据传输含有开始旗子暗记、器件地址、读写掌握、器件内地址访问、数据的有效性、旗子暗记应答、停滞旗子暗记。

1.I2C总线的位传输

数据传输 :SDA的数据在SCL高电日常平凡代被写入从机。
以是SDA的数据变革要发生在SCL低电日常平凡代。
在时钟的高电平周期内,SDA线上的数据必须保持稳定,SDA上传输1位数据(数据线仅可以在时钟SCL为低电平时改变)。

2.I2C总线的开始旗子暗记和结束旗子暗记

起始条件:当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始条件。
结束条件:当SCL为高电平的时候,SDA线上由低到高的跳变被定义为停滞条件。
总线空闲状态 :SDA :高电平 SCL : 高电平

根据上图我们分开进行剖析:当SCL为高电平的时候。
SDA从高电平到低电平,这便是开始旗子暗记(中间会有极小的延时这点要把稳,详细的请参考数据手册),如下图:

当SCL为高电平的时候。
SDA从低电平到高电平,这便是停滞旗子暗记(中间会有极小的延时这点要把稳,详细的请参考数据手册),如下图:

3.I2C总线的字节格式

发送到SDA上的每个字节必须是8位,每次传输可以发送的字节数量不受限定,数据从量高有效位(MSB)开始传输。
吸收器在每成功吸收一个字节后都会返回发送器一个应答位。
如果从机要完成一些其他功能(如一个内部中断做事程序)才能吸收或发送下一个完全的字节,则可以使SCL保持低电平,从而迫使主机进入等待状态。
当从机准备好新的字节数据传输时,开释SCL,数据传输便连续进行。

总结:当IIC主机(不一定是发送端还是接管端)将8位数据或命令传出后,会将SDA旗子暗记设置为输入,等待从机应答( 等待SDA由高电平拉为低电平 )。
若从机精确应答,表明数据或者命令传输成功,否则传输失落败,把稳,应答旗子暗记是数据吸收方发送给数据发送方的。

4.I2C应答旗子暗记

在主机发送完每一个字节数据后,开释SDA(保持高电平),被寻址的吸收器在成功吸收到每个字节后,必须产生一个应答ACK(从机将SDA拉低,使它在这个时钟脉冲的高电日常平凡代保持稳定的低电平)。
当从机吸收不到数据或通信故障时,从机必须使SDA保持高电平。
主机产生一个结束旗子暗记终止传输或者产生重复开始旗子暗记开始新的传输。

SDA上发送的每个字节必须为8位,其后必须跟一个应答位。
12C总线上的所有数量都因此8位字节传送的,发送器每发送一个字节,就在时钟脉冲9期间开释数据线,由吸收器反一个应答旗子暗记。
当应答旗子暗记为低电平时,规定为有效应答位(ACK),表示吸收器已经成功地吸收了该字节:当应答旗子暗记为高电平时,规定为非应答位(NACK),一样平常表示吸收器吸收该字节没有成功。

应答ACK哀求吸收器在第9个时钟脉冲之前的低电日常平凡代将SDA拉低,并且确保在该时钟的高电日常平凡代为稳定的低电平。
如果吸收器是主机,则在它收到末了一个字节后,发送一个NACK旗子暗记,以关照从机发送器结束数据发送,并开释SDA,以便主机吸收器发送一个结束旗子暗记。
传输过程中每次可以发送的字节数量不受限定。
首先传输的是数据的最高有效位(MSB)。

如果从机要在完成一些其他功能之后才能吸收或发送下一个完全的数据字节,则可以使SCL保持低电平,从而迫使主机进入等待状态。
当从机准备好吸收下一个数据字节,并且开释SCL后,数据传输连续。
12C总线必须由主器件掌握,即必须由主机产生开始旗子暗记、结束旗子暗记和时钟旗子暗记。
在时钟旗子暗记为高电平时,SDA上的数据必须保持稳定,SDA上的数据状态仅在时钟旗子暗记为低电平时才可以改变,而当SCL为高电平时,SDA上数据的改变被用来表示开始条件和停滞条件。
须要解释的是,当主机吸收数据时,在末了一个数据字节,必须发送一个非应答旗子暗记(NACK),使从机开释SDA,以便主机产生一个结束旗子暗记来终止总线的数据传送,

总结下来就这两句话:每当主机向从机发送完一个字节的数据,主机总是须要等待从机给出一个应答旗子暗记,以确认从机是否成功吸收到了数据。
从机应答主机所须要的时钟仍是主机供应的,应答涌如今每一次主机完成8个数据位传输后紧随着的时钟周期,低电平0表示应答,1表示非应答。

5.I2C总线的仲裁机制多主机 - 多个主机能够在没有冲突下的情形下,同时共存于总线上,能够通过总线仲裁避免碰撞或数据丢失。
仲裁 - 预先安排的时序,一次只授权一个主机掌握总线。
当SCL线是高电平时,仲裁在SDA线上发生。
在其他主机发送低电平时,发送高电平的主机将会断开它的数据传输级,由于总线上的电平与它自己的电等分歧(线与连接)。
(也便是地址越小,竞争力越强)。
6.从机地址和子地址

在开始条件(S)后,主机发送一个从机地址(或叫作器件地址),指该器件在I2C总线上被主机寻址的地址,地址共有7bit,紧接着的第8bit是数据的读写标志位(0表示写,1表示读)。
从机地址构成:

7.主机发送数据流程

(1)主机在检测到总线为空闲状态(即SDA、SCL均为高电平)时,发送一个开始旗子暗记(S),开始一次通信。

(2)主机接着发送一个命令字节。
该字节由7位的器件地址和l位读写掌握位R/W组成(此时R/W=0)。

(3)相对应的从机收到命令字节后向主机回馈ACK旗子暗记(ACK=0)。
(4)主机收到从机的ACK旗子暗记后,开始发送操作器件内部存储空间的子地址或子地址的高8位。

例如,AT24C02 EEPROM器件内部存储空间访问只须要8位地址。
而AT24C256EEPROM器件内部容量较大,子地址须要16位,那么这一个子地址便是16位子地址的高8位。
(5)从机成功吸收后,返回一个ACK旗子暗记。
(6)主机收到ACK旗子暗记后再发送下一个数据字节或子地址的高8位。
(7)从机成功吸收后,返回一个ACK旗子暗记。
(8)主机的一次发送通信,其发送的数据数量不受限定,当主机发送完末了一个数据字节并收到从机的ACK旗子暗记后,通过向从机发送一个结束旗子暗记(P)结束本次通信并开释总线。
从机收到结束旗子暗记后也退出与主机之间的通信。
I2C总线主机发送数据流程(8位从机地址)如图所示。

I2C总线主机发送数据流程(16位从机地址)如图所示。

8.主机吸收数据流程

(1)主机在检测到总线为空闲状态(即SDA、SCL均为高电平)时,发送一个开始旗子暗记,开始一次通信。
(2)主机接着发送一个命令字节。
该字节由7位的器件地址和1位读写掌握位R/W组成(此时R/w=0)。

(3)相对应的从机收到命令字节后向主机回馈ACK旗子暗记(ACK=0)。
(4)主机收到从机的ACK旗子暗记后开始发送操作器件内部存储空间的子地址。
(5)从机成功吸收后,返回一个ACK旗子暗记。
(6)主机收到应答旗子暗记后,重新产生一个起始旗子暗记。
(7)主机接着发送一个命令字节。
该字节由7位的器件地址和1位读写掌握位R/W组成(此时R/W=1)。
(8)相对应的从机收到命令字节后向主机回馈ACK旗子暗记。
(9)接着,主机开始吸收从机发送过来的数据,在主机成功吸收数据后,如果须要再次吸收数据的话,则主机须要向从机发送一个ACK旗子暗记。
吸收数据的数量不限。
(10)主机吸收到末了一个数据的话,主机向从机发送一个NACK旗子暗记。
(11)从机发送一个结束旗子暗记结束本次通信并开释总线。
从机收到结束旗子暗记后也退出与主机之间的通信。
12C总线主机吸收数据流程如图所示。

14.2 软件仿照I2C协议程序剖析14.2.1 仿照IIC协议简要解释

这点在开头已经说过这里再说一下:由于I2C总线占用的I/O仅须要2根,在很多的实际利用过程中,会利用GPIO引脚来仿照I2C的SDA引脚和SCL引脚,并利用程序来实现I2C协议时序。
软件仿照I2C协议的优点如下。
(1)不须要专门的硬件I2C的掌握器。
(2)引脚可以任意分配,方便PCB布线。
(3)软件修正灵巧。
缺陷:由于采取软件指令会产生韶光的延时,不能用于一些韶光哀求较高的场合。

14.2.2 I2C引脚配置

解释:I2C引脚配置和普通IO配置的过程是一样的。

1.引脚事情模式初始化

将SDA设置为输出模式void SDA_OUT(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(GPIOH, &GPIO_InitStructure);}

对付IIC主机来说,SCL在全体通信过程中都是作为输出模式的、

//将SCL设置为输出模式void SCL_OUT(void)//PA1{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(EEPROM_I2C_SCL_GPIO_CLK,ENABLE);GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);}

对IIC主机,SDA在全体通信过程中,输出数据的时候位输出模式,接収数据或检讨ACK旗子暗记时为输入模式。

//将SDA设置为输入模式void SDA_IN(void) //PA0{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(EEPROM_I2C_SDA_GPIO_CLK,ENABLE);GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);} //将SDA设置为输出模式void SDA_OUT(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(EEPROM_I2C_SDA_GPIO_CLK,ENABLE);GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);} //初始化IICvoid IIC_Init(void){ SDA_OUT();SCL_OUT();IIC_SCL_Hi ;IIC_SDA_Hi;}2.I2C引脚读写掌握

IO操作函数#define IIC_SCL_ Hi GPIO_SetBits(GPIOH,GPIO_Pin_4) //SCL输出高电平#define IIC_SCL_ Lo GPIO_ResetBits(GPIOH,GPIO_Pin_4) //SCL输出低电平#define IIC_SDA_ Hi GPIO_SetBits(GPIOH,GPIO_Pin_5) //SDA输出高电平#define IIC_SDA_ Lo GPIO_ResetBits(GPIOH,GPIO_Pin_5) //SDA输出低电平#define IIC_SDA_In GPIO_ReadInputDataBit (GPIOH,GPIO_Pin_5) //输入SDA状态主机产生IIC起始旗子暗记

起始旗子暗记:当SCL为高电平时,SDA由高电平转向低电平,开始进行数据的传输事情。
开始旗子暗记由主机产生。

主机产生IIC停滞旗子暗记

停滞旗子暗记:当SCL为高电平时,SDA由低电平转高向电平,结束数据的传输事情。
停滞旗子暗记由主机产生。

3 仿照检测ACK旗子暗记

主机每发送一个数据到总线,而且从机每成功收到数据后,都会有一个相应(ACK旗子暗记0)给主机,主机根据检测到的总线上的电平,判断通信是否成功(0成功,1失落败)。

4 软件仿照产生ACK旗子暗记和NACK旗子暗记

当主机成功吸收到从机发送过来的数据,若主机须要接収连续吸收数据,则主机须要返回给从机一个应答旗子暗记,若接収的是末了一个数据,主机会返回给从机一个非应答旗子暗记。

5 软件仿照发送一个字节数据

数据传输的时候,若SCL为高,则SDA必须保持稳定,SDA上传输1位数据。
若SCL为低电平时,SDA才可以改变电平。

6 软件仿照吸收一个字节数据

读一个字节,当ACK=1,发送ACK旗子暗记,ACK=0,发送NACK。

7 软件仿照I2C完全写操作(以AT24xx为例子)

完全的IIC写操作:开始旗子暗记、发送器件地址+写掌握、发送器件子地址(器件内寻址用)、写数据、检测ACK旗子暗记、旗子暗记停滞。

8 软件仿照I2C完全读操作

完全的IIC读操作:开始旗子暗记、发送器件地址+写掌握、发送器件子地址(器件内寻址用)、重启总线、读数据、检测ACK旗子暗记、旗子暗记停滞。

标签:

相关文章