前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【玩转 RT-Thread】I2C 内核

【玩转 RT-Thread】I2C 内核

作者头像
攻城狮杰森
发布于 2022-06-03 06:02:43
发布于 2022-06-03 06:02:43
567036
代码可运行
举报
文章被收录于专栏:技术集锦技术集锦
运行总次数:36
代码可运行

文章目录

一、i2c协议

由飞利浦公司开发,支持设备间的短距离通信。i2c通信需要的引脚少,硬件实现简单、可扩展性强,被广泛应用在系统内多个集成电路(IC)间的通信。

二、i2c物理层

  • i2c通信总线可连接多个i2c通信设备,支持多个通信主机和多个通信从机。i2c通信只需要两条双向总线——SDA(串行数据线)和SCL(串行时钟线)。 SDA:用于传输数据 SCL:用于同步数据收发
  • 每个连接到总线的设备都有一个独立地址,共7bit,主机正是利用该地址对设备进行访问
  • i2c支持多主控,任何时间点都只能有一个主控。
  • i2c器件的SDA引脚和SCL引脚是开漏电路形式,因此,SDA和SCL总线都需要连接上拉电阻,当总线空闲时,两条总线均为高电平。
  • 各器件的SDA和SCL信号线在总线上都是线与关系。(即连接到总线上的任意器件输出低电平都会将总线信号拉低)

三、i2c协议层

协议层定义了i2c的通信协议。一个完整的i2c数据传输包含开始信号,器件地址,读写控制,器件内访问地址,有效数据,应答信号和结束信号。

1.i2c总线的位传输

数据传输:当SCL位高电平时,SDA必须保持稳定,SDA上传1位数据。 数据改变:当SCL为低电平时,SDA才可以改变电平 i2c位传输时序图

2.i2c总线的开始和结束信号

开始信号:SCL 为高电平时,主机将SDA 拉低,表示数据传输即将开始。 结束信号:在SDA 为低电平时,主机将SCL 拉高并保持高电平,然后在将SDA 拉高,表示传输结束。

3.i2c应答信号

  • 主机发送完每一个字节数据后,释放SDA(保持高电平),被寻址的接收器在成功接收到每一个字节后,必须产生一个应答ACK(从机将SDA拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平)
  • 从机接收不到数据或通信故障时,从机必须使SDA保持高电平,主机产生一个结束信号终止传输或者产生新的传输。

4.i2c总线的仲裁机制

  • SDA的仲裁也是建立在总线具有线与逻辑功能的原理上的。
  • 节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致。是,继续发送;否则,退出竞争。
  • SDA的仲裁可以保证i2c总线系统在多个主节点上同时企图控制总线时通信正常进行而且数据不丢失(总线系统通过仲裁只允许一个主节点可以继续占据总线)
  • 当SCL为高电平时,仲裁在SDA上发生。在其他主机发送低电平时,发送高电平的主机将会断开它的数据传输级,因为总线上的电平是线与连接。

四、访问i2c总线设备

一般情况下MCU 的I2C 器件都是作为主机和从机通讯,在RT-Thread 中将I2C 主机虚拟为I2C 总线设备,I2C 从机通过I2C 设备接口和I2C 总线通讯,相关接口如下所示:

函数

描述

rt_device_find()

根据I2C 总线设备名称查找设备获取设备句柄

rt_i2c_transfer()

传输数据

五、查找i2c总线设备

在使用I2C 总线设备前需要根据I2C 总线设备名称获取设备句柄,进而才可以操作I2C 总线设备,查找设备函数如下所示,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rt_device_t rt_device_find(const char* name);

参数

描述

name

i2c总线设备名称

返回

设备句柄

查找到对应设备将返回相应的设备句柄

RT-NULL

没有找到相应的设备对象

一般情况下,注册到系统的I2C 设备名称为i2c0 ,i2c1 等,使用示例如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define AHT10_I2C_BUS_NAME "i2c1" /* 传感器连接的I2C总线设备名称*/
struct rt_i2c_bus_device *i2c_bus; /* I2C总线设备句柄*/
/* 查找I2C总线设备, 获取I2C总线设备句柄*/
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);

六、数据传输

获取到I2C 总线设备句柄就可以使用rt_i2c_transfer() 进行数据传输。函数原型如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
										struct rt_i2c_msg msgs[],
										rt_uint32_t num);

参数

描述

bus

i2c总线设备句柄

msgs[]

待传输的消息数组指针

num

消息数组的元素个数

返回

-

-

-

消息数组的元素个数

成功

错误码

失败

  • 和SPI 总线的自定义传输接口一样,I2C 总线的自定义传输接口传输的数据也是以一个消息为单位。
  • 参数msgs[] 指向待传输的消息数组,用户可以自定义每条消息的内容,实现I2C 总线所支持的2 种不同的数据传输模式。如果主设备需要发送重复开始条件,则需要发送2 个消息。 !!! note “注意事项” 此函数会调用rt_mutex_take(), 不能在中断服务程序里面调用,会导致assertion报错。

I2C 消息数据结构原型如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct rt_i2c_msg
{
rt_uint16_t addr; /* 从机地址*/
rt_uint16_t flags; /* 读、写标志等*/
rt_uint16_t len; /* 读写数据字节数*/
rt_uint8_t *buf; /* 读写数据缓冲区指针 */
}
  • 从机地址addr:支持7 位和10 位二进制地址,需查看不同设备的数据手册。
  • 标志flags 可取值为以下宏定义,根据需要可以与其他宏使用位运算“|” 组合起来使用。 !!! note “注意事项” RT-Thread I2C 设备接口使用的从机地址均不包含读写位,读写位控制需修改标志flags。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define RT_I2C_WR 0x0000 /* 写标志*/
#define RT_I2C_RD (1u << 0) /* 读标志*/
#define RT_I2C_ADDR_10BIT (1u << 2) /* 10 位地址模式*/
#define RT_I2C_NO_START (1u << 4) /* 无开始条件*/
#define RT_I2C_IGNORE_NACK (1u << 5) /* 忽视NACK */
#define RT_I2C_NO_READ_ACK (1u << 6) /* 读的时候不发送ACK */

使用示例如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define AHT10_I2C_BUS_NAME "i2c1" /* 传感器连接的I2C总线设备名称*/
#define AHT10_ADDR 0x38 /* 从机地址*/

struct rt_i2c_bus_device *i2c_bus; /* I2C总线设备句柄*/

/* 查找I2C总线设备, 获取I2C总线设备句柄*/
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);

/* 读传感器寄存器数据*/
static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t
*buf)
{
	struct rt_i2c_msg msgs;
	msgs.addr = AHT10_ADDR; /* 从机地址*/
	msgs.flags = RT_I2C_RD; /* 读标志*/
	msgs.buf = buf; /* 读写数据缓冲区指针 */
	msgs.len = len; /* 读写数据字节数*/
	/* 调用I2C设备接口传输数据*/
	if (rt_i2c_transfer(bus, &msgs, 1) == 1)
	{
		return RT_EOK;
	}
	else
	{
		return -RT_ERROR;
	}
}

七、I2C 总线设备使用示例

I2C 设备的具体使用方式可以参考如下示例代码,示例代码的主要步骤如下:

这两个函数分别调用了rt_i2c_transfer() 传输数据。读取温湿度信息的函数read_temp_humi() 则是调用这两个函数完成功能。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
* 程序清单: 这是一个I2C 设备使用例程
* 例程导出了i2c_aht10_sample 命令到控制终端
* 命令调用格式: i2c_aht10_sample i2c1
* 命令解释: 命令第二个参数是要使用的I2C总线设备名称, 为空则使用默认的I2C总线设备
* 程序功能: 通过I2C 设备读取温湿度传感器aht10 的温湿度数据并打印
*/
#include <rtthread.h>
#include <rtdevice.h>

#define AHT10_I2C_BUS_NAME "i2c1" /* 传感器连接的I2C总线设备名称*/
#define AHT10_ADDR 0x38 /* 从机地址*/
#define AHT10_CALIBRATION_CMD 0xE1 /* 校准命令*/
#define AHT10_NORMAL_CMD 0xA8 /* 一般命令*/
#define AHT10_GET_DATA 0xAC /* 获取数据命令*/

static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄*/
static rt_bool_t initialized = RT_FALSE; /* 传感器初始化状态*/

/* 写传感器寄存器*/
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t*data)
{
	rt_uint8_t buf[3];
	struct rt_i2c_msg msgs;
	buf[0] = reg; //cmd
	buf[1] = data[0];
	buf[2] = data[1];
	msgs.addr = AHT10_ADDR;
	msgs.flags = RT_I2C_WR;
	msgs.buf = buf;
	msgs.len = 3;
	
	/* 调用I2C设备接口传输数据*/
	if (rt_i2c_transfer(bus, &msgs, 1) == 1)
	{
		return RT_EOK;
	}
	else
	{
		return -RT_ERROR;
	}
}

/* 读传感器寄存器数据*/
static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t*buf)
{
	struct rt_i2c_msg msgs;
	msgs.addr = AHT10_ADDR;
	msgs.flags = RT_I2C_RD;
	msgs.buf = buf;
	msgs.len = len;

	/* 调用I2C设备接口传输数据*/
	if (rt_i2c_transfer(bus, &msgs, 1) == 1)
	{
		return RT_EOK;
	}
	else
	{
		return -RT_ERROR;
	}
}

static void read_temp_humi(float *cur_temp, float *cur_humi)
{
	rt_uint8_t temp[6];
	write_reg(i2c_bus, AHT10_GET_DATA, 0); /* 发送命令*/
	rt_thread_mdelay(400);
	read_regs(i2c_bus, 6, temp); /* 获取传感器数据*/
	/* 湿度数据转换*/
	*cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1<< 20);
	/* 温度数据转换*/
	*cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20)- 50;
}

static void aht10_init(const char *name)
{
	rt_uint8_t temp[2] = {0, 0};
	/* 查找I2C总线设备, 获取I2C总线设备句柄*/
	i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
	if (i2c_bus == RT_NULL)
	{
		rt_kprintf("can't find %s device!\n", name);
	}
	else
	{
		write_reg(i2c_bus, AHT10_NORMAL_CMD, temp);
		rt_thread_mdelay(400);
		temp[0] = 0x08;
		temp[1] = 0x00;
		write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp);
		rt_thread_mdelay(400);
		initialized = RT_TRUE;
	}
}

static void i2c_aht10_sample(int argc, char *argv[])
{
	float humidity, temperature;
	char name[RT_NAME_MAX];
	humidity = 0.0;
	temperature = 0.0;
	if (argc == 2)
	{
		rt_strncpy(name, argv[1], RT_NAME_MAX);
	}
	else
	{
		rt_strncpy(name, AHT10_I2C_BUS_NAME, RT_NAME_MAX);
	}
	if (!initialized)
	{
		/* 传感器初始化*/
		aht10_init(name);
	}
	if (initialized)
	{
		/* 读取温湿度数据*/
		read_temp_humi(&temperature, &humidity);
		rt_kprintf("read aht10 sensor humidity : %d.%d %%\n", (int)humidity, (int)
		(humidity * 10) % 10);
		if( temperature >= 0 )
		{
			rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature,
			(int)(temperature * 10) % 10);
		}
		else
		{
			rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature,
			(int)(-temperature * 10) % 10);
		}
	}
	else
	{
		rt_kprintf("initialize sensor failed!\n");
	}
}
/* 导出到msh 命令列表中*/
MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample);

参考资料:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
RT-Thread Nano如何适配I2C设备API,并在RT-Thread Nano使用软件包
本文介绍了如何在 RT-Thread Studio 上使用 RT-Thread Nano,并基于 BearPI-IOT STM32L431RCT6 的基础工程进行讲解如何使用 I2C 设备接口及相关软件包使用。
Rice加饭
2022/05/10
9970
RT-Thread Nano如何适配I2C设备API,并在RT-Thread Nano使用软件包
《rt-thread驱动框架分析》-i2c驱动
简要 上一篇分析了RTT的PIN驱动,得到了很多网友的认可,很开心。很多人跟我反映写一些usb,wlan等框架,这个一步一步来,从浅到深。 这一篇文章我们来分析rt-thread的I2C设备驱动框架,I2C也是我们经常使用到总线。 I2C驱动框架我准备基于我的开源硬件《GND studio 开发板》来做实验。通过硬件I2C和软件I2C分别来驱动一个OLED。 《rt-thread驱动框架分析》专辑回顾: 《rt-thread驱动框架分析》-pin驱动 驱动分析 I2C设备驱动框架图: 我们先RT-Threa
Rice加饭
2022/05/10
1.8K0
《rt-thread驱动框架分析》-i2c驱动
RT-Thread I2C总线设备学习笔记
I2C的基本原理之前在公众号就有相应的文章了,很早之前发的,接下来我们来学习RT-Thread I2C总线设备的使用!这是RTT官方设计的一个软件框架,学习一个新东西,还是一样,我个人主张带着需求去学习,而不是漫无目的的去学,有了需求驱动,并且是一个努力付出就可以拥有的成果,那么这还不容易嘛!
杨源鑫
2020/05/21
1.7K0
RT-Thread实战笔记|TCS34725 RGB 颜色识别传感器详解
RT-Thread 是一个集实时操作系统(RTOS)内核、中间件组件和开发者社区于一体的技术平台,组件完整丰富、高度可伸缩、简易开发、超低功耗、高安全性的物联网操作系统。RT-Thread 拥有良好的软件生态,支持市面上所有主流的编译工具如 GCC、Keil、IAR 等,工具链完善、友好,支持各类标准接口,如 POSIX、CMSIS、C++应用环境、Javascript 执行环境等,方便开发者移植各类应用程序。商用支持所有主流MCU架构,如 ARM Cortex-M/R/A, MIPS, X86, Xtensa, C-Sky, RISC-V,几乎支持市场上所有主流的 MCU 和 Wi-Fi 芯片。
用户8913398
2021/08/13
1.6K0
RT-Thread实战笔记|TCS34725 RGB 颜色识别传感器详解
RT-Thread实战笔记|MPU6050使用详解及DMP姿态解算
小伙伴们大家好,好久不更新RT-Thread实战笔记啦,今天来搞一搞MPU6050,话不多说,淦!
用户8913398
2021/12/18
4.1K0
RT-Thread实战笔记|MPU6050使用详解及DMP姿态解算
RT-Thread实战笔记-小白一看就会的平衡车DIY教程(附源码)
小伙伴们,停更很久的RT-Thread实战笔记来啦,本章节教大家如何打造一个属于自己的平衡车,废话不多说,来吧,淦!!!
用户8913398
2022/11/16
8780
RT-Thread实战笔记-小白一看就会的平衡车DIY教程(附源码)
《rt-thread驱动框架分析》-touch驱动
简介 rt-smart相关文章 《rt-smart的第一个应用程序,imx6ull用户态点灯》 《rt-smart用户态通过IPC通信玩转传感器数据》 rt-thread驱动相关文章 《rt-thread驱动框架分析》-pin驱动 《rt-thread驱动框架分析》-i2c驱动 有了LCD之后,那必然要有触摸,没触摸的屏幕感觉少了灵魂。 TouchIC没有对应软件包(重新造了一个软件包GT911,目前已经PR到RTT的软件包仓库了,欢迎使用),下面讲解的是我个人的做法,不对的地方,请指出。。。。 Touch
Rice加饭
2022/05/10
6401
《rt-thread驱动框架分析》-touch驱动
鸿蒙之获取温湿度
HarmonyOS轻量和小型系统适用于内存较小的IOT设备。通过本文,开发者可以快速熟悉HarmonyOS轻量和小型系统的环境搭建、编译、烧录、调测以及运行“Hello World”等。 轻量和小型系统的开发有以下两种方法: 用Windows环境进行开发和烧录,使用Linux环境进行编译。 统一使用Linux环境进行开发、编译和烧录。
跋扈洋
2022/01/23
6460
Linux应用开发【第十二章】I2C编程应用开发
​ I2C(Inter-Integrated Circuit BUS)是I2C BUS简称,中文为集成电路总线,是目前应用最广泛的总线之一。和IMX6ULL有些相关的是,刚好该总线是NXP前身的PHILIPS设计。
韦东山
2021/12/15
4K0
Linux应用开发【第十二章】I2C编程应用开发
I2C 总线协议
1.I2C协议 2条双向串行线,一条数据线SDA,一条时钟线SCL。 SDA传输数据是大端传输,每次传输8bit,即一字节。 支持多主控(multimastering),任何时间点只能有一个主控。 总线上每个设备都有自己的一个addr,共7个bit,广播地址全0. 系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。 1.1 I2C位传输 数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit; 若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲) 数据改变:SCL为低电平时,SDA线才能改变传输的bit 1.2 I2C开始和结束信号 开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。 结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。 1.3 I2C应答信号 Master每发送完8bit数据后等待Slave的ACK。 即在第9个clock,若从IC发ACK,SDA会被拉低。 若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示: 1.4 I2C写流程 写寄存器的标准流程为: 1. Master发起START 2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK 3. Slave发送ACK 4. Master发送reg addr(8bit),等待ACK 5. Slave发送ACK 6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK 7. Slave发送ACK 8. 第6步和第7步可以重复多次,即顺序写多个寄存器 9. Master发起STOP 写一个寄存器 写多个寄存器 1.5 I2C读流程 读寄存器的标准流程为: 1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK 2. Slave发送ACK 3. Master发送reg addr(8bit),等待ACK 4. Slave发送ACK 5. Master发起START 6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK 7. Slave发送ACK 8. Slave发送data(8bit),即寄存器里的值 9. Master发送ACK 10. 第8步和第9步可以重复多次,即顺序读多个寄存器 读一个寄存器 读多个寄存器 2. PowerPC的I2C实现
RainMark
2019/09/10
1.6K0
STM32通信模拟 I2C
I²C(Inter-Integrated Circuit),常读作“I方C”,它是一种多主从架构串行通信总线。在1980年由飞利浦公司设计,用于让主板、嵌入式系统或手机连接低速周边设备。如今在嵌入式领域是非常常见通信协议,常用于MPU/MCU与外部设备连接通信、数据传输。
韦东山
2022/05/09
1.1K0
STM32通信模拟 I2C
Linux的I2C驱动框架分析
总线代表着同类设备需要共同遵守的工作时序,不同的总线对于物理电平的要求是不一样的,对于每个比特的电平维持宽度也是不一样,而总线上传递的命令也会有自己的格式约束。如I2C总线、USB总线、PCI总线等等。以I2C总线为例,在同一组I2C总线上连接着不同的I2C设备。
bigmagic
2020/03/17
5.2K0
RT-Thread ADC设备学习笔记
上一节我们学习了RTT的PIN设备的使用,从PIN设备的例程再一次体会到RTT编程的灵活和简单,最重要的是让开发者专注于应用开发,文章链接:
杨源鑫
2020/05/21
1.7K0
RT-Thread实战笔记|LD3320非限定词条语音控制器使用详解
【Rt-thread平台使用LD3320语音识别控制器-哔哩哔哩】https://b23.tv/5m9OXt
用户8913398
2021/09/10
1.4K0
I2C spec 总结
速度由 SCL 决定,不同模式对上升沿的要求不一样,上升沿斜率受上拉电阻和等效电容影响。
Jasonangel
2022/10/25
1.6K0
I2C spec  总结
第019课 I2C协议详解及裸机程序分析
I2C在硬件上的接法如下(图19-1)所示,主控芯片引出两条线SCL,SDA线,在一条I2C总线上可以接很多I2C设备,我们还会放一个上拉电阻(放一个上拉电阻的原因以后我们再说)。
韦东山
2020/09/30
1.6K0
第019课 I2C协议详解及裸机程序分析
一文看懂I2C协议
据非官方统计,90%电子行业的公众号都介绍过3种串行通讯协议:UART、SPI和I2C。这3种串行协议也是电子开发行业最常用的协议。前面介绍了串口通讯协议及其FPGA实现,SPI协议。本篇文章介绍I2C通讯协议及其FPGA实测波形。
单片机点灯小能手
2021/04/02
2K0
基于RT-Thread Studio 和小熊派 实现智慧农业
摘要:如何从零开发一个“智慧农业”案例?小伙伴们有福了,孙教授手把手的带大家基于小熊派+RT-Thread开发一个智慧农业案例。
杨源鑫
2021/07/07
1.6K0
基于RT-Thread Studio 和小熊派 实现智慧农业
树莓派I2C接口技术及Python SMBus串行I2C EEPROM应用编程
文章目录 一、I2C接口技术 1.I2C总线系统组成 2.I2C总线的状态及信号 3.I2C总线基本操作 4.启动和停止条件 5.I2C总线数据传输格式 二、I2C总线上拉电阻的估算与选取 三、树莓派与AT24C02接口实验电路及Python SMBus串行I2C EEPROM应用编程 1.启动RPi串行I2C接口及安装Python SMBus库 2. 树莓派与AT24C02 EEPROM接口实验电路 3. Python SMBus库函数介绍 4. 使用I2C Tools及Python SMBus读写AT24C02 EEPROM 一、I2C接口技术 I2C接口是嵌入式系统中常用的网络接口之一,它采用串行通信方式将MCU/传感器连接到系统总线,通过主机/从机的方式协调工作。 I2C/IIC(Inter-Integrated Circuit)总线是由PHILIPS公司于1982年针对MCU/传感器等应用需求而研制的一种两线式串行总线,用于连接MCU及传感器等设备。 I2C总线的主要特点如下: (1)I2C总线最主要的优点是其简单性和有效性。 (2)由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。 (3)I2C总线的长度可高达25英尺(约7.6m),并且能够以标准模式100Kbps的传输速率支持40个组件。新一代I2C总线还支持高速模式400Kbps传输。 (4)I2C总线的另一个优点是支持多主控(multi-mastering), 其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号传输和时钟频率。当然,在任何时间点上只能有一个主控。 1. I2C总线系统组成 I2C总线协议包含两层协议:物理层和数据链路层。 在物理层,I2C总线仅使用了两条信号线:一个是串行数据线SDA (Serial DAta line),它用于数据的发送和接收;另一个是串行时钟线SCL (Serial Clock Line)构成的串行总线,它用于指示何时数据线上是有效数据,即数据同步。MCU与被控IC之间、IC与IC之间进行双向传送,I2C标准模式最大传送速率为100kbps,I2C快速模式最大传输速率为400kbps。 在数据链路层,每个连接到I2C总线上的设备都有唯一的地址,设备的地址由系统设计者决定。在信息的传输过程中,I2C总线上并接的每一设备既是主设备(或从设备)又是发送器(或接收器),这取决于它所要完成的功能。 由I2C总线所构成的系统可以有多个I2C节点设备,并且可以是多主系统,任何一个设备都可以为主I2C;但是任一时刻只能有一个主I2C设备,I2C具有总线仲裁功能,以保证系统正确运行。主I2C设备发出时钟信号、地址信号和控制信号,选择通信的从I2C设备并控制收发。I2C总线要求:(1)各个节点设备必须具有I2C接口功能;(2)各个节点设备必须共地;(3)两根信号线必须接上拉电阻Rp。如图1所示。  图1 多I2C设备接口示意图 2. I2C总线的状态及信号 (1)空闲状态 SCL和SDA均处于高电平状态,即为总线空闲状态(空闲状态为何是高电平的道理很简单,因为它们都接上拉电阻)。 (2)占有总线和释放总线 若想让器件使用总线应当先占有它,占有总线的主控器向SCL线发出时钟信号。数据传送完成后应当及时释放总线,即解除对总线的控制(或占有),使其恢复成空闲状态。 (3)启动信号[S] 启动信号由主控器产生。在SCL信号为高时,SDA产生一个由高变低的电平变化,产生启动信号。 (4)结束/停止信号[P] 当SCL线高电平时,主控器在SDA线上产生一个由低电平向高电平跳变,产生停止信号。启动信号和停止信号的产生见图2所示。  图2 启动信号和停止信号的产生 (5)应答/响应信号[A/NA] 应答信号是对字节数据传输的确认。应答信号占1位,数据接收者接收1字节数据后,应向数据发出者发送一个应答信号。对应于SCL第9个应答时钟脉冲,若SDA线仍保持高电平,则为非应答信号(NA/ACK)。低电平为应答,继续发送;高电平为非应答,结束发送。 (6)控制位信号[R/nW] 控制位信号占1位,IIC主机发出的读写控制信号,高为读、低为写(对IIC主机而言)。控制位(或方向位)在寻址字节中给出。 (7)地址信号 地址信号为从机地址,占7位,称之为“寻址字节”(见表1)。 表1 寻址字节  下面对表1中的各字段进行说明。 器件地址(DA3-DA0):DA3-DA0是I2C总线接口器件固有的地址编码,由器件生产厂家给定,如AT24C××I2C总线EEPROM器件的地址为1010等。 引脚地址(A2、A1、A0):引脚地址由I2C总线接口器件的地址引脚A2、A1、A0的高低来确定,接高电平者为1,接地者为0。 读写控制位/方向位(R/n W):R/nW为1表示主机读,R/nW为0表示主机
用户7886150
2020/12/30
1.3K0
rt-smart用户态通过IPC通信玩转传感器数据
简介 首先纠正一下上一篇文章中,在我的仓库中,1月11日的代码会出现系统崩溃。原因在于我的驱动中内存物理地址映射到虚拟地址的操作有问题,我已经把这个bug解决了,如果有兴趣,欢迎拉取最新的代码。 这一篇来介绍我在rt-smart的第二个应用。这个应用将加入rt-smart与rt-thread区别之处--进程间的通信。 功能主要是在用户态读取传感器数据,传感器是100ASK_imx6ull板载的ap3216c,它是采用I2C总线进行通信。 为啥这次会先对接I2C呢?因为接下来想把屏幕在rt-smart跑起来,
Rice加饭
2022/05/10
3070
rt-smart用户态通过IPC通信玩转传感器数据
推荐阅读
相关推荐
RT-Thread Nano如何适配I2C设备API,并在RT-Thread Nano使用软件包
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验