I2C是一种多向控制总线,它是由PHILIPS公司在二十世纪八十年代初设计出来的,利用该总线可实现多主机系统所需的裁决和高低速设备同步等功能,是一种高性能的串行总线。I2C总线只用两根双向传输线就可以将128个不同的设备互连到一起。这两根线一根是时钟线SCL,一根是数据线SDA。外部硬件只需要接两个上拉电阻,每根线上一个。所有连接到总线上的设备都有自己的地址。

I2C总线上传输的数据是通过在时钟线(SCL)高电平期间所对应的数据线(SDA)上的电平来判别的。在SCL线拉高期间对应到SDA线的电平,如果为高则这位数据为1,反之则为0。只有在SCL线为低电平期间,SDA线才可以更新下一位数据。

除了传送的数据以外,I2C总线在每一帧数据传送之前,还会有一个启动信号,以通知从机准备接收数据。在数据传送结束之后,也会有一个停止信号,以通知从机数据传输结束。在SCL为高电平期间,若对应的SDA线上有一个由高变低的电平下降沿,表示这是一个启动信号。同样,在SCL为高电平期间,若对应的SDA线上有一个由低变高的电平上升沿,表示这是一个停止信号。当已经有一个启动信号之后,在没有停止信号出现之前若再次出现启动信号,则表示该信号是一个重新启动信号,它主要用于在主机不放弃总线控制的情况下启动新的传送。

在启动信号之后紧接着的是地址帧,所有的地址包均为9位,包括7位地址位、1位READ/WRITE控制位(即方向位,表明是主机写从机还是从机写主机)与1位应答位。如果READ/WRITE为1,则执行读(从机写主机)操作;否则执行写(主机写从机)操作。从机被寻址后,必须在第九个SCL(ACK)周期通过拉低SDA作出应答。

地址帧发送后,紧接着就要发送数据帧。所有在I2C总线上传送的数据包长度为9位,包括8位数据位及1位应答位。在数据传送中,主机产生时钟及START与STOP状态,接收器响应接收。应答是由从机在第9个SCL周期拉低SDA实现的,如果接收器在第9个SCL周期使SDA为高,则发出的是NACK信号。NACK信号是接收器在完成了最后数据的接收,或者由于某些原因无法接收更多数据时,才在收到最后字节后发出去通知发送器的。

I2C总线上一个完整的传输过程将包含地址包和数据包。发送主要由START状态、SLA+R/W、至少一个数据包及STOP状态组成。一个典型的数据传送的过程可用下图来描述。

LPC824在硬件上完整支持I2C接口规范,并配有4个I2C接口(具体引脚取决于开关矩阵SWM的配置),它们具有以下特性。

(1)独立的主机、从机和监控器功能。
(2)支持多主机和带从机功能的多主机。
(3)硬件支持多个I2C从机地址。
(4)可以通过一个位屏蔽或一个地址范围选择性验证一个从机地址,从而响应多个I2C总线地址。
(5)通过软件辅助支持10位寻址。
(6)支持SMBus。
(7)支持I2C总线规格达到超快速模式(高达1兆赫)。

LPC824提供一个基于片上ROM的I2C API,以配置和操作I2C接口。

下图是I2C接口的功能框图。

在LPC824中,一共有四组I2C接口,分别为I2C0/1/2/3。I2C0组接口引脚是固定的(PIO0_10和PIO0_11),通过开关矩阵使能,支持超快速模式。I2C1/2/3这三组接口的引脚都是可移动的,可被分配至任何引脚。除PIO0_10和PIO0_11引脚以外,其他组的引脚不是开漏引脚,也不支持超快速模式,所有的引脚均支持400 kHz比特率。下表给出了这些引脚各自的SWM配置寄存器。

从上表中可以看出,I2C0接口的引脚是固定的,通过PINENABLE0寄存器来使能(详见“开关矩阵SWM”一章)。其他三组I2C接口的共8个引脚可以被分配到任意一个物理引脚上,涉及到PINASSIGN9、PINASSIGN10共2个配置寄存器,接下来就分别给出这两个寄存的具体结构。

下表给出的是引脚分配寄存器PINASSIGN9的全部位结构,其字节地址为0x4000C024。

(1)第0到7位为SCT_OUT5功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(2)第8到15位为I2C1_SDA功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(3)第16到23位为I2C1_SCL功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(4)第24到31位为I2C2_SDA功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。

下表给出的是引脚分配寄存器PINASSIGN10的全部位结构,其字节地址为0x4000C028。

(1)第0到7位为I2C2_SCL功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(2)第8到15位为I2C3_SDA功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(3)第16到23位为I2C3_SCL功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。
(4)第24到31位为ADC_PINTRIG0功能分配引脚,可选范围从PIO0_0到PIO0_28一共29根引脚,默认为未分配状态。

下表给出了I2C接口用到的全部寄存器描述。

由于LPC824的I2C接口功能很完善,所以涉及到的寄存器较多,它一共使用了18个寄存器来进行控制,应用上有些复杂。下面给出了上述寄存器对应的结构体定义。

typedef struct {
__IO uint32_t CFG;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR;
__IO uint32_t TIMEOUT;
__IO uint32_t CLKDIV;
__I uint32_t INTSTAT;
__I uint32_t RESERVED0;
__IO uint32_t MSTCTL;
__IO uint32_t MSTTIME;
__IO uint32_t MSTDAT;
__I uint32_t RESERVED1[5];
__IO uint32_t SLVCTL;
__IO uint32_t SLVDAT;
__IO uint32_t SLVADR0;
__IO uint32_t SLVADR1;
__IO uint32_t SLVADR2;
__IO uint32_t SLVADR3;
__IO uint32_t SLVQUAL0;
__I uint32_t RESERVED2[9];
__I uint32_t MONRXDAT;
} LPC_I2C0_Type;

为了将4个I2C的基址指针强制转换为上述结构体,还要加上下面的定义。

#define LPC_I2C0_BASE 0x40050000UL
#define LPC_I2C1_BASE 0x40054000UL
#define LPC_I2C2_BASE 0x40070000UL
#define LPC_I2C3_BASE 0x40074000UL
#define LPC_I2C0 ((LPC_I2C0_Type *) LPC_I2C0_BASE)
#define LPC_I2C1 ((LPC_I2C0_Type *) LPC_I2C1_BASE)
#define LPC_I2C2 ((LPC_I2C0_Type *) LPC_I2C2_BASE)
#define LPC_I2C3 ((LPC_I2C0_Type *) LPC_I2C3_BASE)

I2C接口涉及到的寄存器较多,后面会对它们进行具体分析。

--待续--

I2C接口的更多相关文章

  1. (6)s3c2440用I2C接口访问EEPROM

    在前面阅读理解了I2C的官方协议文档后,就拿s3c2440和EEPROM来验证一下. 本来是想用s3c2440的SDA和SCL管脚复用为GPIO来模拟的,但在没有示波器的情况下搞了一周,怎么都出不来, ...

  2. 解决STM32 I2C接口死锁在BUSY状态的方法讨论

    关于STM32的I2C接口死锁在BUSY状态无法恢复的现象,网上已有很多讨论,看早几年比较老的贴子,有人提到复位MCU也无法恢复.只有断电才行的状况,那可是相当严重的问题.类似复位也无法恢复的情况是存 ...

  3. JZ2440 裸机驱动 第12章 I2C接口

    本章目标: 了解I2C总线协议: 掌握S3C2410/S3C2440中I2C接口的使用方法: 12.1 I2C总线协议及硬件介绍 12.1.1 I2C总线协议 1 I2C总线的概念 2 I2C总线的信 ...

  4. 树莓派配置RTC时钟(DS3231,I2C接口)

    1.购买基于DS3231的RTC时钟模块,并且支持3.3V的那种 2.配置树莓派 a.打开树莓派的i2c接口 sudo raspi-config -->Interfacing Options - ...

  5. linux 标准i2c接口(一)

    一:I2C设备操作方式: 1.  应用程序操作法:i2c的设备的驱动可以直接利用linux内核提供的i2c-dev.c文件提供的ioctl函数接口在应用层实现对i2c设备的读写,但是在应用层使用ioc ...

  6. EEPROM的操作---SPI接口和I2C接口

    参考:http://blog.csdn.net/yuanlulu/article/details/6163106 ROM最初不能编程,出厂什么内容就永远什么内容,不灵活.后来出现了PROM,可以自己写 ...

  7. 为 MaixPy 加入软 I2C 接口(移植 MicroPython 的 I2C)

    起因 本文的重心为讲解如何为一款芯片移植和实现 micropython 的通用组件,但会顺带解释不同芯片的工作方式和特性. 国际惯例,先有起因,再谈问题的解决,所以记得上次总结的 关于 K210 Ma ...

  8. C51 I2C接口驱动,IO口模拟I2C(主+从)

    Master.asm ;/*------------------------------------------------------------------*/ ;/* --- STC MCU I ...

  9. i2c接口笔记

    一. i2c基础知识 1. NACK信号:当在第9个时钟脉冲的时候SDA线保持高电平,就被定义为NACK信号.Master要么产生STOP条件来放弃这次传输,或者重复START条件来发起一个新的开始. ...

  10. 协议类接口 - I2C

    一.12c总线概述 I2C( Inter-Integrated Circuit,又称IIC)总线是一种串行总线,用 于连接微控制器及其外围设备,硬件图非常简单:一条串行数据线(SDA),一条串行时钟线 ...

随机推荐

  1. 如何使用 IdGen 生成 UID

    在分布式系统中,雪花 ID 是一种常用的唯一 ID 生成算法.它通过结合时间戳.机器码和自增序列来生成 64 位整数 ID,可以保证 ID 的唯一性和顺序性. 在.Net 项目中,我们可以使用 IdG ...

  2. 为什么NoSQL数据库这么受欢迎?

    大数据时代,NoSQL数据库是企业构建数据能力的核心工具之一.近期,在2022腾讯全球数字生态大会NoSQL数据库专场上,腾讯云发布了多项NoSQL产品能力升级,并重点讲解了其背后的自研技术要点及实现 ...

  3. 回顾Vue计算属性VS其他语法有感

    回顾Vue计算属性VS其他语法有感 重新回顾官方教程中的到计算属性和侦听器,发觉获益良多,主要就是两点: 计算属性和其他语法的比较 计算属性.侦听属性.方法.模板变量的使用 计算属性和其他语法的比较 ...

  4. WCF 服务容器化的一些问题

    背景 目前项目当中存有 .NET Framework 和 .NET Core 两种类型的项目,但是都需要进行容器化将其分别部署在 Windows 集群和 Linux 集群当中.在 WCF 进行容器化的 ...

  5. .Net 6 使用 Consul 实现服务注册与发现 看这篇就够了

    前言 在这几年的工作中,也经历过几个微服务项目,大多数都上了k8s,基本上都看不到Consul的身影,所以在工作之余折腾了下Consul,作为个人来讲还是得学习下,所以也就顺便通过文章来记录下学习过程 ...

  6. 遗传算法 Genetic Algorithms

    遗传算法 Genetic Algorithms 遗传算法是一种"adaptive heuristic search algorithm"(自适应启发式搜索算法),虽不明.但觉厉.其 ...

  7. angular2-qrcode 引用报错 error NG8001: 'qr-code' is not a known element:

    error NG8001: 'qr-code' is not a known element: 解决方案 假如你的组件模块叫做a-demo.module,你的组件叫做print.component.t ...

  8. 如何将WebAssembly优化到2MB?

    Blazor WebAssembly加载优化方案 对于Blazor WebAssembly加载方案的优化是针对于WebAssembly首次加载,由于BlazorWebAssembly是在首次加载的时候 ...

  9. 除了Navicat和DBeaver,还有没有免费又好用的数据库管理/SQL工具推荐

    很多国内SQL学习者和开发者对Navicat.DBeaver等国外数据库管理工具已经很熟悉了.但是,有没有比他们更适合SQL开发者的数据库管理/SQL工具呢?这里,笔者结合自己的调研来聊一下. 笔者做 ...

  10. Java 进阶P-4.2+P-4.3

    继承 什么是继承:通俗易懂就好像是你继承你了爸的财产,其中你是子类,你爸是父类继承在Java中被称为面向对象的三大的特征,其中他表示的是,从已有的类中派生出新的类,新的类拥有了父类中属性和方法(pri ...