I2C简介
- I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线
- 两根通信线:SCL(Serial Clock)、SDA(Serial Data)
- 同步,半双工
- 带数据应答
- 支持总线挂载多设备(一主多从、多主多从)
硬件电路
- 所有I2C设备的SCL连在一起,SDA连在一起
- 设备的SCL和SDA均要配置成开漏输出模式
- SCL和SDA各添加一个上拉电阻,阻值一般为4.7KΩ左右

I2C时序基本单元
- 起始条件:SCL高电平期间,SDA从高电平切换到低电平
- 终止条件:SCL高电平期间,SDA从低电平切换到高电平

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

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

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

I2C时序
指定地址写
对于指定设备(Slave Address),在指定地址(Reg Address)下,写入指定数据(Data)

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

指定地址读
对于指定设备(Slave Address),在指定地址(Reg Address)下,读取从机数据(Data)

I2C外设
- STM32内部集成了硬件I2C收发电路,可以由硬件自动执行时钟生成、起始终止条件生成、应答位收发、数据收发等功能,减轻CPU的负担
- 支持多主机模型
- 支持7位/10位地址模式
- 支持不同的通讯速度,标准速度(高达100 kHz),快速(高达400 kHz)
- 支持DMA
- 兼容SMBus协议
实际外设: STM32F103C8T6 硬件I2C资源:I2C1、I2C2


序列图


代码
软件I2C
|
|
硬件I2C
|
|
I2C_InitTypeDef为I2C配置结构体I2C_Mode为I2C模式I2C_ClockSpeed为时钟频率I2C_DutyCycle为I2C快速模式占空比I2C_Ack为响应使能I2C_AcknowledgedAddress为地址模式I2C_OwnAddress1为本设备的第一个ID
I2C_GenerateSTART函数发送起始条件I2C_Send7bitAddress函数发送7位地址I2C_SendData函数发送数据I2C_GenerateSTOP函数发送终止条件I2C_AcknowledgeConfig函数配置应答I2C_CheckEvent函数读取状态I2C_ReceiveData函数读取结果
| I2C_EVENT | 事件 | 值 |
|---|---|---|
| I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED | EV1 | ((uint32_t)0x00060082) |
| I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED | EV1 | ((uint32_t)0x00020002) |
| I2C_EVENT_SLAVE_TRANSMITTER_SECONDADDRESS_MATCHED | EV1 | ((uint32_t)0x00860080) |
| I2C_EVENT_SLAVE_RECEIVER_SECONDADDRESS_MATCHED | EV1 | ((uint32_t)0x00820000) |
| I2C_EVENT_SLAVE_GENERALCALLADDRESS_MATCHED | EV1 | ((uint32_t)0x00120000) |
| I2C_EVENT_SLAVE_BYTE_RECEIVED | EV2 | ((uint32_t)0x00020040) |
| (I2C_EVENT_SLAVE_BYTE_RECEIVED| I2C_FLAG_DUALF) | EV2 | |
| (I2C_EVENT_SLAVE_BYTE_RECEIVED| I2C_FLAG_GENCALL) | EV2 | |
| I2C_EVENT_SLAVE_BYTE_TRANSMITTED | EV3 | ((uint32_t)0x00060084) |
| (I2C_EVENT_SLAVE_BYTE_TRANSMITTED| I2C_FLAG_DUALF) | EV3 | |
| (I2C_EVENT_SLAVE_BYTE_TRANSMITTED| I2C_FLAG_GENCALL) | EV3 | |
| I2C_EVENT_SLAVE_ACK_FAILURE | EV3_2 | ((uint32_t)0x00000400) |
| I2C_EVENT_SLAVE_STOP_DETECTED | EV4 | ((uint32_t)0x00000010) |
| I2C_EVENT_MASTER_MODE_SELECT | EV5 | |
| I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED | EV6 | |
| I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED | EV6 | |
| I2C_EVENT_MASTER_BYTE_RECEIVED | EV7 | |
| I2C_EVENT_MASTER_BYTE_TRANSMITTING | EV8 | |
| I2C_EVENT_MASTER_BYTE_TRANSMITTED | EV8_2 | |
| I2C_EVENT_MASTER_MODE_ADDRESS10 | EV9 |
I2C事件流程(常用的主模式)
通讯开始
- EV5
- I2C_EVENT_MASTER_MODE_SELECT
- After sending the START condition (I2C_GenerateSTART() function) the master has to wait for this event. It means that the Start condition has been correctly released on the I2C bus (the bus is free, no other devices is communicating).
- 发送 通讯启动条件(I2C_GenerateSTART() 函数)后,主设备必须等待此事件(EV5)。 此事件意味着I2C总线上的启动条件已正确释放(总线空闲,没有其他设备正在通信)。
地址确认
- EV6
- I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
- After checking on EV5 (start condition correctly released on the bus), the master sends the address of the slave(s) with which it will communicate (I2C_Send7bitAddress() function, it also determines the direction of the communication: Master transmitter or Receiver). Then the master has to wait that a slave acknowledges his address. If an acknowledge is sent on the bus, one of the following events will be set:
- In case of Master Receiver (7-bit addressing): the I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED event is set.
- In case of Master Transmitter (7-bit addressing): the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED is set
- In case of 10-Bit addressing mode, the master (just after generating the START and checking on EV5) has to send the header of 10-bit addressing mode (I2C_SendData() function). Then master should wait on EV9. It means that the 10-bit addressing header has been correctly sent on the bus. Then master should send the second part of the 10-bit address (LSB) using the function I2C_Send7bitAddress(). Then master should wait for event EV6.
- 主设备发送与其通信的从设备的地址,同时确定通信方向,然后主设备应该等待事件EV6。
通讯事件
- EV8、EV8_2 / EV7
- I2C_EVENT_MASTER_BYTE_TRANSMITTING、I2C_EVENT_MASTER_BYTE_TRANSMITTED / I2C_EVENT_MASTER_BYTE_RECEIVED
Others
If a communication is established (START condition generated and slave address acknowledged) then the master has to check on one of the following events for communication procedures:
- Master Receiver mode: The master has to wait on the event EV7 then to read the data received from the slave (I2C_ReceiveData() function).
- Master Transmitter mode: The master has to send data (I2C_SendData() function) then to wait on event EV8 or EV8_2. These two events are similar:
- EV8 means that the data has been written in the data register and is being shifted out.
- EV8_2 means that the data has been physically shifted out and output on the bus.
- In most cases, using EV8 is sufficient for the application. Using EV8_2 leads to a slower communication but ensure more reliable test. EV8_2 is also more suitable than EV8 for testing on the last data transmission (before Stop condition generation).
- In case the user software does not guarantee that this event EV7 is managed before the current byte end of transfer, then user may check on EV7 and BTF flag at the same time (ie. (I2C_EVENT_MASTER_BYTE_RECEIVED | I2C_FLAG_BTF)). In this case the communication may be slower.