【协议项目之 I2C】(一) 基本时序与实现

2023-05-16

一、基本介绍

  I2C协议(集成电路总线)使用两根线SDASCL实现数据传输,其连接如下图所示,总线上通过上拉电阻可以挂载各种低速外设,例如EEPROM 24C02,传感器等。
在这里插入图片描述
  使用I2C,可以将多个从机(Slave)连接到单个主设备(Master),并且还可以有多个主设备(Master)控制一个或多个从机(Slave)

一、启动时序与时钟产生(START condition)

  启动时序如下图所示,
在这里插入图片描述
  在总线空闲时,SDA,SCL都处于高电平。而在启动I2C传输时,主设备先将SDA拉低,再将SCL拉低。开始标志之后,就开始传输数据,传输数据要求保证在SCL的高电平时期保持不变,否则会被误识别为停止标志或者其他标志。
  假设SDA是sda_clk的时钟下降沿发生变化,其中sda_clk是I2C模块的内部时钟之一。带有sda_clk的参考时序图如下所示。
1
  该图的绘制代码如下,可以在这个网站使用js进行绘制

{signal: [
  {name:'scl_clk',wave:'p.......|',data:['data1','data2','data3']},
  {name:'SDA',wave:'1.0====|.',data:['data1','data2','data3'],phase:-0.5},
  {name:'SCL',wave:'1.0p....',data:['data1','data2','data3'],phase:-0.75},
]}

  如上图,以scl_clk为基准参考,SDA是由该时钟生成的同步电路,并且我们就假设SDA都是在时钟下降沿发生变化。由于SCL需要满足I2C协议中的以下两个条件

1.在启动时序中,SCL其拉低是在SDA之后的,而SDA拉低是在时钟下降沿(以上升沿为参考,下降沿的相位移动是phase:-0.5,遵循函数左加右减规则)
2.SCL的高电平区域在传输数据时不允许SDA发生跳变,即SDA的数据变化必须落在SCL的低电平区域

  基于以上的要求,我们可以推导出时钟相关信号的生成步骤

在这里插入图片描述

  时钟产生的逻辑是,首先对高速时钟进行1000分频(即添加500计数器clk_div,每数到500就进行一次翻转),这样就生成了时钟scl_clk;

//scl_clk生成(驱动sda)
always@(posege clk_i)
	if(clkdiv < CLK_DIV)
		clkdiv=clkdiv+1'b1;
	else begin
		clkdiv=16'd0;
		scl_clk<=!scl_clk;
	end

  接着,根据scl_clk生成下降沿转换的状态机IIC_S。SDA由状态机的状态组合逻辑产生,也是在scl_clk下降沿跳变。
  由于SCL需要满足两个条件(上文提到)。我们先产生与时钟下降沿对齐的scl_r中间信号,然后再进行调整。scl_r的逻辑就是在IDLE或者STOP1/2这些状态为高,其余状态为scl_clk的取反。

//scl_r生成逻辑,IIC_S为状态机状态
always@(*)begin
	if(IIC_S==IDLE || IIC_S ==STOP1 || IIC_S ==STOP2)
		scl_r<=1'b1;
	else
		scl_r<=~scl_clk;

  为了满足两个条件,我们发现只要把scl_r略微右移就可以实现。为了实现略微右移,我们先生成scl_offset信号。

parameter OFFSET=CLKDIV-CLK_DIV/4;
wire scl_offset=(clkdiv==OFFSET);

  scl_clk是在clk_div==CLKDIV时候翻转,而scl_offset比其早了0.25个CLKDIV计数,其关系如上图所示。
  我们基于scl_offsetscl_r进行滞后采样,根据图上关系所示,从而生成SCL波形(iic_scl),这样可以满足两个条件

	iic_scl<=scl_offset?scl_r:iic_scl;

二、停止时序(STOP condition)

  I2C协议中对停止时序的要求是,SCL先拉高,然后SDA再拉高。这个时序刚好与启动时序相反。由于上一节中提到,SCL是scl_r滞后采样得到的,因此需要SCL率先拉高,就需要scl_r比SDA率先拉高。因此可以将STOP状态定义为两个状态,STOP1和STOP2.
在这里插入图片描述

  如果只有一个停止·状态(例如只有stop1),那么SDA就要在STOP位置高,如上图SDA_wrong所示,而scl_r也同样在此时置高,SCL滞后于scl_r,这样就会导致SCL比SDA_wrong更晚拉高,不满足停止时序所要求的SCL率先拉高。
  因此我们分出两个停止状态STOP1,STOP2,将scl_r现在STOP1就拉高,而将SDA在STOP2再拉高,这样一来就满足了SCL先于SDA拉高的时序,并且两者拉高的间隔小于一个scl_clk时钟周期(由于滞后采样的原因)

三、状态机分析(基于EEPROM应用)

  以上只是简单写一个包(8bit)的状态演示,其状态还不够完备。
  由于是想要用于驱动E2PROM的,因此有些完备状态的补充,我们需要参考E2PROM的用户手册

字节写

  如下图所示,为字节写的时序,本质是实现了连续三次的写数据。首先是开始标志,标志着I2C传输的开始。然后紧接着是八位指令
在这里插入图片描述
  该指令构成如下
在这里插入图片描述
  其中1010是该器件24C02内部规定好的,用于标志总线的设备类型,其实属于地址的一部分,用来区分不同的设备。然后后面紧接着的A2 to A0是器件的地址,可以在器件的这三个引脚给出高低电平来设置某个EEPROM 24C02器件的地址。最后一位是度或者写指令,其中为0表示写为1表示读。
  以上就是指令的构成格式。指令结束后,经过一位ACK,然后主机在总线上写入连续8位(第二个包,指令是第一个包)作为写入E2PROM的地址,然后再经过一位ACK,主机在总线上写入连续8位(第三个包)作为数据,最后经过一位ACK产生停止标志,这样就完成了对特定地址的写操作。
  因此,从字节写操作中,我们发现对状态的要求有:在一个包内,需要能用重复发8bit数据。此外包与包之间是连续发送,仅隔了一个ACK,并没有经历新的START。所以发完一个包并不能进入STOP和IDLE状态。因此我们设计满足字节写操作的状态机如下图所示。
在这里插入图片描述

连续写(写一页(8BYTE))

在这里插入图片描述

  是写一个字节操作的扩展,可以发现上述状态机仍然满足连续写,只是再下一个包的循环中多循环几轮的差别,我们可以再状态转移逻辑中对其进行设置,例如设置一个写包计数器,来表征需要连续写入字节的个数,计数器归零后发送停止条件。

读当前字节

在这里插入图片描述

  EEPROM内部是有指针的,内部计数器指向上一个操作地址的下一地址空间。
  如时序图所示,主设备写入读命令后,接收到EEPROM的一个ACK回答,然后连续在总线上读取8位数据地址(其中高位在前),主器件接收完毕后,无需回送ACK,只需要发送停止标志即可。

读随机字节

在这里插入图片描述

  随机读,即读特定地址的一个字节的数据,时序如上图所示。主机先在总线上写1Byte的指令来表征要进行写操作,紧接着写需要读的8位地址。然后再重新给出起始条件,转为在总线上写1Byte的指令来表征要进行的读操作,然后再读取地址。

连续读字节

  连续读可以理解为读的扩展,不管是直接读还是随机读,都可以发送ACK来继续下一次读取,EEPROM内部计数器会自动加一。
在这里插入图片描述

  综上所述,其实主机发送的指令其实只有两种,分别是读指令和写指令,

76543210
1010A2A1A0W/R

  其中R为1,W为0.由于对应某一个特定的EEPROM器件,其指令高7位地址都是相同的,因此主机对其发送的指令只有最低位为1(读)和最低位为0(写)这两种指令。每次主机发送一种指令都需要一个起始位。因此读写转换,写读转换都需要重新发送起始位。
  我们以随机读为例,随机读相对于直接读,前面多了俩字节,而后面的两字节(主机往总线上写入读指令,主机接收读到的数据)是相同的。前面的两字节是往总线上写入写指令和写地址,我们比较一下写字节指令,只给出了要写的地址,并未给出要写的数据,因此它可以改变内部指针计数器,而并未真的写入,这样就实现了随机读的功能。
  基于以上分析,就有了下述状态机的设计。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【协议项目之 I2C】(一) 基本时序与实现 的相关文章

  • (无人机方向)ros小白学习之路(四)ROS通信机制---服务通信

    文章目录 前言ROS服务通讯定义应用场景实现0 Server注册1 Client注册2 ROS Master实现信息匹配3 Client发送请求4 Server发送响应 服务通信自定义srv创建功能包 然后创建srv文件夹 再创建Addin
  • 修改双系统(win10+ubuntu)启动顺序和启动时间

    安装了ubuntu16 04后 xff0c GNU GRUB引导的默认启动项是ubuntu xff0c 如果希望默认启动项是windows xff0c 修改方法如下 xff1a step1 进入Ubuntu系统 xff0c 打开终端 xff
  • 虚拟帧缓冲驱动

    17 2 2 虚拟帧缓冲驱动 嵌入式Linux系统开发全程解析 是一本全面介绍嵌入式Linux开发的专著 xff0c 书中涵盖了程序生成工具 调试工具 引导加载器 Linux系统结构 Linux内核 驱动程序 用户空间编程 用户空间中间件等
  • 神经网络每次输出不一样,神经网络输出值相同

    BP神经网络最后得出的误差很大 1 看看是不是训练效果好 xff0c 预测效果不好 如果是这样那就是过拟合 网上搜搜有很多解决过拟合的方法 2 如果训练和预测都不好 xff0c 那就是模型有问题 可能原因是 xff08 1 xff09 数据
  • 深度神经网络应用实例

    深度神经网络目前有哪些成功的应用 深度学习最成功的应用是在音视频的识别上 xff0c 几乎所有的商用语音识别都是深度学习来完成的 其次深度学习应用最成功的领域就是图像识别 xff0c 目前识别准确率已经超越人类 深度学习成了图像识别的标配
  • 研究pixhawk的makefile的结构(-)

    首先研究 xff50 xff49 xff58 xff48 xff41 xff57 xff4b 的 xff4d xff41 xff4b xff45 xff46 xff49 xff4c xff45 的结构是怎样的 方便以后开发测试 xff11
  • 制作ROS移动机器人地盘

    制作ROS移动机器人地盘 摘要概述硬件需求车体设计电路设计程序设计PID控制轮速 摘要 本教程讲述如何利用扫地机轮子制作ROS移动机器人地盘 概述 原本不打算自己造轮子的 xff0c 但是网上的移动机器人地盘要么巨贵 对于学生党 xff0c
  • Lumia520刷安卓教程

    Date 2017 09 02 Author SuperDeveloper Descreption install android on luima 520 devices Email na1206 64 live com 警告 本教程只适
  • openwrt编译及第一个安装包教程

    Date 2017 03 14 Made SuperDeverloper Email na1206 64 live com Target For mt7688 based board 说明 xff1a 本人在学习过程中走了不少弯路 xff0
  • turtlebot3 Slam+nvigation仿真 ROS-lunar

    Date 2017 09 06 Author SuperDeveloper Description Slam simulation 说明 xff1a 1 Slam 初学笔记 xff0c 搭建slam仿真环境 xff1b 2 文章里的连接可能
  • 基于NVIDIA Xavier NX(ubuntu20.04)的Optitrack视觉定位 PX4+ros noetic(实物运行记录)

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 xff1a 硬件准备两种界面化显示的方式无线连接有线连接 二 xff1a 软件准备1 远程登录软件 NoMachine2
  • ros机器人搭建总纲

    author xff1a superDeveloper date 2017 11 29 type note 近期准备搭建一个ROS机器人平台 xff0c 建立此博客记录搭建过程以及相关问题的解决办法 xff0c 作为笔记 xff0c 亦供相
  • ros gmapping 运行错误:Assertion 'beams<LASER_MAXBEAMS' failed>

    在使用真实激光器发布数据的时候 xff0c 出现了 Laser is mounted upward警告 xff0c 以及slam gmapping tmp buildd ros hydro openslam gmapping 0 1 0 2
  • realloc():invalid next size....错误

    Author SuperDeveloper Date 2018 1 2 在程序中使用了realloc函数 xff0c 更改结构体数组的大小 xff0c 错误代码如下 xff1a struct point span class hljs su
  • git简单命令笔记

    这是一篇关于git的使用笔记 xff0c 刚刚开始使用git 1 创建git本地仓库 xff1a 在你需要版本控制的项目Project根目录下右键点击Git Bash here执行git init 然后在该目录下生成 一个 git的隐藏文件
  • 源码编译Boost库的正确姿态

    源码编译Boost库的正确姿态 写在前面step 1 step 2 step 3 step4 写在前面 项目需要编译pcl库到arm平台 xff0c 交叉编译Boost xff0c Eigen3 Flann 之后再编译pcl库的时候总是报错
  • 第一讲、四旋翼的整体控制方案

    各位朋友 xff0c 我们工作室以后会长期更新一些飞行器干货 xff0c 本部分先介绍四旋翼的整体控制方案及相关设计 控制系统的框架如下 xff0c 借鉴网上来源图片 xff0c 传感器主要是姿态传感器 xff0c 对于大四轴而言 xff0
  • 网页中屏蔽鼠标右键、Ctrl+N、Shift+F10

    lt script language 61 34 Javascript 34 gt 屏蔽鼠标右键 Ctrl 43 N Shift 43 F10 F5刷新 退格键 屏蔽F1帮助 function window onhelp return fa
  • asp.net上一页下一页的部分代码

    lt asp linkbutton id 61 34 btnFirst 34 nclick 61 34 PagerButtonClick 34 runat 61 34 server 34 CommandArgument 61 34 0 34
  • Visual C# 编程操作Excel

    Visual C 编程操作Excel 2004 08 20 作者 xff1a 邵回祖 出处 xff1a ahcit http www yesky com SoftChannel 72342380468109312 20040819 1844

随机推荐