0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

IIC协议超详细解释

jf_7CID84f3 来源:传感器与检测技术 作者:传感器与检测技术 2022-10-26 15:48 次阅读

以下内容,将解释以下几个问题
1.IIC协议是什么?
2.IIC协议用来干什么?
3.IIC协议的通信过程?

1.IIC协议是什么?

IIC,即I²C,全称 Inter-Integrated Circuit,字面上的意思是集成电路之间,它其实是I²C Bus简称,所以中文应该叫 集成电路总线 ,它是一种串行通信总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统手机用以连接低速周边设备而发展。(百度百科)

2.IIC协议用来干什么?

简单地说,IIC就是一种通信协议,是为了能让主板,或嵌入式系统等与其他外设模块进行通信而进行开发的。玩过stm32开发板的同学都知道,对于一块stm32核心开发板而言,要想使用其他的外设模块,就肯定要经过接线,写代码,烧录运行的这个过程。

其实这个过程,就是一个stm32与外设模块通信的过程。接线,就是搭建通信的线路。写代码,就是制定通信的传输协议。烧录运行,就是正式的通信过程。只不过有的模块通信过程很简单,大家感觉不出来。

外设和芯片间的通信可以形象地比喻成两个人讲话:

你说的别人得能听懂:双方约定信号的协议

你的语速别人得能接受:双方满足时序要求

但是随着科技的发展,模块越来越多,总不可能,每个模块都要制定一种通信协议,这样不现实。所以,总要有一些代表性的协议能够适应大部分的模块的通信。IIC这是这样一种协议,一个IIC总线上,可以挂载多个外接设备。

常用的串行通信协议有:

UART串口通信

②IIC协议

③SPI协议

USB协议(很难)

常用的并行通信协议有:

①8080

②6800

3 .IIC协议的通信过程( 此处重点 )

接线:要搭建IIC的通信线路,出除去电源之外,还需要两条线,分别是SDA和SCLK

SDA:数据信号线,用于传输数据

SCLK:时钟信号线,用于产生时钟频率,控制时序,实现协议过程

由此可以看出,由于是单总线进行数据传输,所以IIC协议是半双工的。

搭建好线路之后,就要进行具体的通信了。

要通信,总得先发个开始信号吧。就像你要和别人说话,总要先喊他一声一样。如下图所示,协议规定,当SCLK时钟信号一直处于高电平状态时,SDA线由高电平跳变到低电平这个动作,表示起始信号。注意此时就算SDA数据线的电平跳变完,SCLK线依然是高电平哦。当连接在IIC总线上的外设模块检测到这个信号时,就知道数据要开始传输了。对于结束信号同理,协议规定,当SCLK时钟信号一直处于高电平状态时,SDA线由低电平跳变到高电平这个动作,表示结束信号。

b330b250-359f-11ed-ba43-dac502259ad0.png

在明白如何开始之后,就要开始进行数据的传输了。

协议规定,在数据的传输过程中,SCLK为高电平时,外设模块开始采集SDA数据线上的数据,此时要求SDA数据线上的电平状态必须稳定(不然鬼知道这一位数据是0还是1),当SCLK为低电平时才允许SDA线上的数据跳变成另外一种状态。

以下以传输1个bit的数据为例,如下图所示:

现在,我想传输1bit数据,该位数据为1,从上文知道,我们在发完开始信号之后,此时SDA数据线的电平状态为低电平,SCLK信号依然是高电平。难道这个时候外设就要开始读取数据了吗?

这显然不是的,从发完开始信号到真正的数据传输之间,会有一段缓冲时间,让我们去准备数据,在准备数据阶段,先将SCLK信号拉低一段时间,在这期间将SDA数据线拉高一段时间(即数据1),然后再将SCLK信号拉高,此时这个时钟信号的高电平被外设检测到的话,外设就知道要读取数据了,从而SDA上的数据就会被外设读到了。依次类推,传输下一位数据。

b375ff2c-359f-11ed-ba43-dac502259ad0.png

一般,传输完1个字节(即8bit,高位先入)的数据,才算做一次完整的数据传输,因为对存储单元而言,最小的单位便是字节。那如何确定,每次都完好地传输了一个字节呢?

这种情况就需要外设来做出回应了,就像打电话一样,如果对方不在,或不想听,说再多也没用啊。那么外设如何做出回应呢?

协议规定,主机每传完一个字节的数据即外设每收到一个字节的数据,外设就要在第9个时钟脉冲到来的时候,将SDA数据线拉低进行应答(ACK),且必须是稳定的低电平,表示已经收到了一个字节的数据,拉高表示不进行应答(NACK;注意这里是外设将SDA数据线拉低,不是主机了哦。如下图所示:

b39abaec-359f-11ed-ba43-dac502259ad0.png

所以在主机传完一个字节的数据之后,就应该释放总线(协议规定,当SDA和SCLK同时为高时,表示空闲状态)然后把SDA数据线连接的IO口从输出模式转换成输入模式,这样才能拿到SDA数据线上的应答信号。这样,一个字节的数据就从主机到外设传输完毕了。

既然IIC是双向通信的,那主机肯定也是需要从外设读取数据的,那这个读取的过程又是怎么实现的呢?毕竟外设对于我们而言是不能直接操作的,我们能操作的只有stm32。我们知道,一个IIC总线上,可以挂载多个设备,那么stm32如何确定是哪个外设正在跟我进行通信呢。对于此,那些生产外设模块的厂商们就约定,要是这个设备使用IIC协议进行通信,那么就要给这个设备指定一个器件地址,以供芯片访问。这个器件地址会在你购买其模块的时候在使用手册上注明。所以,要跟哪个模块通信,就一定要通过查阅其使用手册,找到它的器件地址。

所以,在上文所述的最开始的一个字节的数据传输过程中,这一个数据往往是器件地址。这样,对应的外设才知道,是要跟我进行通信。读取数据,也是同理,要想从外设中读取到数据,主机要明确三点:从哪个外设中的哪个地方读取数据,读取到的数据要存到哪里。

所以主机,在开始读数据之前,主机必须要先给外设发器件地址,数据所在的地址,外设才会知道你要从该地址读取数据,从而把数据通过SDA线传出来。至于具体的每个字节的传输过程,和上面所讲的从主机到外设的过程差不多,只不过反了一个反向而已,并且主机的等待应答变成了主动应答。

/*  设置SDA总线为输出模式  参数值:NULL  返回值:NULL*/
void IIC_setSDAMode_Out(){  GPIO_InitTypeDef GPIO_IIC;    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);    GPIO_IIC.GPIO_Mode  = GPIO_Mode_OUT;        //输出  GPIO_IIC.GPIO_OType = GPIO_OType_PP;        //推挽  GPIO_IIC.GPIO_Pin   = GPIO_Pin_15;                //引脚  GPIO_IIC.GPIO_PuPd  = GPIO_PuPd_UP;           //上拉  GPIO_IIC.GPIO_Speed = GPIO_Speed_25MHz;        //输出  GPIO_Init(GPIOE, &GPIO_IIC);}

/*  设置SDA总线为输入模式  参数值:NULL  返回值:NULL*/
void IIC_setSDAMode_In(){
  GPIO_InitTypeDef GPIO_IIC;  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);    GPIO_IIC.GPIO_Mode  = GPIO_Mode_IN;           //输出  GPIO_IIC.GPIO_Pin   = GPIO_Pin_15;                 //引脚  GPIO_IIC.GPIO_PuPd  = GPIO_PuPd_UP;            //上拉  GPIO_Init(GPIOE, &GPIO_IIC);
}
/*  IIC开始信号  参数值:NULL  返回值:NULL*/
void IIC_Start(){    IIC_setSDAMode_Out();        IIC_SDA_OUT(1);                             //总线释放状态    IIC_SCL_OUT(1);    delay_us(5);      IIC_SDA_OUT(0);                             //SDA跳变为低电平    delay_us(5);      IIC_SCL_OUT(0);            delay_us(5);


}
/*  IIC停止信号  参数值:NULL  返回值:NULL*/
void IIC_Stop(){    IIC_setSDAMode_Out();        IIC_SDA_OUT(0);              IIC_SCL_OUT(0);    delay_us(5);      IIC_SCL_OUT(1);                              //SDA跳变为高电平    delay_us(5);      IIC_SDA_OUT(1);            delay_us(5);
}
/*  主机写入数据到外设中  参数值:         data  要写入的一个字节  返回值:NULL*/
void IIC_writeByte(u8 data){    IIC_setSDAMode_Out();    IIC_SCL_OUT(0);                                 //只有时钟线拉低,SDA上的数据才允许写入  delay_us(5);    //将数据一位一位的发出去  for(int i =0;i<8;i++)  {      if(data&(0x1<<(7-i)))               //高位先入      {          IIC_SDA_OUT(1);      }      else      {          IIC_SDA_OUT(0);      }             IIC_SCL_OUT(1);                 //让外设读取数据       delay_us(5);           IIC_SCL_OUT(0);                 //重新拉低,准备写入下一位数据       delay_us(5);  }}


/*  主机从外设中读取一个字节的数据  参数值:NULL  返回值:NULL*/
u8 IIC_readByte(){
    u8 data = 0;  IIC_setSDAMode_In();
  IIC_SCL_OUT(0);                  //先拉低,为读取数据做准备  delay_us(5);
  for(int i=0;i<8;i++)  {        IIC_SCL_OUT(1);         // SCL为高期间才可以读取数据      delay_us(5);        if(IIC_SDA_IN)    {        data|=(0x01<<(7-i));          }else{      data &= ~(0x1<<(7-i));    }      IIC_SCL_OUT(0);    delay_us(5);  }  return data;

}


/*  主机等待应答  参数值:NULL  返回值:ack     0  应答   1 不应答*/

u8 IIC_waitAck(){    u8 ack =0;  IIC_setSDAMode_In();
  IIC_SCL_OUT(0);             //准备时序  delay_us(5);    IIC_SCL_OUT(1);  delay_us(5);  
  if(IIC_SDA_IN)  {        ack =1;  }  else  {        ack =0;    }      IIC_SCL_OUT(0);              //拉低,表示应答完成  delay_us(5);      return  ack;

}
/*  主机主动应答  参数值:        ack  0 应答 1 不应答  返回值:NULL*/

void IIC_Ack(u8 ack){  IIC_setSDAMode_Out();  IIC_SCL_OUT(0);  delay_us(5);    if(ack)  {    IIC_SDA_OUT(1);  }  else  {      IIC_SCL_OUT(0);  }      IIC_SCL_OUT(1);  delay_us(5);    IIC_SCL_OUT(0);  delay_us(5);    }

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 通信协议
    +关注

    关注

    28

    文章

    739

    浏览量

    39749
  • 总线
    +关注

    关注

    10

    文章

    2706

    浏览量

    87222
  • IIC
    IIC
    +关注

    关注

    11

    文章

    285

    浏览量

    37806

原文标题:IIC协议超详细解释(适合小白入门)

文章出处:【微信号:传感器与检测技术,微信公众号:传感器与检测技术】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    FPGA实现IIC协议的设计

    今天给大家带来的是IIC通信,IIC协议应用非常广泛,例如与MPU6050进行通信,配置OV5640摄像头、驱动OLED屏幕等等,都需要使用到IIC
    的头像 发表于 03-04 10:49 579次阅读
    FPGA实现<b class='flag-5'>IIC</b><b class='flag-5'>协议</b>的设计

    什么是IIC和SPI总线协议

    通信协议非常适合近距离低速芯片间通信。Philips(for IIC)和Motorola(for SPI) 出于不同背景和市场需求制定了这两种标准通信协议
    发表于 10-21 07:25

    STM32的IIC协议简介

    文章目录(一)IIC协议简介(二)物理层和协议层简介(三)IIC物理层:3.1、物理层的特点(四)IIC
    发表于 01-05 06:13

    IIC协议软件模拟方法

    关于iic协议和对AT24C16进行读写数据的代码解读认识IIC协议IIC协议软件模拟方法功能快
    发表于 02-09 07:00

    IIC协议的相关资料下载

    关于MPU6050学习的一些总结之二IIC协议前言一、IIC总线前言在查阅并了解了MPU6050的芯片手册后,已经对MPU6050有了大致的了解。那么接下来如何使MPU6050工作并且读取内部寄存器
    发表于 02-10 06:02

    如何使用代码实现的IIC协议

    1. 综述  由上篇博客可知道IIC协议如何用代码实现,本篇博客就不涉及协议内容,只讲解如何使用。  本次的实验传感为:DS3231(时钟模块),对于时钟模块的具体信息我也就不多介绍,大家可以自行度
    发表于 02-21 06:36

    iic总线的详细说明

    iic总线的详细说明,协议说明,教程,学习
    发表于 11-16 19:05 0次下载

    IIC总线协议

    IIC总线协议,感兴趣的小伙伴们可以看看。
    发表于 07-26 16:29 57次下载

    IIC总线协议中文版

    IIC协议的介绍,中文版,易懂,可以在里面了解到IIC是何物,如何使用以及定义
    发表于 08-09 15:08 0次下载

    使用51单片机进行IIC协议的解读程序免费下载

    本文档的主要内容详细介绍的是使用51单片机进行IIC协议的解读程序免费下载。
    发表于 08-15 17:32 4次下载
    使用51单片机进行<b class='flag-5'>IIC</b><b class='flag-5'>协议</b>的解读程序免费下载

    51单片机中IIC协议详细资料说明

    本文档的主要内容详细介绍的是51单片机中IIC协议详细资料说明。
    发表于 06-26 17:43 7次下载
    51单片机中<b class='flag-5'>IIC</b><b class='flag-5'>协议</b>的<b class='flag-5'>详细</b>资料说明

    IIC协议详细解释(适合小白入门)

    以下内容,将解释以下几个问题1.IIC协议是什么?2.IIC协议用来干什么?3.IIC
    发表于 12-07 14:21 5次下载
    <b class='flag-5'>IIC</b><b class='flag-5'>协议</b>超<b class='flag-5'>详细</b><b class='flag-5'>解释</b>(适合小白入门)

    振弦采集模块的通讯协议IIC

    振弦采集模块的通讯协议IICIIC 通讯协议本身即是基于设备地址和寄存器的物理层通讯协议, VMXXX 使用
    的头像 发表于 11-17 10:02 557次阅读
    振弦采集模块的通讯<b class='flag-5'>协议</b>( <b class='flag-5'>IIC</b>)

    什么是IIC协议

    IIC协议最早1982年由飞利浦公司设计开发,是一种两线制(SDA + SCL)的串行通行方式,提供了主从机之间通行的一种方案,在今天也是被广泛的应用在很多的产品设备上。
    的头像 发表于 02-10 10:53 3005次阅读
    什么是<b class='flag-5'>IIC</b><b class='flag-5'>协议</b>

    IIC通讯协议的电路设计

    前面我们概述过一些常见的通讯协议,本文着重讲讲关于IIC协议
    的头像 发表于 04-19 11:00 1339次阅读
    <b class='flag-5'>IIC</b>通讯<b class='flag-5'>协议</b>的电路设计