历史上的今天
返回首页

历史上的今天

今天是:2025年03月24日(星期一)

正在发生

2020年03月24日 | 第016课 Nand Flash操作原理及裸机程序分析

2020-03-24 来源:eefocus

第001节_NAND_FLASH操作原理

这里写图片描述

NAND FLASH原理图 

NAND FLASH是一个存储芯片 

那么: 这样的操作很合理”读地址A的数据,把数据B写到地址A”


问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址? 

答1.在DATA0~DATA7上既传输数据,又传输地址当ALE为高电平时传输的是地址,


那么在数据线上是不是只传输数据和只传输地址呢?


我们参考NAND FLASH的芯片手册可以知道,对NAND FLASH的操作还需要发出命令,下面有个NAND FLASH的命令表格 

这里写图片描述

问2. 从NAND FLASH芯片手册可知,要操作NAND FLASH需要先发出命令怎么传入命令?


答2.在DATA0~DATA7上既传输数据,又传输地址,也传输命令:


当ALE为高电平时传输的是地址。


当CLE为高电平时传输的是命令。


当ALE和CLE都为低电平时传输的是数据。


问3. 数据线既接到NAND FLASH,也接到NOR FLASH,还接到SDRAM、DM9000等等 

那么怎么避免干扰?


答3. 这些设备,要访问之必须”选中”,没有选中的芯片不会工作,相当于没接一样。


问4. 假设烧写NAND FLASH,把命令、地址、数据发给它之后,NAND FLASH肯定不可能瞬间完成烧写的,怎么判断烧写完成?


答4. 通过状态引脚RnB来判断:它为高电平表示就绪,它为低电平表示正忙


问5. 怎么操作NAND FLASH呢?


答5. 根据NAND FLASH的芯片手册,一般的过程是:


发出命令


发出地址


发出数据/读数据


看上面的命令表格,不容易看,我们看一下读ID的时序图, 

这里写图片描述

每个NAND FLASH都内嵌一些ID(譬如:厂家ID,设备ID),时序图从左往右看,纵向放是一列一列的看。


对于我们s3c2440来说,内部集成了一个NAND FLASH控制器,2440和外设连接的简易图,如下图所示 

这里写图片描述

NAND FLASH控制器,帮我们简化了对NAND FLASH的操作,下面来分析一下不使用NAND FLASH控制器和使用NAND FLASH控制器对外设NAND FLASH的操作。


发命令:

image.png?imageView2/2/w/550

发地址:

image.png?imageView2/2/w/550

发数据:

image.png?imageView2/2/w/550

读数据 :

image.png?imageView2/2/w/550


用UBOOT来体验NAND FLASH的操作:

  1. 读ID


image.png?imageView2/2/w/550

下图是读操作时序图 
这里写图片描述


对于存储为256M的NAND FLASH,需要28条地址线,来表示这个地址值,根据原理图可以,只用8根地址线,所以需要4个周期的地址,为了兼容更大容量的NAND FLASH,要发出5个周期的地址:

2,读数据

image.png?imageView2/2/w/550

第002节_NandFlash时序及初始化

image.png?imageView2/2/w/550


AND FLASH控制器的时序,是为了让NAND FLASH外设工作起来,假如外接不同的 

NAND FLASH外设,那么它的操作时序可能就会不同,所以NAND FLASH控制器发出 

的时序图,就是不一样的,所以我们根据NAND FLASH外设来设置NAND FLASH控制器, 

这里写图片描述

NAND FLASH时序图,如下所示: 

这里写图片描述
这里写图片描述
这里写图片描述

我们在汇编语言中已经设置HCLK为100MHZ,一个周期T = 1000/100 = 10s,通过上面三个图可以知道:TACLS的值可以为0;TWRPH0的值可以为1;TWRPH1的值可以为0。 
这里写图片描述

所以NFCONF寄存器设置如下:


#define  TACLS   0

#define  TWRPH0  1

#define  TWRPH1  0

/*设置NAND FLASH的时序*/

NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);


到此设置NAND FLASH的时序已经设置完了,我们接着来使能,使能实在NFCONT。 

这里写图片描述
MODE [0]: 设置为1,使能NAND FLASH。

Reg_nCE [1]: 设置为1,禁止片选。因为我们现在还没有使用。为例错误的操作。

InitECC [4]: 初始化ECC的编码器,后边要使用,我们设置为1,来初始化。

所以NFCONF寄存器设置如下:

/*使能NAND FLASH控制器,初始化ECC,禁止片选*/ NFCONT = (1<<4) | (1<<1) | (1<<0);



第003节_NandFlash的芯片id读取

上节课我们讲解了NAND FLASH的初始化,这节课我们来讲解读取NAND FLASH的ID, 
我们可以参考NAND FLASHh的芯片手册,如下图所示:(NAND FLASH读操作时序图) 
这里写图片描述



我们一般先操作片选使能,只有片选使能之后才能进行后边的操作,片选是能代码如下:


void nand_select(void)

{

    /*使能片选*/

    NFCONT &=~(1<<1);

}


有使能片选,一定有禁止片选,禁止片选的代码如下:


void nand_deselect(void)

{

    /*禁止片选*/

    NFCONT |= (1<<1);

}


读ID的操作时序图,如下所示 

这里写图片描述

我们按照从左往右的时间点,来分析,片选信号像一个总开关,只有使能了片选信号,后续的操作才会有意义,我们使能片选信号之后,片选引脚nCE后续一直为低电平,在前面的命令时序图中知道tCLS和tWP最小的时间参数都是12us,就表明CLE和nWE这两个信号可以同时发出,就表示要命令了,对于写什么命令,就要看数据总线上要发送的命令了,当CLE从高电平变为低电平后,表示上次的写操作已经结束了。


对于上面复杂的时序,我们可以使用2440上的NAND FLASH控制器简化操作,只需要往NFCMMD寄存器写入要传输的命令就可以了,NAND FLASH控制器默认把上面复杂的时序发出来。


发命令后,后面就需要发送地址了,当nWE和ALE有效的时候,表示写地址,上图中,要写入的地址是0x00,当ALE从高电平变为低电平的时候,表示写地址结束,我们可以简化为:往NFADDR寄存器中写值就可以了,比如:NFADDR=0x00。


下面我们写代码:发命令的函数,和发地址的函数代码如下:


void nand_cmd(unsigned char cmd)

{

    volatile int i;

    NFCCMD = cmd;

    for(i=0; i<10; i++);

}


void nand_addr_byte(unsigned char addr)

{

    volatile int i;

    NFADDR = addr;

    for(i=0; i<10; i++);

}


接下来就可以读取数据了,数据可以直接通过读取NFDATA寄存器里面数据来获得数据,根据时序图,是读5个字节的数据,代码如下:


unsigned char nand_data(void)

{

    return  NFDATA;

}


读芯片ID之前先打开片选, 读取芯片ID函数,代码如下:


void nand_chip_id(void)

    unsigned char buf[5]={0};


    nand_select(); 

    nand_cmd(0x90);

    nand_addr_byte(0x00);


    buf[0] = nand_data();

    buf[1] = nand_data();   

    buf[2] = nand_data();

    buf[3] = nand_data();

    buf[4] = nand_data();   

    nand_deselect();    


    printf("maker   id  = 0x%xnr",buf[0]);

    printf("device  id  = 0x%xnr",buf[1]);    

    printf("3rd byte    = 0x%xnr",buf[2]);        

    printf("4th byte    = 0x%xnr",buf[3]);            

    printf("page  size  = %d kbnr",1  <<  (buf[3] & 0x03));   

    printf("block size  = %d kbnr",64 << ((buf[3] >> 4) & 0x03)); 

    printf("5th byte    = 0x%xnr",buf[4]);

}


下面我们再写一个打印菜单的函数,在菜单中调用读取芯片ID的函数,代码如下


oid nand_flash_test(void)

{

    char c;


    while (1)

    {

        /* 打印菜单, 供我们选择测试内容 */

        printf("[s] Scan nand flashnr");

        printf("[e] Erase nand flashnr");

        printf("[w] Write nand flashnr");

        printf("[r] Read nand flashnr");

        printf("[q] quitnr");

        printf("Enter selection: ");


        c = getchar();

        printf("%cnr", c);


        /* 测试内容:

         * 1. 识别nand flash

         * 2. 擦除nand flash某个扇区

         * 3. 编写某个地址

         * 4. 读某个地址

         */

        switch (c)       

        {

            case 'q':

            case 'Q':

                return;

                break;


            case 's':

            case 'S':

                nand_chip_id();

                break;


            case 'e':

            case 'E':

                break;


            case 'w':

            case 'W':

                break;


            case 'r':

            case 'R':

                break;

            default:

                break;

        }

    }

}


在主函数中调用nand flash的初始化函数,和nand flash的测试函数。


int main(void)

{

    led_init();

    //interrupt_init();  /* 初始化中断控制器 */

    key_eint_init();   /* 初始化按键, 设为中断源 */

    //timer_init();


    puts("nrg_A = ");

    printHex(g_A);

    puts("nr");


    //nor_flash_test();

    nand_init();

    nand_flash_test();


    return 0;

}


第004节_NandFlash的数据读取

在上节 我们实现了芯片ID的读取,可是那个程序已经超过了4k,我们想把它烧到开发板的话,必需把它烧写到NOR FLASH上去,这节我们来讲解NAND FLASH数据的读取,并且实现超过4k的程序从NAND FLASH启动。


下图为NAND FLASH内部结构图,从图中可以可以知道,一个page含有2k 字节的页数据,和64字节的oob区,后面会介绍页数据和oob区有什么关系。 

这里写图片描述

下图的表格,来说明NAND FLASH内部结构,前面2K(0~2047)表示页数据,后边64字节(2048~2111)表示oob。 
这里写图片描述

问:CPU想读取,第2048个数据,它是哪以一个?


答:是Page1的第0个字节。CPU使用某个地址访问数据的时候,是在页数据空间来寻址的,根本就看不到oob区。


我们知道NAND FLASH 和 NOR FLASH相比有个缺点,NAND FLASH读或写一页数据的时候,可能会发生位反转,里面可能有一位是错误的,为了解决这个问题,引入oob区, 

它写页数据的时候,把数据写进页数据的同时会生成一个校验码,把这个校验码写进oob区里面,当读数据的时候,读出1页数据,读取1数据里面有可能有某一位发生错误,它继续读出原来的校验码,使用oob区里面的校验码,来修正页数据里面的数据。从这里我们可以得出一个结论,oob区的存在是为了解决NAND FLASH的缺陷而存在的。


CPU: 只关心数据,不需要看到oob区的校验码(把数据读出来,然后进行校验再把正确的数据返回,就可以了)。CPU想使用某个addr来访问数据的时候,addr是在页数据区间来寻址的,addr根本不会在oob区里面寻址。


为了形象在下面说一个幽默的对话来说明一下CPU和NAND FLASH的功能:


CPU大爷: 小nand啊,你的性能比不上小nor啊,听说你有位反转的毛病


Nand : 是的,大爷,位反转是我天生的毛病,时有时无


CPU大爷: 靠,你说你价格便宜容量大,这不是害我嘛


Nand : 没事,我有偏方,用OOB就可以解决这问题


CPU大爷: 得得得,你那偏方是什么也别告诉我,我只管能读写正确的数据


Nand : 是的,大爷,我这OOB偏方也就我自个私下使用。您就像使用nor一样使唤我就可以了


下面我们开始写程序,想去读NAND FLASH应该怎样操作,下面是nand flash的地址周期。 

这里写图片描述
下图为读NAND FLASH的时序操作: 
这里写图片描述

读NAND FLASH步骤:(从程序的角度来说),我们需要先发出00命令再发出5个周期的地址,再发出30命令,然后就可以读数据了。比如:我想访问某个地址的数据,需要确定在哪一行page(row),在哪一列col(0~2047)。从NAND FLASH的地址周期中可以看出来,先发出2个col(列地址),再发出3个(Row)行地址。 

下面是程序的编写: 

这里写图片描述

wait_ready函数等待NAND FLASHh空闲,从上图可以看出当NFSTAT寄存器[0]的值为1时NAND FLASH是空闲的,我们可以通过该位来判断NAND FLASH是否繁忙。代码如下:


void wait_ready(void)

{

    while (!(NFSTAT & 1));

}


nand_read函数为NAND FLASH的读函数,代码如下:


void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)

{

    int i = 0;

    int page = addr / 2048;

    int col  = addr & (2048 - 1);


    nand_select(); 


    while (i < len)

    {

        /* 发出00h命令 */

        nand_cmd(00);


        /* 发出地址 */

        /* col addr */

        nand_addr_byte(col & 0xff);

        nand_addr_byte((col>>8) & 0xff);


        /* row/page addr */

        nand_addr_byte(page & 0xff);

        nand_addr_byte((page>>8) & 0xff);

        nand_addr_byte((page>>16) & 0xff);


        /* 发出30h命令 */

        nand_cmd(0x30);


        /* 等待就绪 */

        wait_ready();


        /* 读数据 */

        for (; (col < 2048) && (i < len); col++)

        {

            buf[i++] = nand_data();         

        }

        if (i == len)

            break;


        col = 0;

        page++;

    }


    nand_deselect();    

}


在init.c文件中,加上如下代码,用来判断所使用的FLASH是NOR FLASH还是NAND FLASH。代码如下:


int isBootFromNorFlash(void)

{

    volatile unsigned int *p = (volatile unsigned int *)0;

    unsigned int val = *p;


    *p = 0x12345678;

    if (*p == 0x12345678)

推荐阅读

史海拾趣

E-Mark Inc公司的发展小趣事

在电子汽车行业初期,XYZ公司主要生产简单的车载电子设备。为了进入欧洲市场,公司决定对其产品进行E-Mark认证。经过严格的测试和审核,XYZ公司的产品质量和安全性能得到了欧洲市场的认可。随着欧洲市场的开拓,XYZ公司逐渐扩大了生产规模,提升了技术水平,最终成为了汽车电子行业的领导者。

CHONGQING PINGYANG ELECTRONICS CO.,LTD.公司的发展小趣事

在技术创新的基础上,重庆平洋电子有限公司积极拓展市场,不断提升品牌影响力。公司积极参与国内外各种电子展览和交流活动,与多家知名企业建立了战略合作关系。同时,公司还注重产品质量和售后服务,赢得了客户的信任和好评。随着品牌知名度的提升,公司的市场份额也逐年增长。

Bedford Opto公司的发展小趣事

随着国内市场的饱和,Bedford Opto公司开始寻求国际化扩张的机会。通过与国外知名企业的合作,公司成功打入国际市场,并获得了更多的业务机会。同时,公司还积极参与国际技术交流与合作,不断提升自身的技术水平和创新能力。

Electech Electronics公司的发展小趣事

Electech Electronics一直非常重视产品质量和品质管理。公司建立了严格的质量管理体系,从原材料采购到产品生产、检测和包装等各个环节都进行严格把控。此外,公司还不断引进先进的生产设备和技术,提升产品的制造精度和品质。这些举措使得Electech Electronics的产品在市场上享有很高的声誉,赢得了客户的信赖。

CW Industries公司的发展小趣事

CW Industries公司一直坚持从原材料到最终成品的完全一体化制造流程。这一制造模式使得公司能够对产品质量进行更严格的控制,并确保每一个生产环节的优化。为了进一步提高生产效率,CW Industries还引进了自动化设备,使得制造过程更加高效和精确。这种对生产流程的精细管理,让CW Industries在电子行业中树立了良好的口碑,并为公司的持续发展提供了有力保障。

Giga公司的发展小趣事
如开机自检、按键去抖等。

问答坊 | AI 解惑

如何学习单片机!

初学者如何学习单片机!请看这个吧!《51单片机C语言快速上手》! http://u.xunzai.com/fileview_46147.html http://pickup.mofile.com/7992587555186412 最好是用迅雷下载 [ 本帖最后由 lgh050706 于 2009-8-5 21:30 编辑 ]…

查看全部问答>

全国大学生电子设计竞赛历年试题

本帖最后由 paulhyde 于 2014-9-15 08:55 编辑 全国大学生电子设计竞赛历年试题  …

查看全部问答>

3D报纸引领阅读潮流 成本与内容成制约发展瓶颈

本帖最后由 jameswangsynnex 于 2015-3-3 19:57 编辑 自2009年年底起,3D在国内成为了“时尚”的代名词,继3D电影《阿凡达》、《爱丽丝梦游仙境》在中国市场赚得盆满钵满,3D似乎也成为了报刊企业的又一掘金点。   2010年4月16日,湖北《十堰晚 ...…

查看全部问答>

S3C6410 拍照问题,高手指教

程序预览没问题,拍照800*600也没问题 但是当拍照改为1024*768,1280*1024,1600*1200时,会出现无效数据,随着分辨率的增大,无效数据会越来越多。 当为1600*1200时,有效的部分好像是800*600的两倍。 感觉好像取到的数据一直是800*600,又感觉 ...…

查看全部问答>

关于开发CDMA的通信模块!

先祝各位达人元旦快乐! 我老板现在想开发CDMA的通信模块,就是网上很多卖的那种,可以通过串口或其他通用接口进行CDMA无线通信,但我查了很长时间仍然没有头绪……望各位达人指点一二: 用于开发CDMA模块一般都有什么芯片?我看网上大部分都是高 ...…

查看全部问答>

请教关于Powerpc文件系统的问题

Powerpc现在编译的文件系统是jff2格式,用串口线先传倒powerpc的RAM里,再复制进flash,但是现在文件系统似乎限制了大小,如果传3M左右就能正常启动,如果大于4M就不能正常启动,系统会不停重启。但是如果系统能正常启动后,用FTP上传文件,则没有 ...…

查看全部问答>

什么工具开发驱动程序最快最简单

什么工具开发驱动程序最快最简单? 需要那些基本知识? 介绍几本相关的学习资料,谢了!…

查看全部问答>

workbench!!

之前用的是vxworks+Tornado开发方式,一切比较顺利!! 最近单位买了最新版的vxworks,开发环境是workbench,刚接触,本打算先做启动软盘尝试启动vxworks,可发现每次编译后,目标机出现v1.6++++++++++++++++++然后又重起,尝试了各种方法,都是这样,请各位 ...…

查看全部问答>

【芯币兑换】AVR ATmega16学习板标准原理图

下面是最终版原理图,请大家参考 …

查看全部问答>

有湖北的吗?今年怎么还不出设备清单??

本帖最后由 paulhyde 于 2014-9-15 09:03 编辑 都12号了,还不出设备清单,往年都有的,武大咋搞的!!!  …

查看全部问答>