目录
IIC设备
IIC介绍
电气连接
IIC总线时序
IIC协议
读协议
写协议
访问I2C总线设备
查找 I2C 总线设备
I2C数据读写(数据传输)
配置IIC步骤
IIC设备
IIC介绍
I2C(Inter Integrated Circuit)总线是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。而我们之前的串口设备属于全双工通信,一般使用异步功能。
I2C 总线传输数据时只需两根信号线:
- 双向数据线 SDA
- 双向时钟线 SCL
电气连接
在一个IIC总线上,可以挂在多个主机,也可以挂在多个从机。也就是说在IIC总线上,可以支持多主多从的模式。对于多个主机,IIC采用仲裁的方式来确定到底哪个主机在通信,对于从机的访问是根据协议里面从机的地址来确定到底跟哪一个从机设备通信。
一般我们使用IIC总线采用一主一从或者一主多从的方式。
IIC总线时序
IIC的时序图如下
在IIC通信的时候,需要主机去发送一个起始条件,然后从机才会响应,当主机主动发出停止条件,双方才会结束通信。
起始条件:时钟线在高电平的时候,数据线由高到低产生负跳变。
停止条件:在时钟线的高电平期间,数据线由低到高产生正跳变。
在时钟线的高电平期间,进行数据线的读取。在时钟线的低电平期间,发生数据线的跳变。
在IIC通信中除了基本的读取写入数据,还包括应答。
应答:在通信的时候,主机发送数据或命令给从机的时候,从机需要产生应答信号,数据线为低电平表示发送应答信号,电平拉高表示非应答信号。
IIC协议
读协议
单字节读:
首先主机发送一个起始信号,一旦主机发送起始信号之后,挂载在总线上的所有从机设备都能接收到。因此紧接着会发送一个字节其中包括了目标从机的地址和写命令(一共是0-7八个位,1-7位代表设备地址,0位代表读写方向)。
相应从机接收到命令就会产生一共应答信号。然后主机接着发送一个字节(存储目标寄存器的地址),接着等待从机应答。接着再发送一个字节,其中再次指定目的从机地址和读命令,表示从机想要从机的寄存器中读取数据了。从机再次发送一个应答,并将相应寄存器中的数据发送给主机。
最后主机接收完数据产生一个非应答信号,并发出停止信号。
多字节读:
对于多字节读,步骤前面与单字节读一样。但是在主机接收到从机发送的数据之后,产生的是一个应答信号。那么从机就会继续发送数据,然后手机继续产生应答信号,从机继续发送,直到主机发送一个非应答加停止信号以后才结束通信。
写协议
单字节写:
首先主机发送一个起始信号;接着发送一个字节命令,其中包括从机的地址和写方向;从机产生应答;主机继续发送一个字节,指明了要写入到从机的寄存器地址;从机产生应答;主机发送数据;从机产生应答;主机发送停止信号,通信结束。
多字节写:
多字节写与单字节写相同,只要主机不主动发出停止信号,从机就一直对主机写入数据产生应答,直到主机发送停止信号,才结束通信。
访问I2C总线设备
查找 I2C 总线设备
#define AHT10_I2C_BUS_NAME "i2c1" /*传感器连接的I2C总线设备名称*/
struct rt_i2c_bus_device *i2c_bus; /*I2C总线设备句柄*/
/*for i2c bus driver*/
struct rt_i2c_bus_device
{
struct rt_device parent;
const struct rt_i2c_bus_device_ops *ops;
rt_uint16_t flags;
rt_uint16_t addr;
struct rt_mutex lock;
rt_uint32_t timeout;
rt_uint32_t retries;
void *priv;
};
/*查找I2C总线设备,获取I2C总线设备句柄*/
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
rt_device_t rt_device_find(const char *name);
I2C数据读写(数据传输)
该函数既可以实现写数据,也可以进行读数据
参数1:I2C设备句柄
参数2:要发送获接收的数据包(定义一个结构体数组)
参数3:数据包的个数
#define RT_I2C_WR 0x0000
#define RT_I2C_RD (1u << 0)
struct rt_i2c_msg
{
rt_uint16_t addr;
rt_uint16_t flags;
rt_uint16_t len;
rt_uint8_t *buf;
};
rt_size_t rt_i2c_transfer(structrt_i2c_bus_device *bus,
structrt_i2c_msg msgs[],
rt_uint32_t num)
对于rt_i2c_msg结构体的成员解释:
- addr为从机的地址
- flags为读写的标志,读为1,写为0
- len为要发送获读取的数据长度
- buf指向读写数据的空间首地址
配置IIC步骤
/** if you want to use i2c bus(soft simulate) you can use the following instructions.
*
* STEP 1, open i2c driver framework(soft simulate) support in the RT-Thread Settings file
*
* STEP 2, define macro related to the i2c bus
* such as #define BSP_USING_I2C1
*
* STEP 3, according to the corresponding pin of i2c port, modify the related i2c port and pin information
* such as #define BSP_I2C1_SCL_PIN GET_PIN(port, pin) -> GET_PIN(C, 11)
* #define BSP_I2C1_SDA_PIN GET_PIN(port, pin) -> GET_PIN(C, 12)
*/
步骤一:在驱动框架中开启对IIC设备的支持
步骤二:在board.h中宏定义使用IIC
步骤三:指定IIC使用哪写引脚