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

news/2024/4/29 13:17:46/文章来源:https://blog.csdn.net/SuperiorEE/article/details/129854790

一、基本介绍

  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 beginclkdiv=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@(*)beginif(IIC_S==IDLE || IIC_S ==STOP1 || IIC_S ==STOP2)scl_r<=1'b1;elsescl_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(写)这两种指令。每次主机发送一种指令都需要一个起始位。因此读写转换,写读转换都需要重新发送起始位。
  我们以随机读为例,随机读相对于直接读,前面多了俩字节,而后面的两字节(主机往总线上写入读指令,主机接收读到的数据)是相同的。前面的两字节是往总线上写入写指令和写地址,我们比较一下写字节指令,只给出了要写的地址,并未给出要写的数据,因此它可以改变内部指针计数器,而并未真的写入,这样就实现了随机读的功能。
  基于以上分析,就有了下述状态机的设计。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283247.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

upload-labs pass6-pass10

1.pass-6黑名单 空格绕过 直接上传肯定不可以 这个地方配置文件虽然只过滤了.htaccess&#xff0c;.user.ini也是不可用的&#xff0c;因为这里进行了重命名&#xff0c;通过代码审计可以发现空格没有过滤&#xff0c;这是利用windows的一个特性&#xff0c;后缀后面有空格和…

EasyCVR在公共资源交易中心监控视频汇聚项目中的场景应用方案

一、背景分析 2019年5月&#xff0c;国务院办公厅印发了《国务院办公厅转发国家发展改革委关于深化公共资源交易平台整合共享实施意见的通知》&#xff08;国办函〔2019〕41号&#xff09;&#xff0c;明确深化公共资源平台整合共享&#xff0c;要求地方各级人民政府制度细化落…

1.8 函数的连续与间断

我的理解&#xff1a; 注意&#xff1a; 在处理连续性问题时&#xff0c;需要注意以下几点&#xff1a; 连续函数在一段区间内的取值具有稳定性和连续性&#xff0c;因此可以使用它们来刻画某个过程的规律。 如果一个函数在某个点处不连续&#xff0c;那么这个点就是一个间断…

C语言预处理命令(宏定义和条件编译)

C语言预处理命令&#xff08;宏定义和条件编译&#xff09; 前言 在编译和链接之前&#xff0c;还需要对源文件进行一些文本方面的操作&#xff0c;比如文本替换、文件包含、删除部分代码等&#xff0c;这个过程叫做预处理&#xff0c;由预处理程序完成。 较之其他编程语言&am…

图像复原论文阅读:GRL算法笔记

标题&#xff1a;Efficient and Explicit Modelling of Image Hierarchies for Image Restoration 会议&#xff1a;CVPR2023 论文地址&#xff1a;http://arxiv.org/abs/2303.00748 官方代码&#xff1a;https://github.com/ofsoundof/GRL-Image-Restoration 作者单位&#xf…

国产化复旦微电子 FMQL45T900 替代Xilinx ZYNQ ARM+FPGA 7045方案(评论区有联系方式)

FM4550国产化开发板 功能接口 - - 系统框图 - - 对应参数 - 1.主要参数 系统1&#xff1a; FPGA型号&#xff1a;FMQL45T900 PS内核&#xff1a;四核ARM Cortex-A7&#xff0c;主频800MHz PS端内存&#xff1a;1GB DDR3,数据速率1066Mbps&#xff0c;32bit PL端内存&…

vagrant无剩余磁盘空间,无法连接Mysql

vagrant无剩余磁盘空间&#xff0c;无法连接Mysql 参考博客1 参考博客2 1.报错&#xff1a;设备上没有剩余空间 C:/HashiCorp/Vagrant/embedded/gems/2.2.19/gems/net-scp-3.0.0/lib/net/scp.rb:398:in await_response_state: \x01scp: /tmp/vagrant-network-entry-eth1-1680…

工业树莓派如何保障电气安全?

一、应用背景 电气系统主要用于传输和分配电力&#xff0c;是工业生产过程中不可或缺的组成部分&#xff0c;广泛应用于工业自动化控制、机器人、电动汽车等领域。因此&#xff0c;实时监测电气系统具有重要意义。 电流是电气系统中最基本的参数之一&#xff0c;实时监测电气…

[Linux]管理文件基本操作

​⭐作者介绍&#xff1a;大二本科网络工程专业在读&#xff0c;持续学习Java&#xff0c;输出优质文章 ⭐作者主页&#xff1a;逐梦苍穹 ⭐所属专栏&#xff1a;Linux基础操作。本文主要是分享一些Linux系统常用操作&#xff0c;内容主要来源是学校作业&#xff0c;分享出来的…

0118 定时任务调度

任务调度&#xff1a;指系统在某个时间执行的特定的命令或程序 任务调度分类&#xff1a; 系统工作&#xff1a;有些重要的工作必须周而复始地执行&#xff0c;如病毒扫描等 个别用户工作&#xff1a;个别用户可能希望执行某些程序&#xff0c;如对MySQL数据库的备份 1.cro…

攻防世界web2、ddctf_2019_homebrew_event_loop、 [网鼎杯 2018]Fakebook

web2 进入环境得到源码 <?php $miwen"a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";function encode($str){$_ostrrev($str);// echo $_o;for($_00;$_0<strlen($_o);$_0){$_csubstr($_o,$_0,1);$__ord($_c)1;$_cchr($__);$_$_.$_c; } …

MySQL之事务和锁机制

文章目录一、事务1.1 事务特征1.2 隔离级别1.3 开启事务二、锁机制2.1 读锁、写锁2.2 全局锁、表锁、行锁2.3 记录锁、间隙锁、临键锁提示&#xff1a;以下是本篇文章正文内容&#xff0c;MySQL 系列学习将会持续更新 一、事务 在数据库里面&#xff0c;我们希望有些操作能够以…

CSS模块的书写以及删除线的作用和来历什么是删除线

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/*关羽这一行代码变为绿色*/#gy_li{color: green}/*张飞,苹果这一行代码变为黄色*/#zf_li,#pg_ul{color: yellow}/*i…

华为OD机试题 Q2 押题【贪心的商人 or 最大利润】用 C++ 编码,速通

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:贪心的商人 or 最大利润 题目…

GEE:数据结构——Object 对象(创建、访问、修改、删除、遍历)

在Google Earth Engine (GEE) 平台中&#xff0c;“Object” 是指一种数据结构&#xff0c;它是由一组属性&#xff08;键-值对&#xff09;&#xff08;key-value&#xff09;组成的&#xff0c;可以是数字、字符串、布尔值、数组或其他对象。 在 GEE 中&#xff0c;许多数据…

实战:向人工智能看齐用Docker部署一个ChatGPT

文章目录前言鉴赏chatgpt环境要求开始搭建云安装docker从docker仓库拉取chatgpt-web镜像创建容器并运行chatgpt-web创建容器启动chatgpt-web访问自己的chatgpt总结前言 目前GPT-4都官宣步入多模态大型语言模型领域了&#xff0c;大佬竟然还没有体验GPT么。作为一个资深搬砖人士…

【C++修行之路】面向对象三大特性之多态

文章目录前言认识多态构成多态的必要条件虚函数的重写虚函数重写的两个例外final和override重载、覆盖、隐藏抽象类多态的原理单继承多继承重写了基类的虚函数没有重写基类的虚函数菱形继承和菱形虚拟继承的虚表补充补充继承与多态相关问题inline函数可以是虚函数吗&#xff1f…

2.半导体二极管

1.半导体二极管二极管的组成二极管和PN结伏安特性的区别二极管的伏安特性及电流方程为什么反向饱和电流越小&#xff0c;单向导电性能越强。二极管的等效电路二极管的主要参数稳压二极管&#xff08;又称齐纳二极管或反向击穿二极管&#xff09;稳压二极管与普通二极管的区别其…

深入理解MCU启动原理

前面写了一篇 STM32的完整启动流程分析&#xff0c;但是感觉有些地方没有完全理明白&#xff0c;因此对不清楚的地方又做了一些总结。 1. MCU最开始一启动后去哪里读代码&#xff1f; CPU上电启动后被设计为去地址0x00000000位置处读取代码&#xff1b;首先会连续读取两个字&…

Linux ELK日志分析系统 | logstash日志收集 | elasticsearch 搜索引擎 | kibana 可视化平台 | 架构搭建 | 超详细

Linux ELK日志分析系统 | logstash日志收集 | elasticsearch 搜索引擎 | kibana 可视化平台 | 架构搭建 | 超详细ELK 日志分析系统1.日志服务器2.ELK 日志分析系统3 日志处理步骤一、 Elasticsearch 介绍1.1概述1.2核心概念二、Kibana 介绍三 ELK架构搭建3.1 配置要求3.2 安装 …