zoukankan      html  css  js  c++  java
  • 第二季-专题13-NandFlash变硬盘

    专题3-NandFlash变硬盘

    第1课-NandFlash原理解析

    1. 角色分析

    在电脑中有硬盘,它是用来存储文件的。嵌入式系统是防电脑的系统,在嵌入式系统中,NandFlash就相当于硬盘的存在。

    1. NandFlash的分类

    2.1 根据物理结构上的区别,NandFlash主要分为如下两类:

    l  SLC(Single Level Cell):单层式存储

    l  MLC(Muti Level Cell):多层式存储

    SLC在存储格上只存一位数据,而MLC则存放两位数据

    2.2 MLC对比SLC

    价格:由于MLC采用了更高密度的存储方式,因此同容量的MLC价格上远低于SLC

    访问速度:SLC的访问速度一般要比MLC快3倍以上

    使用寿命:SLC能进行10万次的擦写,MLC能进行1万次

    功耗:MLC功耗比SLC高15%左右

    1. 访问方式

    (1)       对比内存与NandFlash的编址区别

    CPU内部有NandFlash控制,负责NandFlash与CPU之间的通信,通过地址、命令和数据三个寄存器来完成这一系列的通信。

    (2)       NandFlash地址构成

    一块NandFlash划分成多个Block,一个Block划分成多个page,一个page划分成两个部分。

    (3)       信号引脚

    CLE(Command Latch Enable): 命令锁存允许

    ALE(Address Lactch Enable): 地址锁存允许

    CE:芯片选择

    RE:读允许

    WE:写允许

    WE:写允许

    WP:在写或擦除期间,提供写保护

     R/B:读/忙

    第2课-NandFlash驱动设计~读

    #define NFCONF (*(volatile unsigned long*)0x4E000000)

    #define NFCONT (*(volatile unsigned long*)0x4E000004)

    #define NFSTAT (*(volatile unsigned char*)0x4E000020)

    #define NFCMD  (*(volatile unsigned char*)0x4E000008)

    #define NFADDR (*(volatile unsigned char*)0x4E00000C)

    #define NFDATA (*(volatile unsigned char*)0x4E000010)

     

    #define TACLS 1

    #define TWRPH0 2

    #define TWRPH1 1

     

     

    void select_chip()

    {

        NFCONT &= ~(1<<1);

    }

     

    void deselect_chip()

    {

        NFCONT |= (1<<1);

    }

     

    void clear_RnB()

    {

       NFSTAT |= (1<<2);

    }

     

    void send_cmd(unsigned cmd)

    {

         NFCMD = cmd;

    }

     

    void send_addr(unsigned addr)

    {

         NFADDR = addr;

    }

     

    void wait_RnB()

    {

       while (!(NFSTAT&(1<<2)))  

       {

           ;

       }

    }

     

    void nand_reset()

    {

        //选中flash

        select_chip();

       

        //清除RnB

        clear_RnB();

       

       

        //发送0xff命令

        send_cmd(0xff);

       

       

        //等待RnB

        wait_RnB();

       

       

        //取消选中flash

        deselect_chip();

    }

     

    void nand_init()

    {

        //初始化NFCONF

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

       

        //初始化NFCONT

        NFCONT = (1<<0) | (1<<1);

       

        //复位

        nand_reset();

    }

     

    void NF_PageRead(unsigned long addr,unsigned char* buff)

    {

        int i;

       

        //选中nandflash芯片

        select_chip();

       

        //清除RnB

        clear_RnB();

       

        //发送命令0x00

        send_cmd(0x00);

       

        //发送列地址

        send_addr(0x00);

        send_addr(0x00);

       

        //发送行地址

        send_addr(addr&0xff);

        send_addr((addr>>8)&0xff);

        send_addr((addr>>16)&0xff);

       

        //发送命令0x30

        send_cmd(0x30);

       

        //等待RnB

        wait_RnB();

       

        //读取数据

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

        {

           buff[i] = NFDATA; 

        }

       

        //取消选中nandflash芯片

        deselect_chip();

    }

     

     

    void nand_to_ram(unsigned long start_addr, unsigned char* sdram_addr, int size)

    {

         int i;

         

        for( i=(start_addr >>11); size>0;)

        {

            NF_PageRead(i,sdram_addr);

            size -= 2048;

            sdram_addr += 2048;

            i++;

        }

    }

    第3课-NandFlash驱动设计~写

    #define NFCONF (*(volatile unsigned long*)0x4E000000)

    #define NFCONT (*(volatile unsigned long*)0x4E000004)

    #define NFSTAT (*(volatile unsigned char*)0x4E000020)

    #define NFCMD  (*(volatile unsigned char*)0x4E000008)

    #define NFADDR (*(volatile unsigned char*)0x4E00000C)

    #define NFDATA (*(volatile unsigned char*)0x4E000010)

     

    #define TACLS 1

    #define TWRPH0 2

    #define TWRPH1 1

     

     

    void select_chip()

    {

        NFCONT &= ~(1<<1);

    }

     

    void deselect_chip()

    {

        NFCONT |= (1<<1);

    }

     

    void clear_RnB()

    {

       NFSTAT |= (1<<2);

    }

     

    void send_cmd(unsigned cmd)

    {

         NFCMD = cmd;

    }

     

    void send_addr(unsigned addr)

    {

         NFADDR = addr;

    }

     

    void wait_RnB()

    {

       while (!(NFSTAT&(1<<2)))  

       {

           ;

       }

    }

     

    void nand_reset()

    {

        //选中flash

        select_chip();

       

        //清除RnB

        clear_RnB();

       

       

        //发送0xff命令

        send_cmd(0xff);

       

       

        //等待RnB

        wait_RnB();

       

       

        //取消选中flash

        deselect_chip();

    }

     

    void nand_init()

    {

        //初始化NFCONF

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

       

        //初始化NFCONT

        NFCONT = (1<<0) | (1<<1);

       

        //复位

        nand_reset();

    }

     

    void NF_PageRead(unsigned long addr,unsigned char* buff)

    {

        int i;

       

        //选中nandflash芯片

        select_chip();

       

        //清除RnB

        clear_RnB();

       

        //发送命令0x00

        send_cmd(0x00);

       

        //发送列地址

        send_addr(0x00);

        send_addr(0x00);

       

        //发送行地址

        send_addr(addr&0xff);

        send_addr((addr>>8)&0xff);

        send_addr((addr>>16)&0xff);

       

        //发送命令0x30

        send_cmd(0x30);

       

        //等待RnB

        wait_RnB();

       

        //读取数据

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

        {

           buff[i] = NFDATA; 

        }

       

        //取消选中nandflash芯片

        deselect_chip();

    }

     

     

    void nand_to_ram(unsigned long start_addr, unsigned char* sdram_addr, int size)

    {

         int i;

        

        for( i=(start_addr >>11); size>0;)

        {

            NF_PageRead(i,sdram_addr);

            size -= 2048;

            sdram_addr += 2048;

            i++;

        }

    }

     

     

    int NF_WritePage(unsigned long addr, unsigned char* buff)

    {

        int ret;

        int i;

       

        //选中flash芯片

        select_chip();

       

        //清除RnB

        clear_RnB();

       

        //发送命令0x80

        send_cmd(0x80);

       

        //发送列地址

        send_addr(0x00);

        send_addr(0x00);

       

        //发送行地址

        send_addr(addr&0xff);

        send_addr((addr>>8)&0xff);

        send_addr((addr>>16)&0xff);

       

        //写入数据

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

        {

           NFDATA = buff[i];

        }

       

        //发送命令0x10

        send_cmd(0x10);

       

        //等待RnB

        wait_RnB();

       

        //发送命令0x70

        send_cmd(0x70);

       

        //读取写入结果

        ret = NFDATA;

       

        //取消选中flash芯片

        deselect_chip();

       

        return ret; 

    }

  • 相关阅读:
    算法设计策略
    挖金矿
    寻找假币
    循环赛日程表
    【三分钟视频教程】iOS开发中 Xcode 报 apple-o linker 错误的#解决方案#
    iOS问题#解决方案#之关于“application/x-www-form-urlencoded;charset=utf-8” not supported
    【两分钟教程】如何为博客园添加QQ咨询效果
    【两分钟教程】如何更改Xcode项目名称
    iOS数据库操作之coredata详细操作步骤
    svn使用笔记
  • 原文地址:https://www.cnblogs.com/free-1122/p/11452183.html
Copyright © 2011-2022 走看看