打印
[其他]

RTT(RT-Thread)IIC设备

[复制链接]
1659|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
coshi|  楼主 | 2023-9-19 15:27 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
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使用哪写引脚


————————————————
版权声明:本文为CSDN博主「竹烟淮雨」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_25218501/article/details/132336307

6902865094d5bc73dc.png (92.94 KB )

6902865094d5bc73dc.png

使用特权

评论回复
沙发
tpgf| | 2023-10-12 14:10 | 只看该作者
可以对iic的设备进行批量程序烧写吗

使用特权

评论回复
板凳
八层楼| | 2023-10-12 14:35 | 只看该作者
tpgf 发表于 2023-10-12 14:10
可以对iic的设备进行批量程序烧写吗

应该没有这样的烧写器 不过可以通过上位机批量生成烧写文件

使用特权

评论回复
地板
guanjiaer| | 2023-10-12 15:14 | 只看该作者
没看明白iic设备是怎么跑的系统

使用特权

评论回复
5
heimaojingzhang| | 2023-10-12 16:01 | 只看该作者
RT-Thread 是一款主要由中国开源社区主导开发的开源实时操作系统

使用特权

评论回复
6
观海| | 2023-10-12 20:12 | 只看该作者
一般情况下如果通讯失败了会如何处理呢

使用特权

评论回复
7
caigang13| | 2023-10-12 20:40 | 只看该作者
IIC是最简单也是最容易出错的协议

使用特权

评论回复
8
keaibukelian| | 2023-10-12 22:33 | 只看该作者
这两种配合起来的话 在一定程度上能提高数据传输的速度吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

95

主题

3301

帖子

4

粉丝