一文教你彻底学会IIC协议

简介: 一文教你彻底学会IIC协议

一.序言

背景知识:I2C总线上是通过上拉电阻接到电源。当I2C设备空闲时,会输出高阻态,当所有设备都空闲时,由上拉电阻把总线拉成高电平。所以默认总线上是高电平。

I2C设备之间常见的连接方式。

二.IIC读写过程

注:一般单片机是主机,各种模块是从机(eeprom,oled显示屏,以及各种传感器)

2.1主机向从机写入数据

首先给一个起始信号,然后发送从机地址(地址最后一位决定是写数据还是读数据)这里给的是 ‘0’,表示写入数据。写入从机地址后,等待从机给响应信号。主机接收到响应数据后才可以开始传输数据了,如果主机不想传输数据了,就给出停止信号。数据传输结束

2.2主机向从机读取数据

这边同写入数据一样,先给一个起始信号,再发送从机地址(地址最后一位表示读还是写)这里是 ‘1’,表示读取数据。等待从机响应。响应后就可以读取数据了。读取数据后,要发送一个应答信号(告诉从机数据已经被读取),从机收到应答信号后就可以继续发送数据给主机。如果主机不想再接收数据了,就发送一个非应答信号(告诉从机不要发送数据了),主机给出停止信号。数据读取完成。

2.3 I2C起始信号和停止信号

起始信号是SCL时钟线在高电平时,SDA由高拉低,产生一个下降沿。表示起始信号。

停止信号是SCL时钟线在高电平时,SDA由低电平拉到高电平,产生一个上升沿。表示停止信号

三. 数据的有效性

我们知道I2C是时钟线和数据线协同工作的。那么I2C是如何表示有效数据的呢?

其实就是在SCL保持高电平的时候,SDA的数据才是有效的,正确的。这时候才能去读取SDA的数据(同时这时候不能去改变SDA的数据)不然可能会读取到错误数据,那么SCL低电平时是在干嘛? SCL低电平时SDA进行数据变化(此时并不会读取SDA的数据),等SDA数据稳定后,在拉高SCL,进行数据读取。

四.时序要求

前面我们只是讲了大概流程,其实I2C对时序也是要求严格的。下面我就给大家讲解时序。

4.1 起始信号

起始产生时,SCL高电平时,SDA高电平至少维持4.7us,此时拉低SDA产生下降沿,至少维持4us.

4.2 终止信号

终止信号产生时,SCL高电平时,SDA低电平至少维持4us,再拉高SDA产生上升沿。维持SDA至少4.7us

4.3 应答信号

当SCL是高电平时,且至少维持4us,SDA数据线是0,此时表示应答信号

4.4 非应答信号

当SCL是高电平时,且至少维持4us,SDA数据线是1,此时表示非应答信号

4.5读取数据

我们可以参考下图,当读取数据时SCL保持时间为tHIGH最少4ms。当SDA变化数据是,SCL保持低电平的时间tLow至少保持4.7us,此时可以改变SDA上的数据。

五.代码实例

void I2C_Start(void)
{
  IIC_SDA = 1;      
  IIC_SCL = 1; //高电平         
  delay_us(5); //保持4.7us以上,这里5us     
  IIC_SDA = 0; //拉低,下降沿  
  delay_us(5); //保持低电平      
  IIC_SCL = 0; //拉低   
}
void I2C_Stop(void)
{
  IIC_SDA = 0;        
  IIC_SCL = 1;           
  delay_us(5);//保持高电平        
  IIC_SDA = 1; //拉高,上升沿      
  delay_us(5);            
}
void I2C_SendACK(char ack)
{
  IIC_SCL = 0;            
  if(ack) IIC_SDA = 1; 
  else IIC_SDA = 0;   
  delay_us(2);  //短延时等待SDA稳定            
  IIC_SCL = 1;  //拉高SCL         
  delay_us(5);  //延时,从机读取SDA           
  IIC_SCL = 0;              
char I2C_RecvACK(void)
{
  unsigned char cnt=0;
  IIC_SDA=1; //释放数据线
  delay_us(1);
  IIC_SCL=1; //时钟线拉高
  delay_us(1);
  while(IIC_SDA) //等待从机把SDA拉低,产生应答信号
  {
    cnt++;
    delay_us(1);
    if(cnt>=250)
    {
      I2C_Stop();
      return 1;
    }
  }
  IIC_SCL=0; 
  return 0;
}
void I2C_SendByte(unsigned char data)
{   
//data高位先发。
  unsigned char  i;
  IIC_SCL = 0;  //拉低SCL
  delay_us(2);  
  for (i=0;i<8;i++) 
  {
    if(data&0x80) IIC_SDA=1;//给SDA赋值
    else IIC_SDA=0;
    data <<= 1;
    IIC_SCL = 1; //拉高时钟线
    delay_us(2); //延时,从机读取SDA数据
    IIC_SCL = 0;
    delay_us(2);
  }
}
unsigned char I2C_RecvByte(void)
{
//低位先接收
  unsigned char  i;
  unsigned char  data = 0;
  for (i=0;i<8;i++)
  {
    IIC_SCL=0;//拉低时钟线
    delay_us(2);//此时从机改变SDA数据
    IIC_SCL=1; //拉高时钟线
    data <<= 1;
    IIC_SCL = 1;
    if(IIC_SDA) data|=0x01;  //读取数据线            
    delay_us(1);
    //因为默认是0,所以IIC_SDA为0是可以不赋值0
  }
  IIC_SCL=0; 
  return data;
}

六.结语

本次也是结合I2C的时序图讲述了如何产生起始信号,停止信号,应答信号,非应答信号,向从机读取数据,向从机写入数据等。最后也是给出了代码实例,理论和实践结合用,帮助读者深入理解IIC。



目录
相关文章
|
存储 运维 数据处理
AIGC浪潮对数据中心基础设施发展的影响
【1月更文挑战第19天】AIGC浪潮对数据中心基础设施发展的影响
375 1
AIGC浪潮对数据中心基础设施发展的影响
|
安全 C# 开发者
C#中的默认接口方法:接口演化的新篇章
【1月更文挑战第11天】本文探讨了C# 8.0中引入的默认接口方法,这一特性允许在接口中定义具有默认实现的方法。文章介绍了默认接口方法的语法、使用场景,以及它们如何影响接口的设计和实现,同时讨论了默认接口方法带来的好处和潜在的陷阱。
|
Unix 编译器 Linux
【计算机基础 ELF文件】深入探索ELF文件:C++编程中的关键组成部分
【计算机基础 ELF文件】深入探索ELF文件:C++编程中的关键组成部分
751 0
|
存储 缓存 开发工具
ZYNQ-双核AMP通信(一)
ZYNQ-双核AMP通信(一)
1869 0
ZYNQ-双核AMP通信(一)
|
7月前
|
人工智能 Java 程序员
一文彻底搞明白电路图和原理图
本文介绍电路图的基本构成、作用及类型,帮助理解电路原理和实际应用。元件符号、连线、节点和注释说明是电路图的核心要素,通过原理图、方框图、装配图和印板图,可以清晰展示电路结构和工作原理。君志所向,一往无前!
2671 0
|
JavaScript 前端开发 API
python对接API二次开发高级实战案例解析:百度地图Web服务API封装函数(行政区划区域检索、地理编码、国内天气查询、IP定位、坐标转换)
python对接API二次开发高级实战案例解析:百度地图Web服务API封装函数(行政区划区域检索、地理编码、国内天气查询、IP定位、坐标转换)
792 0
|
Web App开发 数据可视化 JavaScript
动画墙纸:将视频、网页、游戏、模拟器变成windows墙纸——Lively Wallpaper
动画墙纸:将视频、网页、游戏、模拟器变成windows墙纸——Lively Wallpaper
381 0
|
存储 安全 Windows
Windows无法完成格式化怎么办?5种解决方法
在使用电脑时,我们有时会遇到“Windows无法完成格式化”的问题,这可能由磁盘写保护、权限限制、物理损坏或磁盘占用等原因引起。为解决这个问题,可以尝试关闭写保护开关、提升格式化权限、使用第三方工具、在CMD中用diskpart命令格式化或检查磁盘健康状况。如果磁盘有重要数据,可以先用数据恢复软件拯救数据。如果以上方法无效,可能需要专业售后检查修复或更换硬件。记得在操作前备份重要文件,以防数据丢失。
|
程序员 C语言 C++
C语言中的goto语句:使用、争议与最佳实践
C语言中的goto语句:使用、争议与最佳实践
1093 1
【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例
【ZYNQ】SPI 简介及 EMIO 模拟 SPI 驱动示例
1383 0