IIC总线协议及应用

  • I2C总线知识
    • I2C总线物理拓扑结构
    • I2C总线特征
    • I2C总线协议
    • 数据有效性
    • 响应
  • I2C总线操作
  • IIC总线应用案例
    • RT1052的LPI2C总线特性及架构
      • 通讯引脚
      • 驱动时钟
    • PCF8563芯片简介
    • 部分代码截取
    • 实测I2C总线通信波形
    • PCF8563模块实物

I2C总线知识

I2C总线物理拓扑结构

I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来 产生I2C总线协议所需要的信号进行数据的传递。在总线空闲状态时,这两根线一般被上面所接的上拉电阻拉高,保持着高电平。

I2C总线特征

I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址(可以从I2C器件的数据手册得知),主从设备之间就通过这 个地址来确定与哪个器件进行通信,在通常的应用中,我们把CPU带I2C总线接口的模块作为主设备,把挂接在总线上的其他设备都作为从设备。
I2C总线上可挂接的设备数量受总线的最大电容400pF 限制,如果所挂接的是相同型号的器件,则还受器件地址位的限制。
I2C总线数据传输速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。一般通过I2C总线接口可编程时钟来实现传输速率的调整,同时也跟所接的上拉电阻的阻值有关。
I2C总线上的主设备与从设备之间以字节(8位)为单位进行双向的数据传输。

标准模式(Standard-mode):速率高达100kbit/s
快速模式(Fast-mode):速率高达400kbit/s
快速模式+(Fast-mode Plus):速率高达1Mbit/s。
高速模式(High-speed mode):速率高达3.4Mbit/s

I2C总线协议

I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生。总线在空闲状态 时,SCL和SDA都保持着高电平,当SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件;当SCL为高而SDA由低到高的跳变,表示产生一个 停止条件。在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备 将释放总线,总线再次处于空闲状态。如图所示:


在了解起始条件和停止条件后,我们再来看看在这个过程中数据的传输是如何进行的。前面我们已经提到过,数据传输以字节为单位。主设备在SCL线上产生每个 时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着从设备将拉低SDA线,回传给主设备一个应答位, 此时才认为一个字节真正的被传输完成。当然,并不是所有的字节传输都必须有一个应答位,比如:当从设备不能再接收主设备发送的数据时,从设备将回传一个否 定应答位。数据传输的过程如图所示:


在前面我们还提到过,I2C总线上的每一个设备都对应一个唯一的地址,主从设备之间的数据传输是建立在地址的基础上,也就是说,主设备在传输有效数据之前 要先指定从设备的地址,地址指定的过程和上面数据传输的过程一样,只不过大多数从设备的地址是7位的,然后协议规定再给地址添加一个最低位用来表示接下来 数据传输的方向,0表示主设备向从设备写数据,1表示主设备向从设备读数据。如图所示:

数据有效性

I2C 使用 SDA 信号线来传输数据,使用 SCL 信号线进行数据同步。见图 21‑6。SDA 数据线在 SCL
的每个时钟周期传输一位数据。传输时,SCL 为高电平的时候 SDA 表示的数据有效,即此时的
SDA 为高电平时表示数据“1”,为低电平时表示数据“0”。当 SCL 为低电平时,SDA 的数据无
效,一般在这个时候 SDA 进行电平切换,为下一次表示数据做好准备。

每次数据传输都以字节为单位,每次传输的字节数原则上不受限制。

响应

I2C 的数据和地址传输都带响应。响应包括“应答 (ACK)”和“非应答 (NACK)”两种信号。作为
数据接收端时,当设备 (无论主从机) 接收到 I2C 传输的一个字节数据或地址后,若希望对方继续
发送数据,则需要向对方发送“应答 (ACK)”信号,发送方会继续发送下一个数据;若接收端希
望结束数据传输,则向对方发送“非应答 (NACK)”信号,发送方接收到该信号后会产生一个停
止信号,结束信号传输。

传输时主机产生时钟,在第 9 个时钟时,数据发送端会释放 SDA 的控制权,由数据接收端控制
SDA,若 SDA 为高电平,表示非应答信号 (NACK),低电平表示应答信号 (ACK)。

I2C总线操作

对I2C总线的操作实际就是主从设备之间的读写操作。大致可分为以下三种操作情况:
第一,主设备往从设备中写数据。数据传输格式如下:

第二,主设备从从设备中读数据。数据传输格式如下:

第三,主设备往从设备中写数据,然后重启起始条件,紧接着从从设备中读取数据;或者是主设备从从设备中读数据,然后重启起始条件,紧接着主设备往从设备中写数据。数据传输格式如下:

说明:第三种操作在单个主设备系统中,重复的开启起始条件机制要比用STOP终止传输后又再次开启总线更有效率。

IIC总线应用案例

RT1052的LPI2C总线特性及架构


RT1052 的 I2C 外设可用作通讯的主机及从机,支持标准模式 100Kbit/s、快速模式 400Kbit/s、高
速模式 3.4Mbit/s 以及超高速模式 5Mbit/s 的传输速率,支持 7 位、10 位设备地址,支持 DMA 数
据传输,并具有数据校验功能。它的 I2C 外设还支持 SMBus2.0 协议,SMBus 协议与 I2C 类似,主
要应用于笔记本电脑的电池管理中。

通讯引脚

I2C 的所有硬件架构都是根据图中右侧 SCL 线和 SDA 线展开的。RT1052 芯片有多个 I2C 外设,
它们的 I2C 通讯信号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引脚,见表 21‑1。
关于外设配对的 GPIO 引脚号,可查阅《IMXRT1050RM》(参考手册),以它为准。

特别地,在标准 I2C 协议之外,LPI2C 还增加了 HREQ、SCLS 及 SDAS 这三个引脚,它们的功能
如下:
HREQ:它用于外部设备向 LPI2C 主机申请发起通讯的请求。LPI2C 工作于主机模式时,可
使能检测 HREQ 用于接收外部的电平信号,接收到有效的电平信号后且 I2C 总线空闲,那
么 LPI2C 会发起 I2C 通讯。
SCLS 和 SDAS:这两个被称为第二时钟和第二数据线。

驱动时钟

整个 I2C 外设,分别由功能时钟(Functional Clock)、外部时钟(Extern Clock)和总线时钟(Bus
Clock)这三部分时钟驱动。
功能时钟:I2C 主设备逻辑电路(Master Logic)由功能时钟驱动。它等价于 LPI2C 根时钟(LPI2C_CLK_ROOT),在时钟树中的描述具体见图 21‑11。它可以使用选择的时钟来源如下:

  1. PLL3 的 8 分频,其中 PLL3 的常规配置为 480MHz,它的 8 分频即为 60MHz。
  2. 外部晶振 OSC 它的常规配置为 24MHz。
    选 择 的 输 入 时 钟 源 经 过 时 钟 控 制 模 块 CCM 的 CSCDR2 寄 存 器 的LPI2C_CLK_PODF 位配置分频,得到 LPI2C_CLK_ROOT。
    LPI2C_CLK_ROOT 输入到 LPI2C 外设内部后,可使用 LPI2C 内部的分频器(Prescaler)进一步分频然后用于驱动生成 SCL 时钟信号,该分频因子通过MCFGR1 寄存器的 PRESCALE 位设置即可。

    • 外部时钟:LPI2C 模块工作于从设备模式时,它的从设备逻辑电路(Slave Logic)直接以外
    部的 SCL 和 SDA 总线作为时钟进行驱动。
    • 总线时钟:这个总线时钟是指 RT1052 内部外设总线(Internal Soc Peripheral Bus)的时钟,
    它仅用于内核访问 LPI2C 外设的控制和配置寄存器(包括 FIFO)。

PCF8563芯片简介

The PCF8563 is a CMOS1 Real-Time Clock (RTC) and calendar optimized for low power
consumption. A programmable clock output, interrupt output, and voltage-low detector are
also provided. All addresses and data are transferred serially via a two-line bidirectional
I2C-bus. Maximum bus speed is 400 kbit/s. The register address is incremented
automatically after each written or read data byte.

Provides year, month, day, weekday, hours, minutes, and seconds based on a
32.768 kHz quartz crystal
 Century flag
Clock operating voltage: 1.0 V to 5.5 V at room temperature
 Low backup current; typical 0.25 uA at VDD = 3.0 V and Tamb = 25 C  400 kHz two-wire I2C-bus interface (at VDD = 1.8 V to 5.5 V)
 Programmable clock output for peripheral devices (32.768 kHz, 1.024 kHz, 32 Hz, and
1 Hz)
 Alarm and timer functions
 Integrated oscillator capacitor
 Internal Power-On Reset (POR)
I2C-bus slave address: read A3h and write A2h
Open-drain interrupt pin








As a consequence of this method, it is very important to make a read or write access in
one go, that is, setting or reading seconds through to years should be made in one single
access. Failing to comply with this method could result in the time becoming corrupted.
As an example, if the time (seconds through to hours) is set in one access and then in a
second access the date is set, it is possible that the time may increment between the two
accesses. A similar problem exists when reading. A roll over may occur between reads
thus giving the minutes from one moment and the hours from the next.
Recommended method for reading the time:
1. Send a START condition and the slave address for write (A2h).
2. Set the address pointer to 2 (VL_seconds) by sending 02h.
3. Send a RESTART condition or STOP followed by START.
4. Send the slave address for read (A3h).
5. Read VL_seconds.
6. Read Minutes.
7. Read Hours.
8. Read Days.
9. Read Weekdays.
10. Read Century_months.
11. Read Years.
12. Send a STOP condition.

部分代码截取

#define EXAMPLE_I2C_MASTER_BASE (LPI2C1_BASE)/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
/* Get frequency of lpi2c clock */
#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))#define LPI2C_MASTER_CLOCK_FREQUENCY LPI2C_CLOCK_FREQUENCY#define EXAMPLE_I2C_MASTER ((LPI2C_Type *)EXAMPLE_I2C_MASTER_BASE)#define LPI2C_MASTER_SLAVE_ADDR_7BIT 0x51U //PCF8563 7bit地址
#define LPI2C_BAUDRATE 100000U
#define LPI2C_DATA_LENGTH 9U
uint8_t g_master_txBuff[LPI2C_DATA_LENGTH];
uint8_t g_master_rxBuff[LPI2C_DATA_LENGTH];

设定RTC时间

    /** masterConfig.debugEnable = false;* masterConfig.ignoreAck = false;* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;* masterConfig.baudRate_Hz = 100000U;* masterConfig.busIdleTimeout_ns = 0;* masterConfig.pinLowTimeout_ns = 0;* masterConfig.sdaGlitchFilterWidth_ns = 0;* masterConfig.sclGlitchFilterWidth_ns = 0;*/LPI2C_MasterGetDefaultConfig(&masterConfig);/* Change the default baudrate configuration */masterConfig.baudRate_Hz = LPI2C_BAUDRATE;/* Initialize the LPI2C master peripheral */LPI2C_MasterInit(EXAMPLE_I2C_MASTER, &masterConfig, LPI2C_MASTER_CLOCK_FREQUENCY);if (true == Flag_PCF8563_modify)/* Send master blocking data to slave */if (kStatus_Success == LPI2C_MasterStart(EXAMPLE_I2C_MASTER, LPI2C_MASTER_SLAVE_ADDR_7BIT, kLPI2C_Write)){while (LPI2C_MasterGetStatusFlags(EXAMPLE_I2C_MASTER) & kLPI2C_MasterNackDetectFlag){}/* subAddress = 0x01, data = g_master_txBuff - write to slave.start + slaveaddress(w) + subAddress + length of data buffer + data buffer + stop*/reVal = LPI2C_MasterSend(EXAMPLE_I2C_MASTER, &deviceAddress, 1);if (reVal != kStatus_Success){return -1;}g_master_txBuff[0] = 0x0; //CR_1g_master_txBuff[1] = 0x0; //CR_2g_master_txBuff[2] = 0x02; //VL_secondsg_master_txBuff[3] = 0x52; //Minutesg_master_txBuff[4] = 0x08; //Hoursg_master_txBuff[5] = 0x18; //Daysg_master_txBuff[6] = 0x6; //Weekdays, 0-6, 0代表星期天,1-6代表星期一至星期六g_master_txBuff[7] = 0x09; //Century_monthsg_master_txBuff[8] = 0x21; //YearsreVal = LPI2C_MasterSend(EXAMPLE_I2C_MASTER, g_master_txBuff, 9);if (reVal != kStatus_Success){return -1;}reVal = LPI2C_MasterStop(EXAMPLE_I2C_MASTER);if (reVal != kStatus_Success){return -1;}}

读取RTC时间

    while(1){SysTick_DelayTicks(1000U);PRINTF("Receive data from PCF8563 :");/* Receive blocking data from slave *//* subAddress = 0x01, data = g_master_rxBuff - read from slave.start + slaveaddress(w) + subAddress + repeated start + slaveaddress(r) + rx data buffer + stop */if (kStatus_Success == LPI2C_MasterStart(EXAMPLE_I2C_MASTER, LPI2C_MASTER_SLAVE_ADDR_7BIT, kLPI2C_Write)){while (LPI2C_MasterGetStatusFlags(EXAMPLE_I2C_MASTER) & kLPI2C_MasterNackDetectFlag){}reVal = LPI2C_MasterSend(EXAMPLE_I2C_MASTER, &deviceAddress, 1);if (reVal != kStatus_Success){return -1;}reVal = LPI2C_MasterRepeatedStart(EXAMPLE_I2C_MASTER, LPI2C_MASTER_SLAVE_ADDR_7BIT, kLPI2C_Read);if (reVal != kStatus_Success){return -1;}reVal = LPI2C_MasterReceive(EXAMPLE_I2C_MASTER, g_master_rxBuff, LPI2C_DATA_LENGTH); // LPI2C_DATA_LENGTHif (reVal != kStatus_Success){return -1;}reVal = LPI2C_MasterStop(EXAMPLE_I2C_MASTER);if (reVal != kStatus_Success){return -1;}}for (uint32_t i = 0U; i < LPI2C_DATA_LENGTH; i++){PRINTF("0x%2x  ", g_master_rxBuff[i]);}PRINTF("\r\n\r\n");}

实测I2C总线通信波形

PCF8563模块实物


资料来源:https://blog.csdn.net/w89436838/article/details/38660631

IIC总线协议及应用相关推荐

  1. FPGA IIC总线协议简介

    1.1 FPGA IIC总线协议简介 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA IIC总线协议简介: 5)结束语. 1.1.2 本节引言 "不积 ...

  2. IIC总线协议---以存储芯片at24c64为例

    IIC总线协议 前言:年前给老师做个红外抄表系统,,现在对当中用到的一些模块总结一下. 1.只有在总线空闲时才允许启动数据传送. 2.在数据传送过程中,当时钟线为高电平时,数据线必须保持稳定状态,不允 ...

  3. IIC 总线协议(Verilog)

    IIC (Inter - Integrated Circuit BUS) 集成电路总线,它是一种串行通信总线,多使用主从架构.IIC 接口共有两条总线线路,即 SCL(串行时钟线).SDA(串行数据线 ...

  4. IIC总线协议,7位,8位,10位地址

    IIC总线 1.1. 概述 IIC开发于1982年,当时是为了给电视机内的CPU和外围芯片提供更简易的互连方式.电视机是最早的嵌入式系统之一,而最初的嵌入系统是使用内存映射(memory-mapped ...

  5. IIC总线协议基本原理以及GPIO虚拟IIC接口

    IIC 一般应用于芯片之间的通信,是半双工串行同步通信总线,它的传输距离短,但其好处是 IIC 支持一主多从的挂载方式,因此主机和多个从机之间的通信线只要两条就够了, IIC硬件结构: IIC 串行总 ...

  6. 【STM32】【STM32CubeMX】STM32CubeMX的使用之四:IIC总线协议驱动SHT30温湿度传感器

    文章目录 0.前言 1.传感器介绍 1.1.传感器简介 1.2.传感器板原理图 1.3.传感器引脚定义 1.4.数据采集工作流程 1.4.1.单次数据采集模式 1.4.2.周期型数据采集模式 1.5. ...

  7. STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、图像(硬件IIC)

    参考:基于STM32-Oled(IIC)的使用 作者:奋斗的小殷 发布时间: 2021-05-07 13:09:26 网址:https://blog.csdn.net/boybs/article/de ...

  8. IIC总线的原理与Verilog实现

    IIC总线的原理与Verilog实现 1. 软件平台与硬件平台 2. 原理介绍 2.1 IIC总线的特点: 2.2 IIC总线协议详解: 2.2.1 IIC主机往从机里面写入数据的步骤 2.2.2 I ...

  9. 用Proteus学习51单片机之I2C(IIC)总线

    最近刚做好一个站,基于rails 3,教程为主,大家捧场看看,谢谢!www.yo945.com 在学习单片机的过程中,我常有这样的烦恼:随随便便一个芯片,少则占用三五个IO口,一般的就占用8个,稍微想 ...

最新文章

  1. 恩施茶旅谋定乡村-农业大健康·万祥军:侗乡第一寨促生态
  2. opencv java 摄像头_使用OpenCV Java创建Windows摄像头扫码程序
  3. JavaScript中的作用域、作用域链、预解析
  4. Web前端求职时都会被问到的Redis面试题分享
  5. 自定义input[type=file]的兼容样式
  6. C#替换字符串起始/结尾指定的字符串
  7. rmi full gc问题_RMI强制Full GC每小时运行一次
  8. 在Windows XP下,安装VS 2010 Express For Windows Phone .
  9. 读卡距离和信号强度两方面来考虑
  10. aotuwried是java的注解吗_@autowire注入为null
  11. Linux下辅助DNS的搭建以及远程和加密更新
  12. 【C语言】printf()函数详解
  13. 《验收测试驱动开发:ATDD实例详解》—第2章2.2节结对完成第一个测试
  14. 运维 之 常用运维工具
  15. 花生壳覆盖安装,完全卸载,注册表
  16. JAVASE基础知识栈梳理
  17. 以下不是python语言合法变量_违法行为的客体是指法律所保护的而为违法行为所侵害的:()...
  18. 苹果手机怎么备份所有数据_ORICO手机备份宝,数据备份更轻松
  19. Javascript 合集 自己整理的收藏 记录一下(最下面有惊喜)
  20. [转]浅说软件需求分析

热门文章

  1. 虚拟串口工具VSPD的使用
  2. 网站打开很卡是为什么?
  3. revit卸载/完美解决安装失败/如何彻底卸载清除干净revit各种残留注册表和文件的方法
  4. 什么是接口测试?十年阿里测试人教你怎样做接口测试
  5. flutter app安卓应用开机自启动
  6. android平板打电话,打电话上网不耽误,通话平板你需要吗?
  7. 初学Java(三)——学习准备
  8. 安徽科技学院 信网学院网络文化节 孙晓楠
  9. 平面几何----用余弦定理证明海伦公式
  10. 安信可LoRaWAN网关 RG-02 接入TTN平台,控制多节点LoRaWAN模组。