1.SDA线是串行数据线,用于表示数据;SCL线是时钟线,用于数据收发同步。
2.每一个设备都有一个地址,主机可以利用这个地址和不同的设备进行通信。
3.I2C设备空闲时,会输出高阻态(与总线断开);当所有的设备都进入高阻态状态时,总线会被拉直高电平。
4.多个主机使用总线时,会利用仲裁的方式决定那个设备先占用。asda
5.三种传输模式:标准模式100kbit/s 快速模式400kbit/s 高速模式3.4mbit/s 目前大多设备不支持高速模式.
整个总线空闲时,SDA和SCL线都是被拉成高电平的,所以在SCL线为高电平的时候,SDA线出现一个下降沿,说明总线由空闲状态进入了工作状态,为起始信号;同理,在SCL线为高电平的时候,SDA线出现一个上升沿,说明总线由工作状态进入了空闲状态,为停止信号。
SCL为高电平时数据有效,其中,SDA线为高电平表示1,低电平表示0.
I2C总线上每一个设备都有自己的地址,主机发起通信时,是通过SDA线发送设备地址(SLAVE ADDRESS)来查找从机的。I2C可以规定这个地址时7位还是10位的,一般7位较为常见。紧跟在地址后面的是数据传输方向(R/W),1为主机向从机读数据,0为主机向从机写数据。
MSB,LSB指的是串行输出口是高位先行(MSB)还是低位先行(LSB),STM32一般是MSB。
响应包括应答(ACK)和非应答(NACK)两种信号。
当设备接收到I2C传过来的数据或地址后(无论主从机),若希望对方继续发送数据,则会向对方发送一个应答(ACK)信号,对方会继续发送下一个数据;若接收端希望结束数据传输,则会向对方发送一个非应答(NACK)信号,对方接收到后会发送一个停止信号,接收传输。
STM32上有专门负责实现I2C通信的片上外设,只要配置好相应的寄存器即可。当然,也可以通过GPIO引脚模拟通信协议实现”软件模拟“
STM32上的I2C外设支持100kbit/s和400kbit/s速率,而且支持用DMA传输。
CCR寄存器有一个12位的配置引子CCR,它与I2C外设输入时钟共同作用,产生SCL时钟,由于I2C外设是挂载到APB1上的
所以PCLK1=APB1的时钟=36M。
I2C 的 SDA 信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是
数据寄存器(DR)、地址寄存器(OAR)、PEC 寄存器以及 SDA 数据线。当向外发送数据的时
候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过 SDA 信号线发送
出去;当从外部接收数据的时候,数据移位寄存器把 SDA 信号线采样到的数据一位一位地
存储到“数据寄存器”中。若使能了数据校验,接收到的数据会经过 PCE 计算器运算,运
算结果存储在“PEC 寄存器”中。当 STM32 的 I2C 工作在从机模式的时候,接收到设备地
址信号时,数据移位寄存器会把接收到的地址与 STM32 的自身的“I2C 地址寄存器”的值
零死角玩转 STM32F103—指南者
第 228 页 共 835
作比较,以便响应主机的寻址。STM32 的自身 I2C 地址可通过修改“自身地址寄存器”修
改,支持同时使用两个 I2C 设备地址,两个地址分别存储在 OAR1 和 OAR2 中。
整体控制逻辑负责协调整个 I2C 外设,控制逻辑的工作模式根据我们配置的“控制寄
存器(CR1/CR2)”的参数而改变。在外设工作时,控制逻辑会根据外设的工作状态修改
“状态寄存器(SR1 和 SR2)”,我们只要读取这些寄存器相关的寄存器位,就可以了解 I2C
的工作状态。除此之外,控制逻辑还根据要求,负责控制产生 I2C 中断信号、DMA 请求及
各种 I2C 的通讯信号(起始、停止、响应信号等)。
(1) 控制产生起始信号(S),当发生起始信号后,它产生事件“EV5”,并会对 SR1 寄
存器的“SB”位置 1,表示起始信号已经发送;
(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”及
“EV8”,这时 SR1 寄存器的“ADDR”位及“TXE”位被置 1,ADDR 为 1 表示
地址已经发送,TXE 为 1 表示数据寄存器为空;
(3) 以上步骤正常执行并对 ADDR 位清零后,我们往 I2C 的“数据寄存器 DR”写入
要发送的数据,这时TXE位会被重置0,表示数据寄存器非空,I2C外设通过SDA
信号线一位位把数据发送出去后,又会产生“EV8”事件,即 TXE 位被置 1,重
复这个过程,就可以发送多个字节数据了;
(4) 当我们发送数据完成后,控制 I2C 设备产生一个停止信号(P),这个时候会产生
EV8_2 事件,SR1 的 TXE 位及 BTF 位都被置 1,表示通讯结束。
(1) 同主发送流程,起始信号(S)是由主机端产生的,控制发生起始信号后,它产生事
件“EV5”,并会对 SR1 寄存器的“SB”位置 1,表示起始信号已经发送;
(2) 紧接着发送设备地址并等待应答信号,若有从机应答,则产生事件“EV6”这时
SR1 寄存器的“ADDR”位被置 1,表示地址已经发送。
(3) 从机端接收到地址后,开始向主机端发送数据。当主机接收到这些数据后,会产
生“EV7”事件,SR1 寄存器的 RXNE被置 1,表示接收数据寄存器非空,我们读
取该寄存器后,可对数据寄存器清空,以便接收下一次数据。此时我们可以控制
I2C 发送应答信号(ACK)或非应答信号(NACK),若应答,则重复以上步骤接收数
据,若非应答,则停止传输;
(4) 发送非应答信号后,产生停止信号(P),结束传输。
(1) I2C_ClockSpeed
本成员设置的是 I2C 的传输速率,在调用初始化函数时,函数会根据我们输入的数值
经过运算后把时钟因子写入到 I2C 的时钟控制寄存器 CCR。而我们写入的这个参数值不得
高于 400KHz。实际上由于 CCR 寄存器不能写入小数类型的时钟因子,影响到 SCL 的实际
频率可能会低于本成员设置的参数值,这时除了通讯稍慢一点以外,不会对 I2C 的标准通
讯造成其它影响。
(2) I2C_Mode
本成员是选择 I2C 的使用方式,有 I2C 模式(I2C_Mode_I2C )和 SMBus 主、从模式
(I2C_Mode_SMBusHost、 I2C_Mode_SMBusDevice ) 。I2C 不需要在此处区分主从模式,直
接设置 I2C_Mode_I2C 即可。
(3) I2C_DutyCycle
本成员设置的是 I2C 的 SCL 线时钟的占空比。该配置有两个选择,分别为低电平时间
比高电平时间为 2:1 ( I2C_DutyCycle_2)和 16:9 (I2C_DutyCycle_16_9)。其实这两个模式
的比例差别并不大,一般要求都不会如此严格,这里随便选就可以。
(4) I2C_OwnAddress1
本成员配置的是 STM32 的 I2C 设备自己的地址,每个连接到 I2C 总线上的设备都要有
一 个 自 己 的 地 址 , 作 为 主 机 也 不 例 外 。 地 址 可 设 置 为 7 位 或 10 位 ( 受 下 面
I2C_AcknowledgeAddress 成员决定),只要该地址是 I2C 总线上唯一的即可。
STM32 的 I2C 外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员
I2C_OwnAddress1配置的是默认的、OAR1寄存器存储的地址,若需要设置第二个地址寄存
器 OAR2,可使用 I2C_OwnAddress2Config 函数来配置,OAR2 不支持 10 位地址,只有 7
位。
(5) I2C_Ack_Enable
本成员是关于 I2C 应答设置,设置为使能则可以发送响应信号。本实验配置为允许应
答(I2C_Ack_Enable),这是绝大多数遵循 I
2C 标准的设备的通讯要求,改为禁止应答
(I2C_Ack_Disable)往往会导致通讯错误。
(6) I2C_AcknowledgeAddress
本成员选择 I2C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I2C 总线上
设备的地址进行选择,这个成员的配置也影响到 I2C_OwnAddress1 成员,只有这里设置成
10 位模式时,I2C_OwnAddress1 才支持 10 位地址。
配置完这些结构体成员值,调用库函数 I2C_Init 即可把结构体的配置写入到寄存器中。
本实验板中的 EEPROM 芯片(型号:AT24C02)的 SCL 及 SDA 引脚连接到了 STM32 对
应的 I2C引脚中,结合上拉电阻,构成了 I2C通讯总线,它们通过 I2C总线交互。EEPROM
芯片的设备地址一共有 7 位,其中高 4 位固定为:1010 b,低 3 位则由 A0/A1/A2 信号线的
电平决定,见图 24-13,图中的 R/W 是读写方向位,与地址无关。
按照我们此处的连接,A0/A1/A2均为 0,所以 EEPROM的7位设备地址是:101 0000b ,
即 0x50。由于 I2C 通讯时常常是地址跟读写方向连在一起构成一个 8 位数,且当 R/W 位为
0 时,表示写方向,所以加上 7 位地址,其值为“0xA0”,常称该值为 I2C 设备的“写地
址”;当 R/W 位为 1 时,表示读方向,加上 7 位地址,其值为“0xA1”,常称该值为“读
地址”。
来源:零死角玩转STM32—F103指南者