Nand Flash支持按页写和随机写两种方式,在下面实现的是按页写。闪存在写数据时,只能写入1,不能写入0,所以写函数必须和擦除函数一起使用,并且擦除函数是按块擦除。
/******************************************************************** *名称:write_page_flash *参数: * page 页号 * buf 写缓存,2048字节 *返回: * state 成功:0 * 失败:1 *功能:按页写闪存 *********************************************************************/ int write_page_flash(unsigned long page, unsigned char *buf){ int i; //循环计数器 int state; //写入状态,0表示成功,1表示失败 //选中闪存芯片 NFCONT &= ~(1<<1); //设置Reg_nCE:0 //清除忙信号 NFSTAT |= (1<<2); //设置RnB_TransDetect:0 //发送写命令(0x80) NFCMMD = 0x80; //发送列地址(页内偏移) NFADDR = 0x00; //Col.Add1,按页写忽略页内偏移 NFADDR = 0x00; //Col.Add2 //发送行地址(页号) NFADDR = (page>>0)&0xFF; //Row.Add1 NFADDR = (page>>8)&0xFF; //Row.Add2 NFADDR = (page>>16)&0xFF; //Row.Add3 //写入数据 for(i = 0; i < PAGE_SIZE; i++){ NFDATA = buf[i]; //注意,NFDATA寄存器数据类型要和buf匹配,一个写周期写入一个字节 } //发送写命令(0x10) NFCMMD = 0x10; //等待忙信号 while( !(NFSTAT&(1<<2)) ); //当RnB_TransDetect等于1时,结束循环 //发送读状态命令(0x70) NFCMMD = 0x70; //读取状态 state = NFDATA&0x00000001; //取出数据端口I/O的0位,否则返回随机值 //释放闪存芯片 NFCONT |= 1<<1; //设置Reg_nCE:1 return state; } /******************************************************************** *名称:erase_block_flash *参数: * page 页号 *返回: * state 成功:0 * 失败:1 *功能:按块擦除闪存。提供页的地址,擦除所在的块。 *********************************************************************/ int erase_block_flash(unsigned long page){ int state; //写入状态,0表示成功,1表示失败 //选中闪存芯片 NFCONT &= ~(1<<1); //设置Reg_nCE:0 //清除忙信号 NFSTAT |= (1<<2); //设置RnB_TransDetect:0 //发送擦除命令(0x60) NFCMMD = 0x60; //发送行地址(页号) NFADDR = (page>>0)&0xFF; //Row.Add1 NFADDR = (page>>8)&0xFF; //Row.Add2 NFADDR = (page>>16)&0xFF; //Row.Add3 //发送擦除命令(0xD0) NFCMMD = 0xD0; //等待忙信号 while( !(NFSTAT&(1<<2)) ); //当RnB_TransDetect等于1时,结束循环 //发送读状态命令(0x70) NFCMMD = 0x70; //读取状态 state = NFDATA&0x00000001; //取出数据端口I/O的0位,否则返回随机值 //释放闪存芯片 NFCONT |= 1<<1; //设置Reg_nCE:1 return state; }