串行总线协议笔记

 

 

I2C

--INTER-IC串行总线的缩写,是PHILIPS公司推出的芯片间串行传输总线。它以1根串行数据线(SDA)和1根串行时钟线(SCL)实 现了双工的同步数据传输。具有接口线少,控制方式简化,器件封装形式小,通信速率较高等优点。  I2C总线是双向、两线(SCL、SDA)、串行、多主控(multi-master)接口标准,具有总线仲裁机制,非常适合在器件之间进行近距离、非经常性的数据通信。在主从通信中,可以有多个I2C总线器件同时接到I2C总线 上,通过地址来识别通信对象。

IIC 接口的协议里面包括设备地址信息,可以同一总线上连接多个从设备,通过应答来互通数据及命令。但是传输速率有限,标准模式下可达到100Kbps,快速模式下可达到400Kbps(我们开发板一般在130Kbps),高速模式下达到4Mbps,不能实现全双工,不适合传输很多的数据。

IIC总线是一个真正的多主机总线,总线上多个主机初始化传输,可以通过传输检测和仲裁来防止数据被破坏 。

下来详细了解IIC总线时序:

1.1 总线数据有效性

IIC总线是单工,因此同一时刻数据只有一个流向,因此采样有效时钟也是单一的,是在SCL时钟的高电平采样数据。

IIC总线上SDA数据在SCL时钟低电平是可以发生变化,但是在时钟高电平时必须稳定,以便主从设备根据时钟采样数据,如下图:

1.2 总线空闲条件

IIC总线上设备都释放总线(发出传输停止)后,IIC总线根据上拉电阻变成高电平,SDA SCL都是高电平。

 

1.3 总线数据传输起始和结束条件

IIC总线SCL高电平时SDA出现由高到低的跳变,标志总线上数据传输的开始条件

IIC总线SCL高电平时SDA出现由低到高的跳变,标志总线上数据传输的结束条件

 

1.4 总线数据传输顺序以及ACK应答

IIC总线上数据传输室MSB在前,LSB在后,从示波器上看,从左向右依次读出数据即可

IIC总线传输的数据不收限制,但是每次发到SDA上的必须是8位,并且主机发送8位后释放总线,从机收到数据后必须拉低SDA一个时钟,回应ACK表示数据接收成功,我们如果示波器上看到的波形就是每次9位数据,8bit+1bit ack。如下:

 

 

 

 

 

从机收到一字节数据后,如果需要一些时间处理,则会拉低SCL,让传输进入等待状态,处理完成,释放SCL,继续传输,如下:

 

1.5 总线读写时序

数据的传输在起始条件之后,发送一个7位的从机地址,紧接着第8位是数据方向(R/ W),0-表示发送数据(写),1-表示接收数据(读)。数据传输一般由主机产生的停止位(P)终止。但是如果主机仍希望在总线上通讯,它可以产生重复起始条件(Sr),和寻址另一个从机,而不是首先产生一个停止条件。在这种传输中,可能有不同的读/写格式结合。

IIC总线主设备读写从设备,一般都是与从设备的寄存器打交道,这个可以通过阅读从设备的datasheet获取。总线写时序如下:

master start + master addr|w + slave ack + master reg|w + slave ack + master data + slave ack + master restart。。master data + slave nack + master stop

总线读时序如下:

master start + master addr|w + slave ack + master reg|w + slave ack + master restart + master addr|r + slave ack + slave data + master nack + master stop

总线读时序与写的不同之处在于读需要2次传输才能完成一次读取,首先要写寄存器地址到从设备,其实是写到了从设备的控制寄存器或者命令寄存器,从设备内部会根据这个地址来寻址所要操作的寄存器。

我在读我们的bios和内核时发现,2者在总线读时序上的实现不太一样,在于第一次寄存器地址写入后,一个发的是restart,一个发的是stop,然后再start开始读取数据,示波器抓波形发现读取数据都正确,说明这2种时序都是正确的。

IIC总线的读写时序比较固定,设备通信严格遵循协议,因此iIC总线设备驱动程序的编写也就相对简单一些。

主要应用的iIc总线设备有touchscreen rtc 外扩io等

http://blog.chinaunix.net/uid-21785445-id-2688689.html

IIC总线协议最重要的是起始信号,终止信号和应答信号。起始信号和终止信号由主机产生,应答信号是每次传输完成一个字节数据后必须有的,用于确认传输是否完成,主机向设备发一个字节数据后需要设备作应答,确认设备是否收到数据,主机收一个字节数据后需要向设备发一个应答信号,告诉设备数据是否收到。

(1) 起始信号:在时钟线保持高电平期间,数据线出现由高电平向低电平变化时启动I2C总线;
(2) 终止信号:在时钟线保持高电平期间,数据线出现由低电平向高电平变化时停止I2C总线;
(3) 应答信号:应答信号在第9个时钟位上出现,接收器输出低电平为应答信号(A),输出高电平则为非应答信号(/A)。

 

IIC数据传输:SCL为高电平时将SDA上数据发走,所以SDA上数据必须在SCL为高电平期间保持稳定,IIC总线首先传输的是数据最高位,最后是最低位。

 

设备地址:在起始信号后,需要向设备发送一个字节的设备地址,其中高七位为设备的地址,表示同哪个设备进行通信,最低位为数据传输方向,1表示读(接收),0表示写(发送)。

1.发送(写)一个字节数据流程

a.起始信号

b.发送一个设备地址,这里为0,表示发送(写)),设备应答

c.发送设备的写的基地址,设备应答

d.发送数据到设备基地址,设备应答

e.停止信号

 

2.接收(读)一个字节数据流程

a.起始信号

b.发送一个设备地址,这里为0,表示发送(写)),设备应答

c.发送从设备要读数据的基地址,设备应答

d.起始信号

e.发送一个设备地址,这里为1,表示接收(读)),设备应答

f.从设备基地址处接收到一个字节的数据,主机应答

g.停止信号

 

从设备地址读或写一个字节数据后,设备读写地址会自动加1

3.连续发送(写)多个字节数据

a.起始信号

b.发送一个设备地址,这里为0,表示发送(写)),设备应答

c.发送设备的写的基地址,设备应答

d.发送数据到设备基地址,设备应答

e.发送数据到设备(基地址+1),设备应答

f.发送数据到设备(基地址+2),设备应答

g.发送数据到设备(基地址+n),设备应答

h.停止信号

 

4.连续接收(读)多个字节数据

a.起始信号

b.发送一个设备地址,这里为0,表示发送(写)),设备应答

c.发送从设备要读数据的基地址,设备应答

d.起始信号

e.发送一个设备地址,这里为1,表示接收(读)),设备应答

f.从设备基地址处接收到一个字节的数据,主机应答

g.从设备(基地址处+1)接收到一个字节的数据,主机应答

h.从设备(基地址处+2)接收到一个字节的数据,主机应答

i.从设备(基地址处+n)接收到一个字节的数据,主机应答

j.停止信号

 

SPI

   SPI 的通信原理很简单,它需要至少4根线,事实上3根也可以。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCK(时 钟),CS(片选)。其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许 在同一总线上连接多个SPI设备成为可能。

接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过SDO线,数据在时钟上沿或下沿时改变,在紧接着的下沿或上沿被读取。 完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。

1) SCLK:串行时钟,用来同步数据传输,由主机输出;

 

2) MOSI:主机输出从机输入数据线;

 

3) MISO:主机输入从机输出数据线;

 

4) SS:片选线,低电平有效,由主机输出。

 

在SPI总线上,某一时刻可以出现多个从机,但只能存在一个主机,主机通过片选线来确定要通信的从机。这就要求从机的MISO口具有三态特性,使得该口线在器件未被选通时表现为高阻抗。

 

    要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。

这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。

SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。

不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。


     概述
      

 


      上图只是对 SPI 设备间通信的一个简单的描述, 下面就来解释一下图中所示的几个组件(Module):
       SSPBUF, Synchronous Serial Port Buffer, 泛指 SPI 设备里面的内部缓冲区, 一般在物理上是以 FIFO 的形式, 保存传输过程中的临时数据;
       SSPSR, Synchronous Serial Port Register, 泛指 SPI 设备里面的移位寄存器(Shift Regitser), 它的作用是根据设置好的数据位宽(bit-width) 把数据移入或者移出 SSPBUF;
       Controller, 泛指 SPI 设备里面的控制寄存器, 可以通过配置它们来设置 SPI 总线的传输模式.
        通常情况下, 我们只需要对上图所描述的四个管脚(pin) 进行编程即可控制整个 SPI 设备之间的数据通信:
       SCK, Serial Clock, 主要的作用是 Master 设备往 Slave 设备传输时钟信号, 控制数据交换的时机以及速率;
        SS/CS, Slave Select/Chip Select, 用于 Master 设备片选 Slave 设备, 使被选中的 Slave 设备能够被 Master 设备所访问;
        SDO/MOSI, Serial Data Output/Master Out Slave In, 在 Master 上面也被称为 Tx-Channel, 作为数据的出口, 主要用于 SPI 设备发送数据;
        SDI/MISO, Serial Data Input/Master In Slave Out, 在 Master 上面也被称为 Rx-Channel, 作为数据的入口, 主要用于SPI 设备接收数据;

        SPI 设备在进行通信的过程中, Master 设备和 Slave 设备之间会产生一个数据链路回环(Data Loop), 就像上图所画的那样, 通过 SDO 和 SDI 管脚, SSPSR 控制数据移入移出 SSPBUF, Controller 确定 SPI 总线的通信模式, SCK 传输时钟信号.

 

  SSPSR.

          

 



        SSPSR 是 SPI 设备内部的移位寄存器(Shift Register). 它的主要作用是根据 SPI 时钟信号状态, 往 SSPBUF 里移入或者移出数据, 每次移动的数据大小由 Bus-Width 以及 Channel-Width 所决定.

        Bus-Width 的作用是指定地址总线到 Master 设备之间数据传输的单位.
        例如, 我们想要往 Master 设备里面的 SSPBUF 写入 16 Byte 大小的数据: 首先, 给 Master 设备的配置寄存器设置 Bus-Width 为 Byte; 然后往 Master 设备的 Tx-Data 移位寄存器在地址总线的入口写入数据, 每次写入 1 Byte 大小的数据(使用 writeb 函数); 写完 1 Byte 数据之后, Master 设备里面的 Tx-Data 移位寄存器会自动把从地址总线传来的1 Byte 数据移入 SSPBUF 里; 上述动作一共需要重复执行 16 次.

        Channel-Width 的作用是指定 Master 设备与 Slave 设备之间数据传输的单位. 与 Bus-Width 相似,  Master 设备内部的移位寄存器会依据 Channel-Width 自动地把数据从 Master-SSPBUF 里通过 Master-SDO 管脚搬运到 Slave 设备里的 Slave-SDI 引脚, Slave-SSPSR 再把每次接收的数据移入 Slave-SSPBUF里.

        通常情况下, Bus-Width 总是会大于或等于 Channel-Width, 这样能保证不会出现因 Master 与 Slave 之间数据交换的频率比地址总线与 Master 之间的数据交换频率要快, 导致 SSPBUF 里面存放的数据为无效数据这样的情况.


        SSPBUF.

           

 



          我们知道, 在每个时钟周期内, Master 与 Slave 之间交换的数据其实都是 SPI 内部移位寄存器从 SSPBUF 里面拷贝的. 我们可以通过往 SSPBUF 对应的寄存器 (Tx-Data / Rx-Data register) 里读写数据, 间接地操控 SPI 设备内部的 SSPBUF.

          例如, 在发送数据之前, 我们应该先往 Master 的 Tx-Data 寄存器写入将要发送出去的数据, 这些数据会被 Master-SSPSR 移位寄存器根据 Bus-Width 自动移入 Master-SSPBUF 里, 然后这些数据又会被 Master-SSPSR 根据 Channel-Width 从 Master-SSPBUF 中移出, 通过 Master-SDO  管脚传给 Slave-SDI 管脚,  Slave-SSPSR 则把从  Slave-SDI 接收到的数据移入 Slave-SSPBUF 里.  与此同时, Slave-SSPBUF 里面的数据根据每次接收数据的大小(Channel-Width), 通过 Slave-SDO 发往 Master-SDI, Master-SSPSR 再把从 Master-SDI 接收的数据移入 Master-SSPBUF.在单次数据传输完成之后, 用户程序可以通过从 Master 设备的 Rx-Data 寄存器读取 Master 设备数据交换得到的数据.


      Controller.

           

 



          Master 设备里面的 Controller 主要通过时钟信号(Clock Signal)以及片选信号(Slave Select Signal)来控制 Slave 设备. Slave 设备会一直等待, 直到接收到 Master 设备发过来的片选信号, 然后根据时钟信号来工作.

          Master 设备的片选操作必须由程序所实现. 例如: 由程序把 SS/CS 管脚的时钟信号拉低电平, 完成 SPI 设备数据通信的前期工作; 当程序想让 SPI 设备结束数据通信时, 再把 SS/CS 管脚上的时钟信号拉高电平.

 

 

 

Ps:暂时用不到的概念: 

CPOL: 时钟极性, 表示 SPI 在空闲时, 时钟信号是高电平还是低电平. 若 CPOL 被设为 1, 那么该设备在空闲时 SCK 管脚下的时钟信号为高电平. 当 CPOL 被设为 0 时则正好相反.

        CPHA: 时钟相位, 表示 SPI 设备是在 SCK 管脚上的时钟信号变为上升沿时触发数据采样, 还是在时钟信号变为下降沿时触发数据采样. 若 CPHA 被设置为 1, 则 SPI 设备在时钟信号变为下降沿时触发数据采样, 在上升沿时发送数据. 当 CPHA 被设为 0 时也正好相反.

posted @ 2016-07-26 19:45  渝雪柒柒  阅读(681)  评论(0编辑  收藏  举报