IIC协议解释

2023-05-16

(1)概述

I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主控制器和从器件间的主从通信,在小数据量场合使用,传输距离短,任意时刻只能有一个主机等特性。

经常IIC和SPI接口被认为指定是一种硬件设备,但其实这样的说法是不尽准确的,严格的说他们都是人们所定义的软硬结合体,分为物理层(四线结构)和协议层(主机,从机,时钟极性,时钟相位)。

IIC,SPI的区别不仅在与物理层,IIC比SPI有着一套更为复杂的协议层定义。下面来分别说明一下IIC的物理层和协议层。

(2)IIC的物理层

a.只要求两条总线线路,一条是串行数据线SDA,一条是串行时钟线SCL。(IIC是半双工,而不是全双工)。

b.每个连接到总线的器件都可以通过唯一的地址和其它器件通信,主机/从机角色和地址可配置,主机可以作为主机发送器和主机接收器。

c.IIC是真正的多主机总线,(而这个SPI在每次通信前都需要把主机定死,而IIC可以在通讯过程中,改变主机),如果两个或更多的主机同时请求总线,可以通过冲突检测和仲裁防止总线数据被破坏。

d.传输速率在标准模式下可以达到100kb/s,快速模式下可以达到400kb/s。

e.连接到总线的IC数量只是受到总线的最大负载电容400pf限制。

一个典型的IIC接口如下图(1)所示


图(1)

(3)IIC的协议层

IIC的协议层才是掌握IIC的关键。现在简单概括如下:

a.数据的有效性

在时钟的高电平周期内,SDA线上的数据必须保持稳定,数据线仅可以在时钟SCL为低电平时改变。

如图(2)所示:

      图(2)

b.起始和结束条件

起始条件:当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始条件,结束条件:当SCL为高电平的时候,SDA线上由低到高的跳变被定义为停止条件,要注意起始和终止信号都是由主机发出的,连接到I2C总线上的器件,若具有I2C总线的硬件接口,则很容易检测到起始和终止信号。总线在起始条件之后,视为忙状态,在停止条件之后被视为空闲状态,对起始条件和结束条件的描述如下图(3)所示。


图(3)

c.应答

每当主机向从机发送完一个字节的数据,主机总是需要等待从机给出一个应答信号,以确认从机是否成功接收到了数据,从机应答主机所需要的时钟仍是主机提供的,应答出现在每一次主机完成8个数据位传输后紧跟着的时钟周期,低电平0表示应答,1表示非应答,如图(4)所示。


图(4)

d.数据帧格式

I2C总线上传送的数据信号是广义的,既包括地址信号,又包括真正的数据信号。

在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T),“1”表示主机接收数据(R)。{这里小编在驱动MPU6050模块的时候,就犯过这样的错误,它写的MPU6050从机地址是0x68,因为发送从机地址的时候,要加一位读写方向位,因为刚开始应该是向这个MPU6050里写从机里某个寄存器的地址,所以应该是7位地址   0x68(1101000)+二进制位0=11010000)也就是0xD0,表示要向该IIC设备里写东西,然后再紧接着写入IIC设备里的寄存器地址,而我直接写入了0x68,导致出错},每次数据传送总是由主机产生的终止信号结束。但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。

在总线的一次数据传输过程中,可以有以下几种组合方式:

[1] 主机向从机发送数据,数据传送方向在整个传送过程中不变:



注:有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。

    A表示应答(低电平), A非表示非应答(高电平)。S表示起始信号,P表示终止信号。

[2]主机在第一个字节后,立即从从机读数据:



[3]在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读/写方向位正好反相:



一般情况下,[3]是比较常见的,比如MPU6050模块,

发送起始信号

等待从机应答

写一个从机地址+0(表示写),

等待从机应答

发送一个字节的MPU6050加速度存储寄存器地址,

等待从机应答

再发送一次起始信号

等待从机应答

写一个从机地址+1(表示读)

等待从机应答

读取MPU6050传感器数据

主机非应答

e.IIC信号的模拟

主机可以采用不带I2C总线接口的单片机,如80C51、AT89C2051等单片机,利用软件实现I2C总线的数据传送,即软件与硬件结合的信号模拟。即使是含有IIC硬件的单片机(如stm32 103系列)也有一定的缺陷,所以一般也会模拟IIC的时序。现将具体时间截图如下:


具体的程序代码如下:

起始信号

//产生IIC起始信号
void IIC_Start(void)
{
    SDA_OUT();     //sda线输出
    IIC_SDA=1;        
    IIC_SCL=1;
    delay_us(4);
    IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
    delay_us(4);
    IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}   

停止信号

//产生IIC停止信号
void IIC_Stop(void)
{
    SDA_OUT();//sda线输出
    IIC_SCL=0;
    IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
    delay_us(4);
    IIC_SCL=1; 
    IIC_SDA=1;//发送I2C总线结束信号
    delay_us(4);                                
}

有效应答

//产生ACK应答
void IIC_Ack(void)
{
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=0;
    delay_us(2);
    IIC_SCL=1;
    delay_us(2);
    IIC_SCL=0;
}

无效应答

//不产生ACK应答          
void IIC_NAck(void)
{
    IIC_SCL=0;
    SDA_OUT();
    IIC_SDA=1;
    delay_us(2);
    IIC_SCL=1;
    delay_us(2);
    IIC_SCL=0;
}  

发送单字节

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答           
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
    SDA_OUT();      
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1;      
        delay_us(2);   //对TEA5767这三个延时都是必须的
        IIC_SCL=1;
        delay_us(2); 
        IIC_SCL=0;  
        delay_us(2);
    }    
} 

接收单字节

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
    unsigned char i,receive=0;
    SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
    {
        IIC_SCL=0; 
        delay_us(2);
        IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
        delay_us(1); 
    }                    
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

EEPROM

24C02为IIC接口,容量为256字节。

封装如下图:


管脚定义:

设备地址的高四位固定,中间为地址线定义的地址,最后一位为读写位。 

由于A0,A1,A2设置为0,所以 

读的时候:Device Address = 0xA1; 

写的时候:Device Address = 0xA0;


24C02字节写时序

起始信号

写设备地址,Device Address = 0xA0;

等待应答

确定写入的EEPROM地址即WORD ADDRESS

等待应答

向SDA数据线上写入数据DATA

等待应答

停止信号


//在AT24CXX指定地址写入一个数据
//WriteAddr  :写入数据的目的地址    
//DataToWrite:要写入的数据
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{                                                                                            
    IIC_Start();  
    if(EE_TYPE>AT24C16)
    {
        IIC_Send_Byte(0XA0);        //发送写命令
        IIC_Wait_Ack();
        IIC_Send_Byte(WriteAddr>>8);//发送高地址   
    }else IIC_Send_Byte(0XA0+((WriteAddr/256)<<1));   //发送器件地址0XA0,写数据   
    IIC_Wait_Ack();    
    IIC_Send_Byte(WriteAddr%256);   //发送低地址
    IIC_Wait_Ack();                                                        
    IIC_Send_Byte(DataToWrite);     //发送字节                             
    IIC_Wait_Ack();                    
    IIC_Stop();//产生一个停止条件 
    delay_ms(10);    
}

24C02字节读时序

起始信号

写设备地址,Device Address = 0xA0;

等待应答

确定写入的EEPROM地址即WORD ADDRESS

等待应答

起始信号

读设备地址,Device Address = 0xA1;

等待应答

读SDA上数据

等待应答

停止信号


//在AT24CXX指定地址读出一个数据
//ReadAddr:开始读数的地址  
//返回值  :读到的数据
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{                 
    u8 temp=0;                                                                               
    IIC_Start();  
    if(EE_TYPE>AT24C16)
    {
        IIC_Send_Byte(0XA0);       //发送写命令
        IIC_Wait_Ack();
        IIC_Send_Byte(ReadAddr>>8);//发送高地址      
    }else IIC_Send_Byte(0XA0+((ReadAddr/256)<<1));   //发送器件地址0XA0,写数据      
    IIC_Wait_Ack(); 
    IIC_Send_Byte(ReadAddr%256);   //发送低地址
    IIC_Wait_Ack();     
    IIC_Start();           
    IIC_Send_Byte(0XA1);           //进入接收模式            
    IIC_Wait_Ack();  
    temp=IIC_Read_Byte(0);         
    IIC_Stop();//产生一个停止条件       
    return temp;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IIC协议解释 的相关文章

  • AD7606分析讲解

    一 ad7606数据手册分析 引脚配置和功能描述 ADC7606的典型工作特性 FFT xff08 快速傅里叶变换 xff09 http azaleasays com 2008 10 17 fft and digital signal pr
  • 什么是航位推算(Dead Reckoning )

    只有同时接收三到四个GPS GNSS卫星的信号才能实现精确的GPS GNSS定位 当仅依靠GPS GNSS定位时 xff0c 可能会出现位置精度降低或丢失的情况 例如 xff0c 当车辆在无法接收GPS GNSS信号的区域 xff08 隧道
  • STM32F103系列引脚定义-功能图

    器件功能和配置 xff08 STM32F103XX增强型 xff09 系统结构 管脚图
  • 如何用keil5打开keil4的工程

    参考网友的方法 xff1a 1 到http www2 keil com mdk5 legacy 官网下载keil4的支持包 2 正常流程安装所下载的安装包 xff1b 3 安装完成后 xff0c 用keil5打开工程 xff08 keil4
  • NMEA-0183 协议简介

    NMEA 0183 是美国国家海洋电子协会 xff08 National Marine Electronics Association xff09 为海用电子设备制定的标准格式 目前业已成了 GPS 北斗导航设备统一的 RTCM xff08
  • 串口通信校验方式(even,odd,space,mark)UART数据波形分析

    1 even 每个字节传送整个过程中bit为1的个数是偶数个 xff08 校验位调整个数 xff09 2 odd 每个字节穿送整个过程中bit为1的个数是奇数个 xff08 校验位调整个数 xff09 3 noparity没有校验位 4 s
  • Linex Ubuntu环境下 Intel Realsense D435I 驱动+ROS驱动安装配置

    任务背景 在ROS环境中使用d435i xff0c 订阅图像和imu数据 任务概述 实现在ros中使用d435i主要有两步骤 xff1a 1 安装d435i sdk xff0c 即librealsense xff1b 2 安装realsen
  • C++ 实现简单Http服务器

    实现一个简单的Http服务器 xff0c 基于windows 平台 总共五个文件 HttpServer hpp HttpServer cpp Utils hpp Utils cpp main cpp Utils hpp span class
  • libcurl API介绍及简单编程

    libcurl编程 xff0c 主要采用callback function 回调函数 的形式完成传输任务 xff0c 用户在启动传输前设置好各类参数 和回调函数 xff0c 当满足条件时 libcurl 将调用用户的回调函数实现特定功能 下
  • git patch

    git patch用于将所做的修改进行打包 xff0c 然后再别的分支或给别人可以直接应用该patch xff0c 达到修改复用的效果 diff命令 git diff gt xxxx patch git diff xx file gt xx
  • WIFI知识 - MCS简介

    WIFI知识 MCS简介 MCS简介 802 11n 射频速率的配置通过 MCS xff08 Modulation and Coding Scheme xff0c 调制与编码策略 xff09 索引值实现 MCS 调制编码表是 802 11n
  • 802.11 QoS

    到了空调西瓜WiFi的夏日时光了 xff0c 家里用网的人一多 xff0c 难免会抢占起宽带资源来 有没有什么办法 xff0c 让家里所有人都可以得到一个比较不错的网络体验呢 xff1f 那今天你可以试试打开你路由器的QoS功能了 xff0
  • Wireshark抓包分析WLAN连接过程

    一个完整的WLAN连接过程 xff1a 一 xff1a WLAN扫描 主动扫描 xff1a 两种方式 xff1a xff08 1 xff09 向各个信道发出Probe Request帧并制定某个SSID xff0c 只有能够提供指定SSID
  • 802.11X用户身份验证 EAPOL

    EAPOL是什么 sogou com 802 11X用户身份验证 走看看 zoukankan com EAPOl的由来是基于802 1x网络访问认证技术 xff1a 802 1x协议起源于802 11协议 xff0c 后者是IEEE的无线局
  • git reset

    git reset 三种模式分别为 mixed 默认 soft hard 直接看官方的解释 其中HEAD代表版本库 xff0c index代表暂存区 xff0c 另外还有一个我们改代码的工作区 mixed 回退版本库 xff0c 暂存区 m
  • git reset还是git revert?

    reset和revert都可以用来回滚代码 但他们是有区别的 xff0c 准确来说 xff0c reset是用来 34 回退 34 到某个提交 xff0c 而revert是用来 34 撤销 34 某次或者某几次提交 xff0c 撤销也会作为
  • PR and MR

    GitHub 的 Pull Request 是指什么意思 xff1f 作者 xff1a 知乎用户 链接 xff1a https www zhihu com question 21682976 answer 79489643 来源 xff1a
  • python--基础知识点--subprocess模块

    subprocess 模块的介绍与使用 一 介绍 subprocess模块可以生成新的进程 xff0c 连接到它们的input output error管道 xff0c 同时获取它们的返回码 二 基本操作方法 1 subprocess的ru
  • Homebus(HBS)通信协议学习

    HBS通信主控与从机连接示意图 两根HBS总线之间的电压差大约为15V xff0c 差分信号分别加载到HBS的这两根总线上 用示波器的探头测得 xff08 探头的地在任意一根HBS总线上 xff0c 探头的信号输入端在另一根HBS总线上 x
  • RSA参数及RSA用法

    RSA算法n e d三个参数的意义 n为q p乘机 e为加密质数数值 d为解密质数数值 其中 e d p 1 q 1 61 1余数为1 其中p和q为2个足够大的素数 RSA的算法涉及三个参数 xff0c n e1 e2 其中 xff0c n

随机推荐

  • STM32的CAN

    一 CAN控制器简介 STM32自带了基本扩展CAN外设 xff0c 又称bxCAN xff0c bxCAN的特点如下 xff1a 1 支持CAN协议2 0A和2 0B主动模式 2 波特率最高达1Mbps 3 支持时间触发通信 4 具有3个
  • VSCode使用ssh密钥,不用每次输密码登录服务器的方法

    如果已经用ssh keygen 生成密钥了 xff0c 则跳过生成密钥这一步 客户端机器生成密钥 也就是vscode运行的机器 xff0c 在终端任意路径下输入 ssh keygen 生成密钥 本地 ssh keygen 默认目录在 ssh
  • Wi-Fi 802.11协议 管理帧 之 Auth帧详解

    Auth xff1a 链路认证 链路认证阶段主要是 AP 用来确认 Station 是否是 802 11 设备 xff0c 确认彼此是否可以正常通讯 xff0c 身份认证一般有为两种方式 xff0c 一种是开放系统认证 xff0c 另一种是
  • 802.11 协议介绍

    802 11协议基础 前言 OSI七层网络 开放式系统互联模型 xff08 Open System Interconnection Model xff09 是一种概念模型 xff0c 由国际标准化组织提出 xff0c 一个试图使各种计算机在
  • 802.11标准deauth报文的reason code中文版

    代码 原因 0 保留 1非特定原因 2以前的身份验证不再有效 3由于发送STA离开 xff08 或已经离开 xff09 ibs或ESS而被取消身份验证 4由于不活动而解除关联 5已解除关联 xff0c 因为AP无法处理所有当前关联的STA
  • 虚拟机ubuntu单向ping通

    可以单向ping通 xff0c 到win端查看VMnet8 xff0c 发现VMnet8不见了 找回方法 xff1a 在VMware中对NAT模式进行 还原默认设置 操作或者配置好后点击确定 xff08 注意 xff1a 虚拟机开机后无法还
  • Beyond compare文件夹内容自动比较

    前言 xff1a 在一开始比较文件都是手动一个个去点击文件 xff0c 如果是几万个代码文件这将是巨大的工程 xff0c 带着偷懒的想法跑去找方法真找到了 默认会全部的文件标红 xff0c 这就很难受了 解决方案 xff1a 顶部的菜单 会
  • 从MIT协议谈契约精神

    以前看到过李笑来讲的发生在他身上的故事 xff0c 说他当年 2001年 住在双榆树 xff0c 经常去双安商场的地下超市买东西 xff0c 有一次买了个什么东西觉得不好 xff0c 要退 xff0c 超市服务员说按规定 xff0c 该类商
  • VLC命令行使用帮助

    Usage vlc options stream You can specify multiple streams on the commandline They will be enqueued in the playlist The f
  • 将Conda Prompt Here添加到右键菜单

    如何将Conda Prompt Here添加到右键菜单 Conda是一个非常流行的Python的环境管理工具 xff0c 在做项目的时候把它跟IDE整合在一起用来管理不同项目的环境会很方便 xff0c 但是在日常使用Windows的过程中如
  • AMS-1117

    电路图 说明 10uF 61 10622uF 61 226100nF 61 104106 61 10乘以10的6次方pF xff1b 简单点的说就是106表示容量 10后面加六个零 单位pF 转换成uF就是10uF 电容之间的换算公式 xf
  • ROS---用catkin创建ROS包、编译

    安装好ROS后 xff0c 默认已经安装了catkin xff0c 接着执行以下步骤 用catkin创建ROS包 span class hljs comment 每次都要进入这个目录 xff0c 也就是所有的包都要放在这个目录下 span
  • libQtGui.so: undefined reference to `png

    使用Qt4 包在Centos上编译时 xff0c 出现libQtGui so 找到未定义的png等 首先进行网上搜索 xff0c 没有发现任何思路 执行ldd时 xff0c 发现少了很多依赖库 xff0c 如下 xff1a ldd libQ
  • C/C++中在头文件中定义函数或变量会出现的问题

    在 C C 43 43 中 xff0c 我们一般是把代码分为头文件 xff08 h xff09 和源文件 xff08 c cpp xff09 分开保存 xff0c 这样可以方便代码管理和阅读 但是如果把函数或变量的定义也放在头文件中会出现什
  • C++ 求100的阶乘

    include lt iostream gt using namespace std int main int n int k 61 1 k为当前的位数 int fact 10000 61 1 0 cout lt lt 34 输入阶乘n 3
  • C++ 读入一个整数,将各个数位上的数拆分下来并输出(从高位到低位)。

    include lt iostream gt include lt cmath gt using namespace std void split int num int n 61 num int count 61 0 位数 int tem
  • C++建立一个关于平面点坐标的类

    建立一个关于平面点坐标的类 include lt iostream gt include lt cmath gt using namespace std class Cpoint private int flag flag 61 1时 xf
  • 图---生成树与最小生成树

    今天在做题的时候遇到一个问题 xff0c 如何根据图的邻接表来画出 DFS 生成树和 BFS 生成树 xff0c 有两年的真题中涉及到这个问题 xff0c 在以前的学习中没注意过此问题 xff0c 由于严奶奶的书上也只是一带而过 xff0c
  • 编写一个递归算法,实现将一棵二叉树的左右孩子互换。

    include 34 iostream 34 using namespace std define max 20 定义树的结点数 typedef struct BTNode 定义二叉树结点类型 char data 结点数据类型 struct
  • IIC协议解释

    xff08 1 xff09 概述 I2C Inter Integrated Circuit BUS 集成电路总线 xff0c 该总线由NXP xff08 原PHILIPS xff09 公司设计 xff0c 多用于主控制器和从器件间的主从通信