stm32—I2C

I2C基本概念

I2C (芯片间)总线接口连接微控制器和串行I2C总线。它提供多主机功能,控制所有I2C总线特定的时序、协议、仲裁和定时。支持标准和快速两种模式,同时与SMBus 2.0兼容。I2C模块有多种用途,包括CRC码的生成和校验、 SMBus(系统管理总线—System Management Bus)和PMBus(电源管理总线—Power Management Bus)。根据特定设备的需要,可以使用DMA以减轻CPU的负担。

I2C功能描述

I2C模块接收和发送数据,并将数据从串行转换成并行,或并行转换成串行。可以开启或禁止中断。接口通过数据引脚(SDA)和时钟引脚(SCL)连接到I2C总线。允许连接到标准(高达100kHz)或快速(高达400kHz)的I2C总线。

I2C采用一根双向串行数据线SDA和一根双向串行时钟线SCL实现主/从设备间的多主串行通信。

I2C总线协议:

I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生I2C总线在传输数据的过程中一共有三种信号:开始信号、结束信号、应答信号。

  • 开始信号:SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件
  • 结束信号:SCL为高电平而SDA由低到高的跳变,表示产生一个 停止条件
  • 应答信号:接收数据的IC在接收到8bit的数据后,向发送数据的IC发出一个特定的低电平脉冲,表示已经接收到数据。例如CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号则再根据实际情况决定是否发送下一个信号;若没有接收到应答信号,则可以判断受控单元出现了故障。

总线在空闲状态时,SCL和SDA都保持着高电平

这三种信号里,起始信号是必须需要的,而结束信号和应答信号都可以视情况不要。

在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备 将释放总线,总线再次处于空闲状态。

数据传输:

数据和地址按8位/字节进行传输,高位在前。主设备在SCL线上产生每个 时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位, 此时才认为一个字节真正的被传输完成。

I2C总线上每个设备都对应唯一地址,主从设备的传输都是建立在地址之上的。也就是说,主设备在传输有效数据之前要先指定从设备的地址,地址指定的过程和上面数据传输的过程一样,只不过大多数从设备的地址是7位的,然后协议规定再给地址添加一个最低位用来表示接下来 数据传输的方向,0表示主设备向从设备写数据,1表示主设备向从设备读数据

主模式下:跟在起始条件后的1或2个字节是地址(7位模式为1个字节, 10位模式为2个字节)。

I2C模式选择:

接口可以下述4种模式中的一种运行:

  • 从发送器模式
  • 从接收器模式
  • 主发送器模式
  • 主接收器模式

该模块默认地工作于从模式。接口在生成起始条件后自动地从从模式切换到主模式;当仲裁丢失或产生停止信号时,则从主模式切换到从模式。允许多主机功能。

I2C从模式

从发送器:

在接收到地址和清除ADDR位后,从发送器将字节从DR寄存器经由内部移位寄存器发送到SDA线上。从设备保持SCL为低电平,直到ADDR位被清除并且待发送数据已写入DR寄存器。 (见下图中的EV1和EV3)。

当收到应答脉冲时:

  • TxE位被硬件置位,如果设置了ITEVFEN和ITBUFEN位,则产生一个中断。

    如果TxE位被置位,但在下一个数据发送结束之前没有新数据写入到I2C_DR寄存器,则BTF位被置位,在清除BTF之前I2C接口将保持SCL为低电平;读出I2C_SR1之后再写入I2C_DR寄存器将清除BTF位。

从接收器:

在接收到地址并清除ADDR后,从接收器将通过内部移位寄存器从SDA线接收到的字节存进DR寄存器。 I2C接口在接收到每个字节后都执行下列操作:

  • 如果设置了ACK位,则产生一个应答脉冲

  • 硬件设置RxNE=1。如果设置了ITEVFEN和ITBUFEN位,则产生一个中断。

    如果RxNE被置位,并且在接收新的数据结束之前DR寄存器未被读出, BTF位被置位,在清除BTF之前I2C接口将保持SCL为低电平;读出I2C_SR1之后再写入 I2C_DR寄存器将清除BTF位。(见下图)。

关闭通信:

在传输完最后一个数据字节后,主设备产生一个停止条件, I2C接口检测到这一条件时:

  • 设置STOPF=1,如果设置了ITEVFEN位,则产生一个中断。然后I2C接口等待读SR1寄存器,再写CR1寄存器。 (见上图的EV4)。

I2C主模式

主发送器:

在发送了地址和清除了ADDR位后, 主设备通过内部移位寄存器将字节从DR寄存器发送到SDA线上。 主设备等待,直到TxE被清除, (见下图的EV8)。

当收到应答脉冲时:

  • TxE位被硬件置位,如果设置了INEVFEN和ITBUFEN位,则产生一个中断。如果TxE被置位并且在上一次数据发送结束之前没有写新的数据字节到DR寄存器,则BTF被硬件置位,在清除BTF之前I2C接口将保持SCL为低电平;读出I2C_SR1之后再写入I2C_DR寄存器将清除BTF位。

关闭通信:

在DR寄存器中写入最后一个字节后,通过设置STOP位产生一个停止条件(见图245的EV8_2),然后I2C接口将自动回到从模式(M/S位清除)。

主接收器:

在发送地址和清除ADDR之后, I2C接口进入主接收器模式。在此模式下, I2C接口从SDA线接收数据字节,并通过内部移位寄存器送至DR寄存器。在每个字节后, I2C接口依次执行以下操作:

  • 如果ACK位被置位,发出一个应答脉冲。
  • 硬件设置RxNE=1,如果设置了INEVFEN和ITBUFEN位,则会产生一个中断(见图246的EV7)。如果RxNE位被置位,并且在接收新数据结束前, DR寄存器中的数据没有被读走,硬件将设置BTF=1,在清除BTF之前I2C接口将保持SCL为低电平;读出I2C_SR1之后再读出I2C_DR寄存器将清除BTF位。

关闭通信:

主设备在从从设备接收到最后一个字节后发送一个NACK。接收到NACK后,从设备释放对SCL和SDA线的控制;主设备就可以发送一个停止/重起始条件。

  • 为了在收到最后一个字节后产生一个NACK脉冲,在读倒数第二个数据字节之后(在倒数第二个RxNE事件之后)必须清除ACK位。
  • 为了产生一个停止/重起始条件,软件必须在读倒数第二个数据字节之后(在倒数第二个RxNE事件之后)设置STOP/START位。
  • 只接收一个字节时,刚好在EV6之后(EV6_1时,清除ADDR之后)要关闭应答和停止条件的产生位。
  • 在产生了停止条件后, I2C接口自动回到从模式(M/SL位被清除)。

猜你喜欢

转载自www.cnblogs.com/wyd-blogs/p/12579970.html