RISC_V_外设_I2C

1. I2C背景知识介绍

I2C总线,全称为Inter-Integrated Circuit(集成电路互联总线),是MCU中常用的接口模块。
它是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。

2. I2C特点

  1. I2C有两根线路组成:一条串行数据线(SDA)和一条串行时钟线(SCL)。
  2. 每个连接到总线的设备都有一个唯一的地址。
  3. 真正的多主机总线,当两个或多个主机同时发起数据传输时,可以通过仲裁机制来防止数据被破坏。
  4. SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出,在使用的时候需要通过上拉电阻接电源,两根线都是高电平。
    [注1. 从机的SCL是单向的输入口]
  5. SCL的时钟频率可以由主机进行配置。
  6. 串行的8bit双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s。
  7. 连接到相同总线的I2C数量只受到总线的最大电容400pF的限制。
  8. I2C通信的数据以8bit为单位,每次发送完一个数据都要等待接收方的ACK信号。

3. I2C内容

3.1 I2C条件判断

SDA 线上的数据必须在时钟的高电平周期保持稳定数据线的高或低电平状态,
只有在SCL 线的时钟信号是低电平时才能改变。为传输的每个数据位生成一个时钟脉冲。

3.1.1 START and STOP 条件

所有的传输都是所有事务都以START(S)开始,并由STOP(P)终止(见图5)。
在这里插入图片描述

  1. SCL 线是高电平时,SDA 线从高电平向低电平切换,表示起始条件。

  2. SCL 是高电平时,SDA 线由低电平向高电平切换,表示停止条件。

起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态,
在停止条件的某段时间后,总线被认为再次处于空闲状态总线的空闲状态将在第15 章详细说明
如果产生重复起始Sr 条件而不产生停止条件总线会一直处于忙的状态此时的起始条件S和重复起始Sr 条件在功能上是一样的见下文。

3.1.2 Rep Start条件,Write条件,Read条件

  1. Rep Start:和start条件一样,在SCL为高电平的时候,SDA下降为低电平,表示一个新的起始。
    在这里插入图片描述
  2. write标志和read标志:I2C总线在write状态的时候,SDA只能在SCL为低的时候改变状态,在SCL为高是,保持SDA的值。
    总线在Read状态的时候,与write相同。

3.2 数据传输

在这里插入图片描述

3.2.1 传输格式

发送到SDA 线上的每个字节必须为8 位每次传输可以发送的字节数量不受限制,每个字节后必须跟一个响应位,首先传输的是数据的最高位MSB 。
如果从机要完成一些其他功能,例如一个内部中断服务程序才能接收或发送下一个完整的数据字节,可以使时钟线SCL 保持低电平迫使主机进入等待状态,当从机准备好接收下一个数据字节并释放时钟线SCL 后数据传输继续。

3.2.2 响应

响应发生在每个字节之后。 应答位允许接收器向发送器发信号通知该字节已成功接收,并且可以发送另一个字节。 主机产生所有时钟脉冲,包括应答第9个时钟脉冲。
响应分为ACK和NACK。

  1. ACK 信号:在响应的时钟脉冲期间,接收器必须将SDA 线拉低,使它在这个时钟脉冲的高电平期间保持稳定的低电平 。当然必须考虑建立和保持时间。

  2. NACK信号:当在第9个时钟脉冲期间SDA保持高电平时,这被定义为非应答信号。主设备可以生成STOP条件以中止传输,或者生成重复的START条件以开始新的传输。 导致生成NACK的条件有五个:

  • 总线上没有带有发送地址的接收器,因此没有设备响应确认。
  • 接收器无法接收或发送,因为它正在执行某些实时功能,并且尚未准备好开始与主站通信。
  • 在传输过程中,接收器获取它不理解的数据或命令。

  • 在传输过程中,接收器无法再接收数据字节。

  • 主接收器必须发信号通知从发送器的传输结束。

3.3 时钟同步和仲裁(多主机)

两个主设备可以同时开始在空闲总线上进行传输,并且必须有一种方法来决定哪个控制总线并完成其传输。 这是通过时钟同步和仲裁完成的。 在单主系统中,不需要时钟同步和仲裁。

3.3.1 时钟同步

时钟同步通过线与连接I2C 接口到SCL 线来执行。这就是说SCL 线的高到低切换会使器件开始数它们的低电平周期,而且一旦器件的时钟变低电平,它会使SCL线保持这种状态直到到达时钟的高电平。但是,如果另一个时钟仍处于低电平周期,这个时钟的低到高切换不会改变SCL线的状态。因此,SCL线被有最长低电平周期的器件保持低电平,此时,低电平周期短的器件会进入高电平的等待状态。
在这里插入图片描述
当所有有关的器件数完了它们的低电平周期后,时钟线被释放并变成高电平。之后器件时钟和SCL线的状态没有差别。而且所有器件会开始数它们的高电平周期。首先完成高电平周期的器件会再次将SCL线拉低。

这样,产生的同步SCL时钟的低电平周期由低电平时钟周期最长的器件决定,而高电平周期由高电平时钟周期最短的器件决定。

3.3.2 仲裁

仲裁与同步一样,只有在系统中使用多个主设备时才需要协议的一部分。主机只能在总线空闲的时侯启动传输。两个或多个主机可能在起始条件的最小持续时间(tHD;STA)内产生一个起始条件,结果在总线上产生一个规定的起始条件。

当SCL 线是高电平时,仲裁在SDA 线发生;这样,在其他主机发送低电平时,发送高电平的主机将断开它的数据输出级,因为总线上的电平与它自己的电平不相同。

仲裁是逐位进行的,在每个位期间,当SCL为高电平时,每个主器件都会检查SDA电平是否与它发送的电平相匹配。 此过程可能需要很多位。 只要传输完全相同,两个主设备实际上可以无错误地完成整个事务。 主设备第一次尝试发送HIGH,但检测到SDA电平为低电平,主机知道它已经丢失仲裁并关闭其SDA输出驱动器。

因为,I2C 总线的地址和数据信息由赢得仲裁的主机决定,在仲裁过程中不会丢失信息。丢失仲裁的主机,可以产生时钟脉冲直到丢失仲裁的该字节末尾。

如果主机也结合了从机功能,而且在寻址阶段丢失仲裁,它很可能就是赢得仲裁的主机在寻址的器件。因此,丢失仲裁的主机必须立即切换到它的从机模式。
在这里插入图片描述
由于I2C总线的控制仅取决于竞争主机发送的地址和数据,因此没有中央主机,也没有总线上的任何优先级顺序。

如果在一个主设备发送重复START或STOP条件而另一个主设备仍在发送数据时仲裁过程仍在进行中,则存在未定义的条件。 换句话说,仲裁在不能下面情况之间进行:

  • 重复起始条件和数据位:主设备1发送重复的START条件,主设备2发送数据位。
  • 停止条件和数据位:主设备1发送STOP条件,主设备2发送数据位。
  • 重复起始条件和停止条件:主站1发送重复的START条件,主站2发送STOP条件。

3.4 Clock stretching

时钟延长通过将SCL线保持为低电平来暂停事务。 在该行再次释放HIGH之前,该事务不能继续。 时钟延长是可选的,事实上,大多数从设备不包括SCL驱动程序,因此它们无法延长时钟。

在字节级,设备可能能够以快速速率接收数据字节,但需要更多时间来存储接收到的字节或准备另一个要传输的字节。 然后,从器件可以在接收和确认一个字节后将SCL线保持为低电平,以强制主器件进入等待状态,直到从器件准备好在一种握手过程中进行下一个字节传输。

在位级,诸如具有或不具有用于I2C总线的有限硬件的微控制器的设备可以通过延长每个时钟LOW周期来减慢总线时钟。 任何主站的速度都适合该设备的内部运行速率。

3.4 地址格式

3.4.1 7位寻址

数据的传输遵循图10 所示的格式,在起始条件S 后发送了一个从机地址,这个地址共有7 位,紧接着的第8 位是数据方向位R/W ,0 表示发送写,1 表示请求数据读,数据传输一般由主机产生的停止位P 终止,但是如果主机仍希望在总线上通讯它可以产生重复起始条件Sr和寻址另一个从机,而不是首先产生一个停止条件,在这种传输中可能有不同的读写格式结合。
在这里插入图片描述

3.4.2 广播呼叫地址

I2C 总线的寻址过程是通常在起始条件后的第一个字节决定了主机选择哪一个从机例外的情况是可以寻址所有器件的广播呼叫地址使用这个地址时理论上所有器件都会发出一个响应但是也可以使器件忽略这个地址。
如果器件要求从广播呼叫地址得到数据它会响应这个地址并作为从机-接收器运转,第二个和接下来的字节会被能处理这些数据的每个从机-接收器响应。广播呼叫地址的含意通常在第二个字节说明。

3.4.3 10位寻址

10位寻址扩展了可能的地址数量。 具有7位和10位地址的器件可以连接到同一个I2C总线,7位和10位寻址都可以用于所有总线速度模式。 目前,10位寻址没有被广泛使用。

10位从地址由START条件(S)或重复START条件(Sr)之后的前两个字节构成。

第一个字节的前七位是组合1111 0XX,其中最后两位(XX)是10位地址的两个最高有效位(MSB); 第一个字节的第八位是决定消息方向的R / W位。

尽管保留地址位1111XXX有八种可能的组合,但只有四种组合1111 0XX用于10位寻址。 其余四种组合1111 1XX保留用于未来的I2C总线增强。

之前针对7位寻址描述的读/写格式的所有组合都可以通过10位寻址实现。 这里有两个详细说明:

主机发送器传输10位从地址发送到从接收器。

主接收器使用10位从地址读取从发送器。

3.5 总线速度

最初,I2C总线限制为100 kbit / s操作。 随着时间的推移,规范已经增加了几个,因此现在有五种运行速度类别。 标准模式,快速模式(Fm),快速模式加(Fm +)和高速模式(Hs模式)设备向下兼容 - 任何设备都可以在降低总线速度。

超快速模式设备与以前的版本不兼容,因为总线是单向的。

双向总线:

  • 标准模式(Sm),比特率高达100 kbit / s
  • 快速模式(Fm),比特率高达400 kbit / s
  • 快速模式加(Fm +),比特率高达1 Mbit / s
  • 高速模式(Hs模式),比特率高达3.4 Mbit / s

带有快速或Hs 模式I2C 总线接口的新从机器件可以有7 位或10 位的从机地址,如果可能的话首选7 位地址因为它是最便宜的硬件解决方案而且报文长度最短

单向总线:

  • 超快速模式(UFm),比特率高达5 Mbit / s

4. RISC_V I2C Master详解

在蜂鸟e203中,采用的是Open core的开源I2C,感兴趣的同学可以在opencore上自行下载,整个模块分为三个层次:

  • 顶层模块 :master_top
  • byte读写模块 :byte_controller
  • bit读写模块 :bit_controller

4.1 顶层模块

在这里插入图片描述

顶层模块如图所示,定义了一个时钟端口,两个复位端口.
因为I2C模块是通过Wishbone总线进行输入,所以相应的有we,stb和cyc三个使能输入端口
Wb_adr_i和Wb_dat_i是地址和数据输入,adr端口连接到7个可配置寄存器,如下表所示。
这里要注意,opencore的I2C并没有直接定义双向端口SCL,SDA,所以需要我们自己在外面接一个IOBUF来驱动SCL和SDA总线,如下图所示:
在这里插入图片描述
顶层模块原理图:
在这里插入图片描述
寄存器配置表:
在这里插入图片描述
[注]表中寄存器在E203系统中的基地址位0x1004_20xx.

4.1.1 prescale 寄存器

prerlo和prerhi是时钟分频寄存器,通过对I2C模块所在时钟域的时钟,进行分频,然后得到SCL的时钟频率,计算公式为:
Prescale寄存器的值=“I2C模块所处的时钟域的时钟频率”/((5*“SCL时钟频率”)-1)。

4.1.2 CTR寄存器

CTR寄存器是控制寄存器,用来控制I2C模块的功能和中断,控制信号分别对应Wb_dat_i的第7位和第6位,如下表所示:
在这里插入图片描述

4.1.3 TXR和RXR寄存器

I2C模块通过I2C_TXR寄存器发送数据,通过I2C_RXR寄存器接收数据。
TXR和RXR寄存器共用一个地址,一个负责写,一个负责读。
[注]I2C协议规定,在I2C传输从设备地址字节是,最低位表示读或者写操作。

4.1.4 CR和SR寄存器

I2C模块通过CR寄存器发送命令请求,CR寄存器在每个命令完成之后都会自动清除,因此I2C需要在发送命令之前重新对命令寄存器写值。
SR寄存器为只读寄存器,负责查看I2C的状态,其功能如下表所示。
CR寄存器:
在这里插入图片描述
SR寄存器:
在这里插入图片描述

4.2 byte 和 bit 子模块

4.2.1 byte_controller模块

byte_controller以字节为单位处理I2C的数据, 它从命令寄存器中获取数据,并根据单个字节的传输将其转换为序列。 例如,通过将命令寄存器中的START,STOP和READ位置1,字节命令控制器会生成一个序列,该序列导致产生START信号,从从设备读取一个字节并产生一个字节。 停止信号。 它通过将每个字节操作划分为单独的位操作来完成此操作,然后将这些位操作发送到位命令控制器。
在这里插入图片描述

4.2.2 bit_controller模块

bit_controller通过控制SCL和SDA线的oen来处理数据的实际传输以及START,重复的START和STOP信号的特定电平的生成。 字节命令控制器告诉位命令控制器必须执行哪个操作。 对于单字节读取,位命令控制器接收8个单独的读取命令。 每个位操作分为5个部分(空闲和A,B,C和D),而STOP操作分为4个部分(空闲和A,B和C)。
在这里插入图片描述

5.iic slave

Opencore的I2C_SLAVE只有两个端口SCL,SDA,其中SDA是双向端口。
Slave在检测到start标志和stop标志时,产生复位信号,随后根据命令进行数据传输,
如下图所示:
在这里插入图片描述

6. 参考文献

[1]广州周立功单片机发展有限公司.《I2C总线规范》.
[2]电子工程世界.《I2C总线详解笔记》.
[3]胡振波.《RISC-V架构嵌入式开发快速入门》.

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最近一个项目需要做I2C的slave,在opencores.org上面找到了一个I2C的代码,不过是master的。 下载来看看,发现里面有一个I2C slave的行为级代码。 于是自己根据这个代码改写了一个I2C slave RTL的代码,并修改了原来那个设计的testbench,将rtl的Slave替换了原来的behavior的Slave,在modelsim里面作了前仿,完全通过。还有一个myram.v文件,是一个register file,和slave相连,存储数据用的。 用synplify做综合,使用x3s400-4的器件,占用LUT<100,速度接近200MHz。性能比较优化。 代码做了详尽的注释,语言采用verilog,并且写了仿真的脚本。解压了直接运行simbehav.bat就可以了。如果modelsim安装的时候注册了环境变量(path),脚本调用modelsim,输入run -all即可看到仿真结果。 虽然不是很复杂,不过对于广大需要做I2C的RTL slave的工程师来说,还是很有参考价值的。 1、 设计流程 将I2C slave的行为模型改为rtl模型。 进行等效仿真,直到波形一致,通过timing check,数据正确。 再进行rtl优化设计 2、 注意要点 a) 时钟的设计 b) 对于restart condition的时序是否正确 c) 3、 进度 a) 11-12:initial状态的bitcnt不对,需要认真比对/设计 b) 11-13:initial基本解决(sda_in的问题)。Sda三态冲突,原因不明。比对原设计 c) 11-14:sda三态冲突解决,原因为sda在初始化时没有将sda_oen赋值(由sm赋值,但是sm没有做async reset)。同时注意verilog的大小写敏感。 d) 11-15:仿真出现错误:read出来的数据非期望值。写入逻辑完全正确。Read时由于sda_oe在sm中有一个cycle_pulse的延迟,导致了mem_do[7]串行移出时错位。在更改了sm的代码风格后再研究解决方法。 e) 11-16:仿真完全匹配波形。计划:优化结构,提高稳定性sm改为每个时钟打一下。 关于I2C的SDA三态转换: Master在发送完第8个bit后随后将sda释放(posedge后大概1/4 scl周期),此时slave需要在第九个bit对应的scl的posedge拉低sda。
### 回答1: RISC-V C函数手册是一个详尽的手册,为开发人员提供了RISC-V平台上可用的所有C语言函数的详细信息。该手册包含用于基本数字操作、内存操作、字符串操作、数学函数、IO操作、系统调用等各种功能的C函数。可以说这是一个非常有用的手册,因为它使开发人员能够快速了解和使用RISC-V平台上的各种功能,从而提高开发效率。 该手册的目录非常详细,其中包括函数名、函数声明、功能描述、输入参数、输出参数、返回值等重要信息。这些信息对于开发人员来说是非常重要的,在开发过程中可以帮助他们更好地理解函数的用途,正确地使用函数,并在需要的时候进行必要的调试和修复。 总之,RISC-V C函数手册是RISC-V平台上C程序开发人员必备的参考资料。从它身上可以获得关键信息,这有助于开发人员开发可靠的软件,并提高软件的质量和性能。随着RISC-V平台的不断发展和应用,该手册将不断更新和改进,以提供更全面、更有用的信息和功能。 ### 回答2: RISC-V是一种基于开源架构的指令集体系结构。为了方便程序员进行开发,RISC-V有一个官方的C语言函数手册。这个手册中包含了所有RISC-V平台上使用的C语言函数。这些函数可以帮助程序员在开发过程中轻松地完成各种操作,比如说内存管理、文件管理、字符串操作等等。 C函数手册大大减少了程序员的代码编写工作。因为这个手册收录了所有常用的C语言函数,程序员可以直接使用这些函数,而不必自己编写代码。这样可以节省时间和精力,让程序员可以更专注于开发自己的业务逻辑部分。 除了常用的C语言函数之外,RISC-V的C函数手册还包含了一些平台相关的函数,这些函数可以帮助程序员处理一些特殊的问题,比如说操作寄存器、处理中断等等。这些函数在操作系统和嵌入式领域非常有用,可以帮助程序员编写出高效、精简的系统代码。 总的来说,RISC-V的C函数手册是一份非常有价值的文档,对于RISC-V开发者来说具有重要意义。它可以帮助程序员更快速地开发出高效的程序,提高开发效率和质量。 ### 回答3: RISC-V C函数手册是RISC-V CPU架构的指令集架构的一部分,它提供了一套用于C编程的系统调用接口和C库函数。在RISC-V指令集架构中,操作系统可以使用该手册的函数和接口来与硬件驱动程序交互,管理内存,进行进程控制等操作。 RISC-V C函数手册包含几个关键部分,以支持C编程和系统调用。这些部分包括标准C库函数、系统调用接口、定时器和计时器接口、异常处理等。 标准C库函数提供了标准数学函数,字符串和输入输出操作等常见的C库函数操作。这些函数与RISC-V硬件指令集紧密配合,提供了基本的编程支持。 系统调用接口是RISC-V C函数手册的核心部分,它允许应用程序与操作系统进行交互。例如,系统调用可以管理进程,分配和释放内存,以及管理文件系统。 另外,RISC-V C函数手册还提供了定时器和计时器接口,以支持测量和管理时间。这些接口是应用程序和操作系统中实现各种计时和延迟的基础。 异常处理是RISC-V C函数手册中的另一个重要部分。它提供了在处理硬件设备故障,例如页错误,系统中断和总线故障等方面的支持。 总之,RISC-V C函数手册是一个完整的C库,它为RISC-V CPU架构提供了完整的编程支持。它包含许多关键部分,包括标准C库函数、系统调用接口、定时器和计时器接口、异常处理等,以支持各种常见操作和系统级函数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值