tag 标签: 串行

相关帖子
相关博文
  • 热度 2
    2018-1-26 20:54
    1808 次阅读|
    0 个评论
    作为经常和 PCB设计 打交道的我们来说,通常说的10Gbps信号,都指的是PCB板上的电信号,虽然会牵涉到光模块,但其实光模块里面也是通过光电转换芯片,而大部分我们还是在和电信号接触,所以后续都是基于电信号而言。同样的10Gbps信号,其实有很多种不同的协议组织下对应的不同的标准,我们常用的主要有如下图一所示,当然还有很多我们不常用的,在此不一一介绍了。 图一 上面就是一些常见的10Gbps信号协议,还是来普及一下各种协议组织以及协议的用途吧。 IEEE802.3标准,这是IEEE协议组织下面的一个分会,也是一个集群协议。IEEE大家想必比较熟悉了吧,全称是Institute of Electrical and Electronic Engineers电器和电子工程师学会(美国),是目前全球最大的非营利性专业技术学会。其中比较出名的是IEEE 802委员会,它成立于1980年2月,它的任务是制定局域网的国际标准,下面又有12个分委员会,而我们比较熟悉的主要背板协议IEEE802.3就是其中的一个,802.3即总线网介质访问控制协议CSMA/CD及物理层技术规范,其中有目前的一些高速信号协议如802.3ap/ba/bj等等;另一分委员会802.11 无线局域网的介质访问控制协议CSMA/CA及其物理层技术规范,相信大家也早就用过,那就是我们的无线网络如WIFI等。关于IEEE的详细介绍,大家也可以自行百度一下,后续我们会主要介绍高速相关的一些子协议。 InfiniBand即无限带宽技术,InfiniBand技术不是用于一般网络连接的,它的主要设计目的是针对服务器端的连接问题。因此,InfiniBand技术将会被应用于服务器与服务器(比如复制,分布式工作等),服务器和存储设备(比如SAN和直接存储附件)以及服务器和网络之间(比如LAN, WANs和the Internet)的通信。接触的不多,不做详细介绍。 SFF8431是SFF Committee标准组织发布的一个关于10Gbps到光模块的协议,该协议主要定义的是SFP+接口。SFF Committee即Small Form Factor(小型化委员会),而SFP+为Enhanced Small Form Factor Pluggable Module (增强型小型可插拔模块)的缩写,里面的信号就是SFI(SFP+ high speed serial electrical interface),这个是我们用得比较多的到光口的10Gbps信号协议,后面会详细介绍。 Fibre Channel即光纤通道,光纤通道或FC是一种高速网络技术(通常以1,2,4,8,16,32和128千兆位/秒速率运行),采用NMb的编码方式,同步串行方式传输。主要用于商用数据中心的存储区域网络(SAN),将计算机数据存储连接到服务器,光纤通道通常在数据中心内部和之间的光纤电缆上运行。FC在国际信息技术标准委员会(INCITS)的T11技术委员会中标准化,该委员会是美国国家标准协会(ANSI)认可的标准委员会。光纤通道协议(FCP)是一种主要通过光纤通道网络传输SCSI命令的传输协议。光纤通道主要接触的也少,不做详细介绍; CEI-11G-SR/MR/LR为OIF协议组织下面的通用电气输入输出标准,OIF为Optical Internetworking Forum光互联网络论坛,而CEI即 Common Electrical I/O通用电气输入输出,OIF也是一家国际非营利组织,拥有超过100家成员公司,其中包括世界领先的运营商和供应商。作为联合数据和光学世界代表的行业集团,OIF的目的是加快部署可互操作,成本效益和可靠的光互联网络及其相关技术。 光互联网络是由光网络元件互连的路由器和数据交换机组成的数据网络。为了促进光网络产品的全球兼容性,OIF积极支持和扩展国家和国际标准机构的工作。已经与CFP-MSA,COAST,以太网联盟,光纤通道T11,IEEE 802.1,IEEE 802.3,IETF,InfiniBand,ITU-T SG13,ITU-T SG15,MEF,ONF,Rapid I / O ,SAS T10,SFF委员会,TMF和TMOC建立了工作关系或正式联络。由于这些组织之间的相互协调,可以说很多协议之间是可以互通的。后续我们介绍的10Gbps、25G/28Gbps甚至50G/56Gbps协议都会出自OIF里面。
  • 热度 19
    2017-5-10 13:56
    1550 次阅读|
    0 个评论
    我们都知道源同步方式的典型代表是DDRx信号,下面就来介绍源同步方式是怎样改善系统同步的先天不足的。 源同步要解决的第一个问题是减少在芯片之间传输数据所需的I/O引脚数量。这通过将芯片#1的输出处的n位数据复用到k位互连(k n),然后将芯片#2的输入上的互连的k位解复用到n位内部数据路径上来实现,如下图所示。所得到的系统只需要每个芯片上的k个I/O引脚,而不需要先前的n个引脚。 当然,虽然引脚数量要求已经通过k:n的比率降低,但是参考时钟的所需频率已经增加了这个比率的倒数。由于噪声,电磁干扰(EMI)和功耗问题,系统设计人员通常不喜欢在系统内分配高速参考时钟。通常,分配较低频率的时钟,并且使用芯片中的PLL将该参考时钟乘以可用频率,但所产生的时钟相位的变化以及数据传输的频率越高,往往会加剧并行数据总线的时序问题。 源同步的第二个法宝就是在两个芯片之间的数据通路中增加了一个高速时钟,如下图所示。假设该时钟源提供的时钟频率略低于在芯片互连上对数据进行触发的时钟频率,每个芯片都使用PLL来产生这个频率倍数的时钟,所得到的时钟用于启动和捕获相应芯片中的数据。芯片#1中用于从该芯片启动数据的PLL的输出时钟也是该芯片的输出,芯片#2使用该时钟来捕获数据,这种方法称为时钟转发。 时钟转发的优点是用于在芯片#1上启动数据的高速时钟可用于芯片#2作为捕获数据的参考。这样之前通过时钟分配网络驱动两个芯片的延迟的变化在时序分析中就不需要考虑了,只有时钟路径和数据位之间的延迟变化是相关的。 虽然制程,电压和温度导致的这些路径之间的变化在一定程度上相互影响,但接口的时序分析需要的余量较少,因此建立和保持时间更容易满足。 我们还是来看看典型的例子吧,图中所示的时钟可以是单数据速率(SDR)或双倍数据速率(DDR)的时钟,如下图所示。SDR就是接收芯片在SDR时钟的每个上升沿(或每个下降沿)捕获数据; 而DDR则是接收芯片捕获DDR时钟的每个边沿(上升沿和下降沿)的数据。 无论时钟是SDR还是DDR时钟,接收芯片都使用该时钟直接捕获数据。 该芯片还使用参考时钟以相同的频率生成内部系统时钟,这些时钟是中间同步的。 虽然频率相同(鉴于它们共享共同的频率参考),但是时钟之间的相位关系是未知的,并且可能由于PVT变化而变化。 因此,接收芯片通常将接收到的数据从接口时钟域重新定时到内部芯片时钟的时钟域。 FIFO用于执行此重定时功能, 期望最小化由接口时钟计时的触发器的数量,以便最小化时钟分配网络中的延迟,否则时钟问题将会加剧。
  • 热度 17
    2017-5-4 11:46
    1722 次阅读|
    0 个评论
    作者:一博科技 在这个系列开篇的时候大家提到了希望了解一下串行信号和并行信号的优缺点,其实基本的概念大家应该都知道一点,但真正要把它写出来,我觉得又不是很好下笔,这也是为什么隔了这么久才推出这篇文章,我们也是为了对大家负责的态度,不能误导了各位忠实的读者,有什么说得不对或者没有说得很清楚的希望大家一起来探讨。 突然有个问题,我们通常说的PCIE,既可以是PCIE信号,也可以是PCIE接口、PCIE总线,还可以是PCIE协议。之所以难写,其实中间就是涉及到了太多的概念和认知的差异,因为串行和并行的概念太广了。只要百度一下串行和并行,就会出来很多类似“串行通信与并行通信”、“串行接口与并行接口”、“串行总线与并行总线”、“串行协议与并行协议”以及“串行传输与并行传输”等概念介绍,而我们现在要说的串行信号应该包括了上面所有的这些概念,既有传输(通信)方式,又有接口类型,同时还有数据本身的协议特点,信号、协议、总线和接口,有时候看起来是一样的,但细细思量却还是有差别的,总之不是一两句话就能说清楚的(如PCIE信号、PCIE协议、PCIE接口以及PCIE总线之间的相互瓜葛就是剪不断理还乱啊)。举个简单的例子,PCI总线说的是一组传输通道,而PCI接口是一种连接标准,两者之间的关系就是PCI接口的设备都要通过PCI总线来进行通信,而PCI总线上走的设备并不全是PCI接口的,像集成声卡,走的就是PCI总线。在这里PCI总线提供了一种通道,这个通道上可以有不同的符合这种通道要求的接口设备或信号(PCI信号或Audio信号)。打个更进一步的比方:两者关系就像马车(接口设备)和马路(总线)一样,马车必须在马路上走,而马路上不一定走马车(牛车等)。如下图所示。 车(接口、信号)有车(接口、信号)的标准(协议),如马车、汽车、火车、货车、自行车等(PCIE、SATA、SAS、USB等信号标准);路(通道、总线)有路的标准,如马路、人行道、高速公路等(PCIE、SATA、SAS、USB等通道标准),所以协议里面又包含通道(总线)协议和信号(接口)协议。是不是感觉越讲越复杂,不明觉历。实际上现在的高速信号定义确实是这么复杂,要搞懂也不是一朝一夕的事情。 用下图来简单介绍下这几个概念之间的关系。 协议即总体框架,定义接口设备、器件及信号、总线及通道之间需要满足的关系,即要实现信号的传输,所有这些组成成员必须通力合作,各自满足协议要求的各种必要条件。 而信号(拿PCIE来说)也是一个比较模糊的概念,在这里可以是接口,也可以是总线,所以“不管黑猫白猫,能抓到老鼠的就是好猫”,暂且不去理会这些接口、总线、协议及信号等纠缠不清的概念,反正我们讲的这些应该都要包括进来。后续我们在介绍协议的时候再一一来讲解。
  • 热度 21
    2012-11-6 00:15
    1168 次阅读|
    0 个评论
    接上次的话茬,在并行的驱动方式下,我们的编程的确是很省事,不过最大的不足就是,如果你的单片机能够给你使用的端口没有那么多,特别是那8 个数据管脚占有的那么多的数量,看着心疼啊,所以这里介绍另一种驱动的方法,那就是串行的驱动方法。   串行的方式有时就不说了,但是也有缺点,那就是速度的制约,你想,原来8 根数据线一同传输的数据,这时要用2 根数据线进行传输,速度肯定是变慢了,具体变慢了多少呢?这个你可以自己计算一下。     下面是在Arduino 中的有关的管脚的定义:     可以明显的看出来,这里的使用的管脚少了很多其实主要就是烧得数据管脚部分,现在我们如果要发送数据,其实这就是主要的功能实现的方法,用发送数据的方法告诉LCD 要显示啥,在哪里显示,以及以怎样的顺序来进行显示,怎样的方式。   所以这样看来,以前的发送数据的函数肯定是不能够使用了,所以这里我们需要去重新写一个函数,以其能够用两根线也能完成我们需要完成的事情,这件事情其实不是很难,主要是在这里,很多事情的铺垫已经做好了。 我们再一次回到时序图,在这里面,有所有我们需要的东西,有我们的函数的书写的指导,有我们需要拉高拉低的电平,有我们需要显示字符的位置,有我们能够做的任何一件事。   照之前的经验,这里重写写数据函数,当然,还有读数据函数。这里的写可以这么理解,就是分为8 个阶段,8 个脉冲,读也是这样子来完成,那么这样的8 个脉冲之前必须还要加上一些标记性的东西才行,不然LCD 凭什么就能知道他应该去把之后的8 个脉冲之内的数据当成他需要读取的数据或者给出的数据?恩,这就在时序图中看出来了。   恩,之前的准备工作还是不可以少的,所以这里贴上,基本上和之前并行的时候差不多,只不过中间使用到的发送数据的函数做了一个改头换面,所以我们的调用形式还是不变,我觉得这个其实还是很重要的,在实际的开发过程中,底层的开发人员提供一些基本的函数,而在设计这些函数之前,必须考虑到今后的改动,以及在入口参数方面做一些详尽的考虑,这样使得以后的开发少一点纠结,这也是一个好的习惯,有些参数现在可能用不到,但是可能以后会用得到,所以有的时候需要做出一些权衡,也是为了上层的工作更好的开展。 好了,闲话少说,初始化: // set the pin mode   pinMode(vcc_pin,OUTPUT);   pinMode(psb_pin,OUTPUT);   pinMode(reset_pin,OUTPUT);   pinMode(bla_pin,OUTPUT);   pinMode(blk_pin,OUTPUT);   pinMode(e_pin,OUTPUT);   pinMode(rs_pin,OUTPUT);   pinMode(rw_pin,OUTPUT);   pinMode(v0_pin,OUTPUT);   pinMode(reset_pin,OUTPUT);     // testing point     digitalWrite(vcc_pin,HIGH);     digitalWrite(bla_pin,HIGH);     digitalWrite(blk_pin,LOW);     digitalWrite(psb_pin,0); // set the mode to parallel     analogWrite(v0_pin,150);       digitalWrite(reset_pin,LOW); digitalWrite(reset_pin,HIGH);     reset 就是一个复位,不过这里是这样,其实不是很必须,不过复位了那就更多一点放心,而已。   之后是一个功能的实现。     LCD_Init();         delay(1000);     LCD_WriteStr(1,1,shuzu);   这个init 的函数后面会讲,之前的初始化其实是对管脚的一轮的初始定义,而在软件代码上还需要一个初始化,这里的目的就是在屏上写一串字符,字符定义在一个数组中,是:char shuzu[]={"hello"}; 好了,看看具体的实现。 我们将写的函数分为两部分,一个有概括的意味: void LCD_write_byte(unsigned char RW, unsigned char RS, unsigned char W_data)   还有一个是一个像是在埋头苦干的小伙: void serial_write_byte(unsigned char dat)   好了,下面是这两者的代码,不过稍等一会,给出时序图先。   这是读写的时序,是每一次写的时候的方式表达。 还有一张图: 这是传送一个完整的8位的字节数据所经历的过程,这样我们写函数的时候就能知道是不是对了,只需要对照这样的两张图进行书写,拉高拉低电平就可以了吗很多的期间其实在时序图上是很复杂的,远远比这个要复杂很多,所以这个时候需要编写者的耐心和细心,这两样是必不可少的,做电子的,其实都是需要这个的,你不知道你所写的代码将要运行在哪一个地方,不知道谁将来回去进行借鉴和参考,并且或者是直接的应用,如果这些代码做的事情和人们的生命安全有关系,和重大的工程项目有关系,那么,你可以想见,这样的细心和耐心是必要的。 这里控制的管脚的名字似乎是不认识了吧,没有关系,其实是换了一身马甲,你还是能够认出他们的。Sclk就是e这个管脚,就是允许管脚,然后剩下的应该很好判断吧,之后的代码中你能够轻易的看出来。 下面啥都不说了,贴代码,一切尽在代码中! void serial_write_byte(unsigned char dat) {       unsigned char i;                      for(i=0;i8;i++)                      {                               if((dat0x80)==0){                              clear_rw();                              delay(2);                              set_e();                              delay(4);                              clear_e();                              delay(2);                              clear_rw();                         }                               else{                              set_rw();                              delay(2);                              set_e();                              delay(4);                              clear_e();                              delay(2);                              clear_rw();                         }                                 dat = dat 1;                        }   }           void LCD_write_byte(unsigned char RW, unsigned char RS, unsigned char W_data)   {       unsigned int H_data,L_data,S_ID = 0xf8;  //11111RWRS0       if(RW == 0)                             //RW=0,MCU写一个数据到液晶;         {             S_ID =~ 0x04;         }       else                    //RW=1,从液晶读数据到MCU         {            S_ID |= 0X04;         }       if(RS == 0)                                   //RS=1,写入的是数据         {            S_ID =~ 0x02;         }       else                      //RS=0,写入的是指令;         {            S_ID |= 0X02;         }       H_data = W_data;       H_data = 0xf0;           //屏蔽低4位的数据       L_data = W_data;          //xxxx0000格式       L_data = 0x0f;           //屏蔽高4位的数据       L_data = 4;             //xxxx0000格式       set_rs();       serial_write_byte(S_ID);    //发送S_ID       serial_write_byte(H_data);  //发送H_data       serial_write_byte(L_data);  //发送L_data       clear_rs();   }       void LCD_Init(void)   {     delay(2);     LCD_write_byte(0,0,0x30); //功能设置 8位数据,基本指令       delay(2);     LCD_write_byte(0,0,0x04); //点设定:显示字符/光标从左到右移位,DDRAM地址加1     delay(2);     LCD_write_byte(0,0,0x0C);  //显示设定:开显示,显示光标,当前显示位反白闪动     delay(2);     LCD_write_byte(0,0,0x01);  //写指令:清除显示, 清DDRAM     delay(2);     LCD_write_byte(0,0,0x02);  //写指令:DDRAM地址归位     delay(2);     LCD_write_byte(0,0,0x80);  //写指令:设置DDRAM地址,把显示地址设为0X80,即为第一行的首位     delay(2);     }
相关资源