首页 > 代码库 > NandFlash读写

NandFlash读写

1.NandFlash分类

根据物理结构上的区别,NandFlash主要分为如下两类:
•SLC (Single Level Cell): 单层式存储
•MLC (Multi Level Cell): 多层式存储
SLC在存储格上只存一位数据,而MLC则存放两位数据。

2.MLC与SLC对比

价格:由于MLC采用了更高密度的存储方式,因此同容量的MLC价格上远低于SLC.
访问速度:SLC的访问速度一般要比MLC快3倍以上.
使用寿命:SLC能进行10万次的擦写,MLC能进行1万次
功耗:MLC功耗比SLC高15%左右

3.NandFlash初始化

3.1 设置时间参数TACLS 、TWRPH0、TWRPH1 

技术分享

3.2 使能NandFlash

技术分享

3.3 NandFlash复位

3.3.1 选中芯片

技术分享

3.3.2 清除RnB

技术分享

 

技术分享

3.3.3 发出复位信号(0xff)

技术分享

3.3.4 等待就绪

技术分享

 

技术分享

3.3.5 取消选中

 4.按页读取NandFlash的值

 技术分享

技术分享

步骤:

1.选中芯片;2.清除RnB;3.发出命令0x00;4.发送列地址;5.发送行地址;6.发出命令0x30;7.等待就绪;8.读数据 ;9.取消片选

5.向NandFlash写入数据

5.1 擦除(写之前要进行擦除)

技术分享

步骤:

1.选中芯片;2.清除RnB;3.发出命令0x60;4.发送行地址(3个周期);5.发送命令D0;6.等待RnB;7.发送命令70;8.读取擦除结果;9.取消片选

 5.2 写入数据

技术分享

步骤:

1.选中芯片;2.清除RnB;3.发出命令0x80;4.发送列地址(2个周期);5.发送行地址(3个周期);6.写入数据;7.发送命令0x10;8.等待RnB;9.发送命令70;10.读取写入结果;10.取消片选

6.代码

nand.c

技术分享
  1 /*  2 tiny6410用的nandflash为 一页2K  3 */  4   5   6 #define NFCONF             (*((volatile unsigned long*)0x70200000))  7 #define NFCONT             (*((volatile unsigned long*)0x70200004))  8 #define NFCMMD             (*((volatile unsigned char*)0x70200008))  9 #define NFSTAT             (*((volatile unsigned char*)0x70200028)) 10 #define NFADDR             (*((volatile unsigned char*)0x7020000c)) 11 #define NFDATA             (*((volatile unsigned char*)0x70200010)) 12  13 void select_ship(void) 14 { 15     NFCONT &= ~(1<<1);     16 } 17  18 void delselect_ship(void) 19 { 20     NFCONT |= (1<<1); 21 } 22  23 void clean_RnB() 24 { 25     NFSTAT |= (1<<4); 26 }  27 void nand_cmd(unsigned char cmd) 28 { 29     NFCMMD = cmd;    30 } 31  32 void wait_RnB(void) 33 { 34     while(!(NFSTAT & 0x1)); 35 } 36  37 void nand_addr(unsigned char addr) 38 { 39     NFADDR = addr; 40 } 41  42 void nand_reset(void) 43 { 44     /* 选中 */ 45     select_ship(); 46      47     /* 清除RnB */ 48     clean_RnB(); 49      50     /* 发出复位信号 */ 51     nand_cmd(0xff); 52      53     /* 等待就绪 */ 54     wait_RnB(); 55      56     /* 取消选中 */ 57     delselect_ship(); 58 } 59  60 void nand_init(void) 61 {  62  63      64     /* 设置时间参数 */ 65 #define TACLS  7 66 #define TWRPH0 7 67 #define TWRPH1 7 68      69     NFCONF &= ~((7<<12)|(7<<8)|(7<<4)); 70     NFCONF |= (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); 71      72     /* 使能 nandflash controller*/ 73     NFCONT = 1 | (1<<1); 74      75      76      77     /* 复位 */ 78     nand_reset(); 79 } 80  81 void NF_PageRead(unsigned long addr,unsigned char* buff) 82 { 83     int i; 84      85      86     /* 选中芯片 */ 87     select_ship(); 88      89     /* 清除RnB */ 90     clean_RnB(); 91      92     /* 发出命令0x00 */ 93      nand_cmd(0x00); 94          95      /* 发出列地址 */ 96     nand_addr(0x00); 97     nand_addr(0x00); 98  99     /* 发出行地址 */100     nand_addr(addr&0xff);101     nand_addr((addr >>8 ) & (0xff));102     nand_addr((addr >>16 ) & (0xff));103         104     /* 发出命令0x30 */105      nand_cmd(0x30);106         107     /* 等待就绪 */108      wait_RnB();109         110     /* 读数据 */111      for(i = 0; i<1024*2; i++)112     {113         *buff++ = NFDATA;114     }115         116       117      /* 取消片选 */118      119      delselect_ship();120      121 }122 123 124 int NF_Erase(unsigned long addr)125 {126     int ret;127     128     //选中flash芯片129     select_ship();130     131     //清除RnB132     clean_RnB();133     134     //发送命令60135     nand_cmd(0x60);136     137     //发送行地址(3个周期)138     nand_addr(addr&0xff);139         nand_addr((addr >>8 ) & (0xff));140         nand_addr((addr >>16 ) & (0xff));141     142     //发送命令D0143     nand_cmd(0xD0);144     145     //等待RnB146     wait_RnB();147     148     //发送命令70149     nand_cmd(0x70);150     151     //读取擦除结果152     ret = NFDATA;153     154     //取消选中flash芯片155     delselect_ship();156     157     return ret;158 }159 160 int NF_WritePage(unsigned long addr,unsigned char* buff)161 {162     int ret,i;163     164     //选中flash芯片165     select_ship();166     167     //清除RnB168     clean_RnB();169     170     //发送命令80171     nand_cmd(0x80);172     173     //发送列地址(2个周期)174     nand_addr(0x00);175         nand_addr(0x00);176     177     //发送行地址(3个周期)178     nand_addr(addr&0xff);179         nand_addr((addr >>8 ) & (0xff));180         nand_addr((addr >>16 ) & (0xff));181     182     //写入数据183     for(i=0;i<1024*2;i++)184     {185         NFDATA =http://www.mamicode.com/ buff[i];    186     }187     188     //发送命令10189     nand_cmd(0x10);190     191     //等待RnB192     wait_RnB();193     194     //发送命令70195     nand_cmd(0x70);196     197     //读取写入结果198     ret = NFDATA;199     200     //取消选中flash芯片201     delselect_ship();202     203     return ret;204 }
nand.c

nand_to_ram

技术分享
 1 copy_to_ram: 2     mov r0,#0 3     ldr r1,=_start 4     ldr r2,=bss_end 5      6     sub r2,r2,r1 7     mov ip,lr 8     bl nand_to_ram 9     10     mov lr,ip11     12     13     mov pc,lr
start.S
技术分享
 1 void nand_to_ram(unsigned long start_addr,unsigned char* sdram_addr,int size) 2 { 3         int i; 4                 5     for( i=(start_addr >>11); size>0;) 6     { 7         NF_PageRead(i,sdram_addr);     8         size -= 2048; 9         sdram_addr += 2048;10         i++;11     }12         13 }
nand_to_ram

 

NandFlash读写