I2C 应用编程

1. I2C 框架结构

1.1 I2C 硬件框架

I2C 总线拓扑图

在一个芯片 (SoC) 内部,有一个或多个 I2C 控制器
在一个 I2C 控制器上,可以连接一个或多个 I2C 设备
I2C 总线只需要 2 条线:时钟线 SCL 数据线 SDA
I2C 总线的 SCL SDA 线上,都有上拉电阻

1.2 I2C 软件框架

I2C 接口的存储设备 AT24C02 为例:

APP
        ◼ 提出要求:把字符串 "www.100ask.net" 写入 AT24C02 地址 16 开始的地方
        ◼ 它是大爷,不关心底层实现的细节
        ◼ 它只需要调用设备驱动程序提供的接口
AT24C02 驱动:
        ◼ 它知道 AT24C02 要求的地址、数据格式
        ◼ 它知道发出什么信号才能让 AT24C02 执行擦除、烧写工作
        ◼ 它知道怎么判断数据是否烧写成功
        ◼ 它构造好一系列的数据,发给 I2C 控制器
I2C 控制器驱动
        ◼ 它根据 I2C 协议发出各类信号: I2C 设备地址、 I2C 存储地址、数据
        ◼ 它根据 I2C 协议判断

1.3 我们讲什么

1.3.1 对于 Linux I2C 结构

从上到下:
先讲 I2C 协议
APP 可以通过两类驱动程序访问设备
        ◼ I2C 设备自己的驱动程序
        ◼ 内核自带的 i2c-dev.c 驱动程序,它是 i2c 控制器驱动程序暴露给用户空间的驱动程序(i2c-dev.c)
I2C Device Driver
        ◼ I2C 设备自己的驱动程序
        ◼ 内核自带的 i2c-dev.c 驱动程序,它是 i2c 控制器驱动程序暴露给用户空间的驱动程序(i2c-dev.c)
I2C Controller Driver
        ◼ 芯片 I2C 控制器的驱动程序 ( 称为 adapter)
        ◼ 使用 GPIO 模拟的 I2C 控制器驱动程序 (i2c-gpio.c)

1.3.2 对于单片机/裸机

从上到下:
先讲 I2C 协议
APP
I2C Device Driver
I2C Controller Driver( 也被称为 adapter)

2 I2C 协议

2.1 硬件连接

        I2C 在硬件上的接法如下所示,主控芯片引出两条线 SCL,SDA 线,在一条 I2C 总线上可以接很多 I2C 设备,我们还会放一个上拉电阻(放一个上拉电阻的原因以后我们再说)。

2.2 传输数据类比

        怎么通过 I2C 传输数据,我们需要把数据从主设备发送到从设备上去,也需要把数据从从设备传送到主设备上去,数据涉及到双向传输。
        举个例子:         

        体育老师:可以把球发给学生,也可以把球从学生中接过来。
发球:
        ◼ 老师:开始了 (start)
        ◼ 老师: A !我要发球给你! ( 地址 / 方向 )
        ◼ 学生 A :到! ( 回应 )
        ◼ 老师把球发出去(传输)
        ◼ A 收到球之后,应该告诉老师一声(回应)
        ◼ 老师:结束(停止)
接球:
        ◼ 老师:开始了 (start)
        ◼ 老师: B !把球发给我! ( 地址 / 方向 )
        ◼ 学生 B :到!
        ◼ B 把球发给老师(传输)
        ◼ 老师收到球之后,给 B 说一声,表示收到球了(回应)
        ◼ 老师:结束(停止)
我们就使用这个简单的例子,来解释一下 IIC 的传输协议:
老师说开始了,表示开始信号 (start)
老师提醒某个学生要发球,表示发送地址和方向 (address/read/write)
老师发球 / 接球,表示数据的传输
收到球要回应:回应信号 (ACK)
老师说结束,表示 IIC 传输结束 (P)

2.3 IIC 传输数据的格式

2.3.1 写操作

主芯片要发出一个 start 信号
然后发出一个设备地址 ( 用来确定是往哪一个芯片写数据 ) ,方向 ( / 写, 0 表示写,1 表示读 )
从设备回应 ( 用来确定这个设备是否存在 ) ,然后就可以传输数据
主设备发送一个字节数据给从设备,并等待回应
每传输一字节数据,接收方要有一个回应信号(确定数据是否接受完成 ) ,然后再传输下一个数据。
数据发送完之后,主芯片就会发送一个停止信号。
下图:白色背景表示 " " ,灰色背景表示 " "

2.3.2 读操作

流程如下:
主芯片要发出一个 start 信号
然后发出一个设备地址 ( 用来确定是往哪一个芯片写数据 ) ,方向 ( / 写, 0 表示写,1 表示读 )
从设备回应 ( 用来确定这个设备是否存在 ) ,然后就可以传输数据
从设备发送一个字节数据给主设备,并等待回应
每传输一字节数据,接收方要有一个回应信号(确定数据是否接受完成 ) ,然后再传输下一个数据。
数据发送完之后,主芯片就会发送一个停止信号。
下图:白色背景表示 " " ,灰色背景表示 " "

3 I2C 信号

        I2C 协议中数据传输的单位是字节,也就是 8 位。但是要用到 9 个时钟:前面 8 个时钟用来传输 8 数据,第 9 个时钟用来传输回应信号。传输时,先传输最高位(MSB)
开始信号( S ): SCL 为高电平时, SDA 由 高电平向低电平跳变,开始传送数据。
结束信号( P ): SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。
响应信号 (ACK) :接收器在接收到 8 位数据后,在第 9 个时钟周期,(从设备)拉低 SDA
SDA 上传输的数据必须在 SCL 为高电平期间保持稳定, SDA 上的数据只能在SCL 为低电平期间变化
        I2C 协议信号如下(前半部分数据是发送地址位和方向,后半部分是数据,发送原理一样):

        在 SCL 为高电平时,SDA 拉高,读取到 1;在SCL为高电平时,SDA拉低,读取到0。

4 协议细节

如何在 SDA 上实现双向传输?
        ◼ 主芯片通过一根 SDA 线既可以把数据发给从设备,也可以从 SDA 上读取数据,连接 SDA 线的引脚里面必然有两个引脚(发送引脚 / 接受引脚)。
主、从设备都可以通过 SDA 发送数据,肯定不能同时发送数据,怎么错开时间?在 9 个时钟里:
        ◼ 前 8 个时钟由主设备发送数据的话,第 9 个时钟就由从设备发送数据;
        ◼ 前 8 个时钟由从设备发送数据的话,第 9 个时钟就由主设备发送数据。
双方设备中,某个设备发送数据时,另一方怎样才能不影响 SDA 上的数据?
        ◼ 设备的 SDA 中有一个三极管,使用开极 / 开漏电路 ( 三极管是开极, CMOS 管是开漏,作用一样) ,如下图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/267544.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud面试题——Sentinel

一:什么是Sentinel? Sentinel是一个面向分布式架构的轻量级服务保护框架,实现服务降级、服务熔断、服务限流等功能 二:什么是服务降级? 比如当某个服务繁忙,不能让客户端的请求一直等待,应该立刻返回给客户端一个备…

C# 图解教程 第5版 —— 第18章 泛型

文章目录 18.1 什么是泛型18.2 C# 中的泛型18.3 泛型类18.3.1 声明泛型类18.3.2 创建构造类型18.3.3 创建变量和实例18.3.4 使用泛型的示例18.3.5 比较泛型和非泛型栈 18.4 类型参数的约束18.4.1 Where 子句18.4.2 约束类型和次序 18.5 泛型方法18.5.1 声明泛型方法18.5.2 调用…

Flutter实现自定义二级列表

在Flutter开发中,其实系统已经给我们提供了一个可靠的二级列表展开的API(ExpansionPanelList),我们先看系统的二级列表展开效果,一次只能展开一个,用ExpansionPanelList.radio实现 由此可见,已经…

算法Day29 打印数目

打印数目 Description 小硕有一套字母表arr,其中每个上都刻有一个字母arr[i]。返回小硕可以印出的非空字母序列的数目。 注意:本题中,每个字母只能使用一次。 Input 输入字符串arr 1≤arr.length≤7 Output 输出可打印数目 Sample 代码 imp…

血的教训,BigDecimal踩过的坑

很多人都用过Java的BigDecimal类型,但是很多人都用错了。如果使用不当,可能会造成非常致命的线上问题,因为这涉及到金额等数据的计算精度。 首先说一下,一般对于不需要特别高精度的计算,我们使用double或float类型就可…

docker-compose的介绍与使用

一、docker-compose 常用命令和指令 1. 概要 默认的模板文件是 docker-compose.yml,其中定义的每个服务可以通过 image 指令指定镜像或 build 指令(需要 Dockerfile)来自动构建。 注意如果使用 build 指令,在 Dockerfile 中设置…

7 Linux 内核移植

一、编译 ST 的 Linux 系统 1. 压缩源码 首先先下载 ST 官方源码,之前章节已经下载过了,直接输入以下命令: cd linux/atk-mpl/stm32mp1-openstlinux-5.4-dunfell-mp1-20-06-24/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.31-r0/ 然…

Linux命令——进程管理

进程管理 一、进程基本介绍二、进程相关命令1、ps2、kill、killall3、top4、pstree 总结 博主最近项目上线,操作了linux系统,感觉命令很容易遗忘,因此总结一下,本文记录的是linux中相关的进程管理命令 一、进程基本介绍 linux中…

java的long类型超过9位报错:the literal 987654321000 of type int is out of range

java的long类型超过9位报错 1、报错提示2、报错截图3、解决办法4、参考文章 1、报错提示 the literal 987654321000 of type int is out of range 2、报错截图 3、解决办法 long类型是一种用于表示较大整数的数据类型,范围比int类型更广泛。然而,即使…

系统延时函数的实现

滴答定时器的工作原理 STM32F103的内核时钟由AHB总线时钟(72M)经过8分频得到,即72/89M LOAD的取值范围是0-1677215,也就是VAL最多可以计2^24次。 滴答定时器的寄存器 系统延时函数的配置 当需要计1us(1/100 0000)时,9M的时钟就要计9次&#x…

Blender学习:走路机器人,骨骼绑定

文章目录 建模骨骼创建骨骼绑定 教程地址:八个案例教程带你从0到1入门blender【已完结】 建模 1 做头:新建立方体,Ctrl2细分并应用,进入编辑模式,删除一半点,然后添加镜像修改器,开启范围限制…

界面控件DevExpress WPF导航组件,助力升级应用程序用户体验!(下)

DevExpress WPF的Side Navigation(侧边导航)、TreeView、导航面板组件能帮助开发者在WPF项目中添加Windows样式的资源管理器栏或Outlook NavBar(导航栏),DevExpress WPF NavBar和Accordion控件包含了许多开发人员友好的…