怎么看时序图--nand flash的读操作详解
本文转自:http://blog.chinaunix.net/uid-28852942-id-3992727.html 这篇文章不是介绍?nand flash的物理结构和关于nand flash的一些基本知识的。你需要至少了解?你手上的?nand flash的物理结构和一些诸如读写命令 操作的大概印象,你至少也需要看过?s3c2440中关于nand flash控制寄存器的说明。 由于本人也没有专门学过这方面的知识,下面的介绍也是经验之谈。 这里?我用的?K9F2G08-SCB0?这款nand flash?来介绍时序图的阅读。不同的芯片操作时序可能不同,读的命令也会有一些差别。 当然其实有时候像nand flash这种?s3c2440内部集成了他的控制器的外设。具体到读写操作的细节时序(比如?CLE/ALE的建立时间,写脉冲的宽度。数据的建立和保持时间等),不明白前期也没有多大的问题。 因为s3c2440内部的nand flash控制器?做了大部分的工作,你需要做的基本就是设置?几个时间参数而已。然后nand flash会自动进行这些细节操作。 当然如果处理器上没有集成?nand flash的控制器?那么久必须要自己来写时序操作了。所以了解最底层的时序操作总是好的 ? 但是上层一点的,比如读写操作的步骤时序(比如读操作,你要片选使能,然后发命令,然后发地址,需要的话还需发一个命令,然后需要等待操作完成,然后再读书数据)。 是必须要明白的。这都不明白的话,怎么进行器件的操作呢 ? 也就是说?s3c2440?可以说在你设置很少的几个时间参数后,将每一个步骤中?细微的操作都替你做好了。(比如写命令,你只要写个命令到相应寄存器中,cpu内部就会协各个引脚发出 适应的信号来实现写命令的操作)。 而我们所需要做的?就是?把这些写命令,写地址,等待操作完成。等步骤组合起来?。从而完成一个?读操作 ? 就像上面说的,虽然我们不会需要去编写每个?步骤中的最细微的时序。?但是了解下。会让你对每个操作步骤的底层细节更加明了 ? 先来看一个命令锁存的时序。也就是上面说的?读?nand flash操作中不是有一个?写命令步骤吗。那么这个步骤具体是怎么实现的。 首先?我们肯定是要片选?nand flash。只有选中芯片才能让他工作啊 nand flash是通过?ALE/CLE (高电平有效)来区分数据线上的数据时命令(CLE有效),地址(ALE有效)还是数据(CLE/ALE都无效)。 那么这里既然是写命令?那么就一定是?CLE有效(高电平)?ALE无效(低电平)。 同样命令既然是写给nand flash的那么?肯定有一个写周期。我们需要注意的是,写是在上升沿有效还是下降沿有效。 时序图如下: 1?这里是命令锁存是时序,那么我们要注意的其实就只有?CLE?为高电平期间这段时序。(写命令啊,CLE有效时(高电平)指示现在的数据其实命令)ALE此时一定为低电平我们可以不关心他 2?所以,CLE为?低电平的时期,其他大部分引脚上都是?灰色的阴影,这代表我们不需要关心这段时期这些引脚的电平 3?那么?这个数据是什么时候被nand flash读取到的呢,?注意到?nWE信号?在上升沿有一个贯穿所有其他引脚时序的竖线(这好像是叫生命线?我也不清楚) ???????这就是说明,写入的数据(命令也是数据啊,只是可以通过CLE有效来区分)是在?WE的上升沿有效。 ???????也就是说,虽然?WE是在低电平有效,但并不是说?WE一变成低电平,命令就被锁存了(即真正获得命令)而是在?WE?的上升沿,命令才真正被锁存。 ? 知道了上面这三点,也就知道了一个大概,那么剩下的图中也只剩那些?txx?的标号。明显它指的是时间,但是具体指什么时间呢。 指的就是箭头两边所指的两条?竖线之间的时间。(在每个信号的跳变沿,都有小竖线) ? 剩下的就是这些时间到底是代表什么了。这里没什么难的,刚接触的觉得看不懂。是因为之前从来没接触过。(就像单片机刚学的时候不也是各种不懂,原因就是我们从没接触过)。 比如? tCLS?? tCLH?从数据手册中我们可以看到?分表代表的?CLE建立时间,和CLE信号保持时间。 简单点你可以理解为,我让?CLE引脚??变成高电平,总得给人间一点时间去变成高电平吧。总不能瞬间就变成高电平 不过从?时序图中我们能看到更多的端倪,之前不是说过?WE?的上升沿上不是有一个最长贯穿其他信号线的?竖线吗。我们说他指示了,数据(命令也是数据) ???????是在上升沿被锁存的,在?WE?的上升沿,我写到数据线上的命令数据才真正被锁存(接收),但是?我们注意到?CLE?信号在WE上升沿之前有就有效了。 ???????所以我们说,?在命令数据真正被锁存之前,CLE?有效的那段?tCLS?时间叫做?CLE信号建立时间。 ?????? WE上升沿后。命令已经被接受了,但这时候?CLE?其实可以变为无效了,因为已经获取到命令了 ???????但是他并没有立刻结束,而是?Tclh时间之后才结束。那么我们?称这段?时间?tCLH?为?CLE?保持时间。
?????? tDS表示数据建立时间,tDH表示数据保持时间 ? 这里我们看到一个小规律,在数据手册中?以?S?结尾的时间通常指的是建立时间,?以?H?结尾的时间指的是保持时间 ?????? ?????? 这里命令锁存的时序就分析完了。我们再来看看??地址锁存时序图,这个图有点复杂, 因为nand flash的?特性是?地址周期通常需要好几个,就是一个地址是分几次发送的 ? 再给出数据手册中对应时间标号的说明
1?这里是地址锁存是时序,那么我们要注意的其实就只有?ALE?为高电平期间这段时序。(写命令啊,ALE有效时(高电平)指示现在的数据其实是地址)CLE此时一定为低电平,可以不用管
? 那么剩下的也好理解 tCLS?这个我们不需要关心,因为?CLE?压根就是无效的。 tCS?就像之前分析的,它是指?CE片选信号在?WE上升沿也就是锁存地址之前的有效时间,也就是?CE?建立时间 tWC?呢??不知道??不知道?看手册啊,前面也说过这些时间标号在手册中都会给出。 ???????从上面手册的解释我们看到,它指的是一个写周期的时间 tWP?写脉冲宽度(也就是?WE是低电平有限,twp指低电平持续时间,就是有效时间) tWH?好理解了,就是高电平时间 ALS ???这不就是?地址信号? ALE?建立时间嘛 ALH ??ALE信号有效保持时间啊 TDS TDH?数据建立和保持时间 就像上面对?命令时序的分析,这里?信号的?建立?和?保持时间都是以?数据被?锁存分界点(WE上升沿) ? 看到这里相信仔细看的人,应该大致该如何看一个时序图了,但是这里?我们牵涉到的?无非都是一些?上面?建立/保持时间。 复杂点的呢。 ? 下面就来看一个复杂点的时序图,其实也不复杂,主要是说明如何在不看手册就能知道?txx指的是什么时间? ?
? 这个时序其实并不复杂,只是他不是像上面分析的那样都是一些?建立时间和保持时间。这里牵涉到跟多的时间标号 不过就像前面说的.?看手册!?手册里对每个时间参数都有说明。不过初学者通常即使看手册,对这些时间参数也是不知道是什么意思。 这里我们看手册前,先来自己分析下。方法会了,手册就成了验证你对不对的东西了,而不是你寻找答案的东西。 ? TRC?这个参数有点简单。看他的范围?是?一个?RE周期?的时间,那么就跟前面的?tWC?应该是一样的。那它应该代表的就是?RE信号的一个周期时间(读信号的一个周期) TREA?呢??看标号看不出所以然,那么我们就看他的起始和结束时间?从时序图能看到,这个指的是从?RE有效(变低)?到数据出现?之间的时间。 那么tREA?可想而知就应该是?读信号有效到数据被读之间的时间 后面的都是这个同样的分析方法 比如最后的那个?tRHZ?是从?RE?无效(高电平)到数据线变成高阻态?之间的时间(数据线画在中间表示的是高阻态) 看下手册中的解释?也基本就是这个意思 ? 到这里?对于时序图怎么看,相信大家都应该能理解了。甚至可能连手册都不用看,就知道他是什么意思了。因为我们能从?时间的起始地址来推测时间标号的意思 ? ? 上面这些分析,都是很底层的操作,如果我们使用?s3c2440?这种高级的处理器?这些时序操作我们根本不需要去实现,顶多也就往几个寄存器中 设置一下上面说的一些时间?然后,CPU?中的?nand flash控制器会自动完成上面所的所有操作。但是还需要了解的原因是,如果你碰到一个没有 nand flash?控制器的处理器?怎么办,那你只能亲自实现这些?具体的?写命令,写地址。等等?单元操作。 然后才能将这些单元操作组合成?读数据,写数据等操作(上面说过?比如读操作?他并不是一个简单的命令而是一系列操作,你要片选使能,然后发命令(读命令), 然后发地址(要读的数据的地址),需要的话还需发一个命令,然后需要等待操作完成,然后读书数据) ? 说完了?这些具体的单元操作,那么我们再来看看一个?读操作?具体需要哪些步骤。也就是我们需要真正必须掌握的时序操作 对于我这款?nand flash?读操作时序如下 我们要注意的主要是?最下面一行?即?I/Ox?信号线的状态,他指示了?读操作需要哪些,单元步骤。 1?首先?我们看到?有一个?0x00?是什么?数据?地址?命令??看?ALE/CLE线啊,这两根线不是决定了现在的数据的类型嘛 ???????顺着往上看,我们知道0x00是在?CLE有效期间的数据那么它就是一个命令 2?然后是?address(5Cycle)?即五个地址序列(这款nand flash?指定读数据的地址时要发送五个地址序列),往上看,是在ALE有效期间的数据,那么应该就是地址了 ???????(对于这五个地址,前面两个是列地址,后面三个是行地址。在nand flash的物理结构中?行地址对应的某一页,列地址就对应这一页中的某一列) ? 3?接着又是?0x30,此时?CLE有效,那么就是命令了(也就是说这款nand flash的读操作需要两个命令)。 ???????但是之后数据并未立刻出来,我们看到在到?DATA Output即数据输出之前还有一段时间,为什么有这段时间? ???????往上看?R/nB?这个数据线上说明了原因,这段时间内它是低电平?即指示现在?处于?忙碌状态,还未准备好数据输出。为什么会这样? ???????因为你?写了?一个命令,写了要读数据的地址,又写了一个命令。?你总要给?cpu一些时间去处理这些命令吧, ???????R/nB为低电平这段时间就是?在处理这些命令(实际上是根据命令将你定位的那一页数据读到内部寄存器中), ???????等?R/nB变成高电平了,就指示命令处理完毕,现在数据也就可以读出来了。 ? 综上我们从手册中我们就知道了读操作的具体步骤, 1?首先nand flash?也是一个外设,要访问他就需要片选它,所以在执行时序图上的步骤之前需要片选nand flash. 2?看后面就是安装时序图来了,看时序图!?第一步先是发送一个命令?0x00. 3?看时序图!?然后发送五个地址序列(先发送两个列地址,在发送三个行地址(即页地址)) 4?看时序图!?接着再是一个命令?0x30. 5?看时序图!? R/nB?引脚为低表示现在正忙,正在处理这些命令,那就要等待?R/nB?引脚变为高电平 6?看时序图!?这个时候就可以读数据了 7?一次读操作结束了?nand flash?暂时是不需要使用了,那么别忘了应该?取消片选信号。 ? 至于这每一个步骤中具体的时序,cpu中的nand flash控制器会帮我们完成。我们要做就是设置几个时间参数 ? 这里我们反复强调了要看时序图。其实学嵌入式前期对数据手册一定要多看,看多了你就回知道,什么东西的你重点要看的,什么是和你的编程操作无关的你不需要关心。这样后面你才能,拿到一个外设?就能写出他的操作。而不用跟着书背步骤。只要手册在就行了。 ? 上面的步骤,是一个具体的读操作的步骤,不过在使用一个器件之前我们需要初始化一下它。至于初始化也就是设置我们上面多次提到的 我们说过?s3c2440已经帮我做了很多底层的单元操作,我们只需设置几个时间参数?片内的?nand flash就会自动发出相应操作的时序操作 那么到底设置那几个时间呢。? s3c2440?手册上给出了?需要我们设置的几个参数。
? 从中我们可以看出?第一幅时序图是?命令和地址锁存的时序,第二幅是?数据读取和写入的时序。
2 TWRPH0?代表的是?WE?的脉冲宽度,即有效时间 3 TWRPH1?代表的是?CLE/ALE?的保持时间
那么我们从?nand flash中随便找一个?命令时序来对照不就行了 就拿上面我们说过的?命令锁存时序来对比
TWRPH0 = tWP? TWRPH1 = tCLH TACLS? = tCLS - tWP ?
? 所以?TWRPH0 = tWP? >=12ns ?????? ?TWRPH1 = tCLH >=5ns ?????? ?TACLS? = tCLS - tWP >=0; 而这三个参数在s3c2440的数据手册中说明为 ? 当然这里的时间都是以?HCLK?为单位的,这几个参数?是在?nand flash控制寄存器中的?NFCONF中设置的 这里我没用使用MPLL?所以HCLK是?12MHZ ? 所以?TWRPH0 = 0 TWRPH1 =0 TACLS =0; (如果你的时钟频率比较高,那就要设别的数了。当然有是有你真不知道,设置大点总没错,只不过速度可能会慢点。) ???????所以?NFCONF =0;(NOFCONF其他位数据手册中有说明,这里只是简单读操作,其他位可以不设置) ? 然后是初始化一下?ECC?使能nand flash控制器(我们只是设置了几个时间参数,时序的具体操作就是靠他来完成的,所以要使能他) 然后先 取消片选nand flash?因为我们现在还没有操作它啊,只是初始化一下。所以还是应该先取消片选,等真正读的时候再使能片选信号 ? NFCONT = (1<<4) | (1<<1) (1<<0); (数据手册中有对应位的说明) 最后,第一次使用nand flash?我们需要复位操作一下。 综上,nand flash?的初始化代码如下 void nand_init(void){ ??????? NFCONF =0; ??????? NFCONT = (1<<4) | (1<<1) | (1<<0); ??????? nand_reset();? //nand reset代码在后面 } ? 下面代码一些地址的写法是与?nand flash?型号有关的。具体需要参考芯片手册 ?????? ? void select_chip(void){ ??????? NFCONT? &= (~(1<<1)) ;??? ??????? int i; ??????? for(i=10;i>0;i--); } void deselect_chip(void){ ??????? NFCONT |= (1<<1); ??????? int i; ??????? for(i=10;i>0;i--); } ? void write_command(unsigned char command){ ??????? NFCMMD = command; ??????? int i; ??????? for(i=10;i>0;i--); } ? /* ???????这款nand flash?的页大小是?2K ???????五个地址周期? (2个列地址?和3和行地址(页地址)) */ void write_address(unsigned int address){ ??????? unsigned int page = address/2048; ??????? unsigned int col? = address&2048; ? ??????? int i; ??????? NFADDR = col & 0xff; ??????? for(i=5;i>0;i--); ??????? NFADDR = (col >>8) & 0x0f; ? ??????for(i=5;i>0;i--); ??????? NFADDR = page & 0xff; ??????? for(i=5;i>0;i--); ??????? NFADDR = (page >>8)& 0xff; ??????? for(i=5;i>0;i--); ??????? NFADDR = (page >>16)&0x01; ??????? for(i=5;i>0;i--); } ? unsigned char read_one_data(void){ ??????? return NFDATA; ??????? int i; ??????? for(i=10;i>0;i--); } ? void wait_ready(void){ ??????? while(!(NFSTAT & 1)); ??????? int i; ??????? for(i=10;i>0;i--); } ? ? static void nand_reset(void){ ??????? select_chip(); ??????? write_command(0xff); ??????? wait_ready(); ??????? deselect_chip(); } void nand_init(void){ ??????? NFCONF =0; ??????? NFCONT = (1<<4) | (1<<1) | (1<<0); ? ??????? nand_reset(); } ? /* nand flash?的读操作是以页为单位的。 ?des: nand flash中读出的数据放到哪 ?start_addr:?从哪里开始读 ?size:?读多大 */ void nand_read(unsigned char *des,unsigned int start_addr,unsigned int size){ ??????? unsigned int col? = start_addr & 2048; ? ??????? select_chip(); ??????? unsigned int start = start_addr; ??????? unsigned int end?? = start_addr + size; ??????? while(start < end){???????????????????????????? //每读一页需要发一次命令 ???? ???????????write_command(0x00); ??????????????? write_address(start); ??????????????? write_command(0x30); ??????????????? wait_ready(); ? ??????????????? while((col<2048) && (start<end)){? //在一页中读,我用的型号一页大小为2K ??????????????????????? *des = read_one_data(); ????????? ??????????????des++; ??????????????????????? col++; ??????????????????????? start++; ??????????????? } ??????????????? col =0; ??????? } ??????? deselect_chip(); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |