三大通信协议(二):IIC通信协议

三大通信协议(二):IIC通信协议1.概念是什么?I²C(Inter-IntegratedCircuit),中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,是由飞利浦公司在1980年代初设计的,方便了主板、嵌入式系统或手机与周边设备组件之间的通讯。由于其简单性,它被广泛用于微控制器与传感器阵列,显示器,IoT设备,EEPROM等之间的通信。优点仅需要两条总线即可通讯(大大的节约了IO口资源)最大主机数量:无限制。最大从机限制:理论127(一个主机多个从机,一对多,多对一,多对多)2.硬件连

大家好,又见面了,我是你们的朋友全栈君。

1. 概念

  • 是什么?

I²C(Inter-Integrated Circuit),中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,是由飞利浦公司在1980年代初设计的,方便了主板、嵌入式系统或手机与周边设备组件之间的通讯。由于其简单性,它被广泛用于微控制器与传感器阵列,显示器,IoT设备,EEPROM等之间的通信。

  • 优点
    1. 仅需要两条总线即可通讯(大大的节约了IO口资源)
    2. 最大主机数量:无限制。最大从机限制:理论127
      (一个主机多个从机,一对多,多对一,多对多)

2. 硬件连接

  • I²C协议仅需要一个SDA(串行数据线)和SCL(串行时钟线)引脚。这两条数据线需要接上拉电阻
  • 上拉电阻使用典型的4.7kΩ
  • 使用I2C设备灌电流不得超过3mA
  • 逻辑0电压不得高于0.4V
    在这里插入图片描述

I²C总线(SDA,SCL)内部都使用漏极开路驱动器(开漏驱动),因此SDA和SCL 可以被拉低为低电平,但是不能被驱动为高电平,所以每条线上都要使用一个上拉电阻,默认情况下将其保持在高电平;
在这里插入图片描述

3. 数据传输协议

主设备和从设备进行数据传输时遵循以下协议格式。
数据通过一条SDA数据线在主设备和从设备之间传输0和1的串行数据。串行数据序列的结构可以分为,开始条件,地址位,读写位,应答位,数据位,停止条件,具体如下所示;

在这里插入图片描述

  1. 主机(Master)发送开始信号给从机(Slave),唤醒所有主从机
  2. 主机发送7位的地址位和1位的读写位给从机
  3. 等待地址匹配从机的应答信号
  4. 主机发送或接收数据到从机
  5. 在传输完每个数据帧后,接收设备将另一个ACK位返回给发送方,以确认已成功接收到该帧:
  6. 结束之后主机发出停止信号

3.1 开始信号

当主设备决定开始通讯时,需要发送开始信号,需要执行以下动作:

  1. 先将SDA线从高压电平切换到低压电平;
  2. 然后将SCL从高电平切换到低电平;

在主设备发送开始条件信号之后,所有从机即使处于睡眠模式也将变为活动状态,并等待接收地址位。
在这里插入图片描述

3.2 地址位

7位组成的地址位
主设备如果需要向从机发送/接收数据,首先要发送对应从机的地址,然后会匹配总线上挂载的从机的地址;

3.3 读写位(R/W)

该位指定数据传输的方向:

  • 如果主设备需要将数据发送到从设备,则该位设置为 0
  • 如果主设备需要往从设备接收数据,则将其设置为 1

3.4 应答位(ACK / NACK)

主机每次发送完数据之后会等待从设备的应答信号ACK:

  • 在第9个时钟信号,如果从设备发送应答信号ACK,则SDA会被拉低;
  • 若没有应答信号NACK,则SDA会输出为高电平,这过程会引起主设备发生重启或者停止;
    在这里插入图片描述

3.5 数据位(8Bit)

传输的数据总共有8位,由发送方设置,它需要将数据位传输到接收方。(这个则是cmd或者data)

发送之后会紧跟一个ACK / NACK位,如果接收器成功接收到数据,则设置为0。否则,它保持逻辑1。

  • 8DataBit+AckBit、8DataBit+AckBit…直到数据发送完进行下一次才接上Stop信号

3.6 停止信号

当主设备决定结束通讯时,需要发送开始信号,需要执行以下动作:

  1. 先将SDA线从低电压电平切换到高电压电平;
  2. 再将SCL线从高电平拉到低电平;

具体如下图所示:
在这里插入图片描述

4. 软件编写

4.1 初始化

void IIC_init()//IIC初始化
{ 
   
       SCL=1; //首先把时钟线拉高
       delay_us(4);//延时函数
       SDA=1; //在SCL为高的情况下把SDA拉高
       delay_us(4); //延时函数
}

4.2 开始信号

//产生IIC起始信号
//1.先拉高SDA,再拉高SCL,空闲状态
//2.拉低SDA
void IIC_Start()//启动信号
{ 
   
       SDA=1; //确保SDA线为高电平
       delay_us(5);
       SCL=1;  //确保SCL高电平
       delay_us(5);
       //以下这一步产生了开始信号的脉冲
       SDA=0; //在SCL为高时拉低SDA线,即为起始信号
       delay_us(5);
}

4.3 IIC发送一个字节数据

//IIC发送一个字节
//返回: 从机有无应答
//1,有应答
//0,无应答 

//只有当SCL被拉低后,SDA才能被改变
//总结:在SCL为低电平期间,发送数据,发送8次数据,数据为1,SDA被拉高,数据为0,SDA被拉低。
//传输期间保持传输稳定,所以数据线仅可以在时钟SCL为低电平时改变。
void IIC_Send_Byte(u8 txd)
{ 
                           
    u8 t;   
    SDA_OUT();         
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    { 
                 
        //IIC_SDA=(txd&0x80)>>7; //获取最高位
        //获取数据的最高位,然后左移7位
        //如果某位为1,则SDA为1,否则相反
        if((txd&0x80)>>7)
            IIC_SDA=1;
        else
            IIC_SDA=0;
        txd<<=1;       
        delay_us(2);   
        IIC_SCL=1;
        delay_us(2); 
        IIC_SCL=0;    
        delay_us(2);
    }     
}       

4.4 IIC读取一个字节


//读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;
}

4.5 停止信号

//产生IIC停止信号
//1.先拉低SDA,再拉低SCL
//2.拉高SCL
//3.拉高SDA
//4.停止接收数据
void IIC_Stop(void)
{ 
   

	IIC_SCL=0;
	IIC_SDA=0;    //STOP:当SCL高时,数据由低变高
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;    //发送I2C总线结束信号
	delay_us(4);							   	
}

参考资料

I2C协议靠这16张图彻底搞懂(超详细)
IIC原理超详细讲解—值得一看

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137552.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vue + echarts 省份地图 以及打包后地图加载不出来(比较详细)「建议收藏」

    vue + echarts 省份地图 以及打包后地图加载不出来(比较详细)「建议收藏」刚开始地图怎么也出不来,经过解决,是因为echarts.min.js引入位置在index.html中引入需要的js版本按照自己需要的来<scriptsrc=”./static/plugins/echarts-5.1.2/echarts.common.min.js”></script><scriptsrc=”./static/plugins/echarts.min.js”></script>(必须引入,地图才能加载)全局引入im

    2022年10月12日
    2
  • RT-Thread零基础快速入门第7讲——FinSH控制台「建议收藏」

    RT-Thread零基础快速入门第7讲——FinSH控制台「建议收藏」目录一、前言源码链接二、FinSH控制台使用方法第一步:配置FinSH第二步:烧录程序并把串口连接到PC端第三步:打开xshell或者串口助手第四步:测试FinSH命令三、自定义FinSH命令自定义msh命令自定义C-Style命令和变量自定义命令重命名四、项目实战五、结束语一、前言本来我是打算先讲完RT-thread的内核,再讲设备和组件,但是考虑到后面很多地方都会用到FinSH控制台…

    2022年5月21日
    38
  • Windows系统日志分析_windows系统事件日志

    Windows系统日志分析_windows系统事件日志Windows操作系统的日志分析Windows日志简介Windows操作系统在其运行的生命周期中会记录其大量的日志信息,这些日志信息包括:Windows事件日志,Windows服务器角色日志,FTP日志,邮件服务日志,MSSQLServer数据库日志等。主要记录行为当前的日期、时间、用户、计算机、信息来源、事件、类型、分类等信息。用户可以通过它来检查错误发生的原因,处理应急事件,提供溯源,这些日志信息在取证和溯源中扮演着重要的角色。Windows日志事件类型Windows操作系统日志分析Wi

    2025年10月2日
    1
  • JSONPath 表达式

    JSONPath 表达式JSONPath是参照,xpath表达式来解析xml文档的方式,json数据结构通常是匿名的并且不一定需要有根元素。JSONPaht用一个抽象的名字$来表示最外层对象。JOSNPath表达式可以使用. 符号如下:$.store.book[0].title或者使用[]符号$[‘store’][‘book’][0][‘title’]从输入路径来看。内部或者输出的路径都会转化成-符号。JSON…

    2022年6月16日
    32
  • python怎么换行输出的数字对齐_python中如何使输出换行「建议收藏」

    Python的print()函数输出时,通常输出结果是整行显示出来的,这时候我们需要考虑一下,我们输出的结果需不需要换行?不需要换行的方法也是嗯容易的的,这里就不多赘述了,来说说如何做到输出换行:常用的转义符方式:\n#-*-coding:utf-8-*-A=”来看看能不能\n换行。”print(A)输出结果来看看能不能换行。使用三引号进行换行:”””value1;value2;value3…

    2022年4月9日
    116
  • [新详细]让Keil5续签到2032年的办法,不可商用

    [新详细]让Keil5续签到2032年的办法,不可商用使用方法和以前的版本一样,MDK或者C51以及ARM等均适用,软件来自网络,如有纠纷请留言。仅供学习与参考,商业用途请购买正版。非新手,直接看文章最后流程打开你的Keil主页面,添加证书激活的位置在File→LicenseManagement复制CID将CID复制进软件,通过Target选择你用的类型,复制后,点击Generate计算出新的licenseID码复制…

    2022年6月1日
    167

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号