Flash 存储器具有ROM存储器的结构特点,存储在该芯片中的数据可在断电情况下保持10年而不丢失,而芯片的引脚和访问又具有类似于RAM的特点。由于芯片直接提供有数据,地址,读,写和片选控制等信号引脚且与CPU相连十分方便,因此,FLASH存储器应用越来越广泛。
单片机扩展外部Nand FLASH存储器K9F5608的电路设计如图所示(在本例中,由于扩展的存储器不占用单片机的数据存储空间,因此扩展电路中单片机的/EA端可以不接地。)
程序流程图(需要注意的是NAND FLASH存储器K9F5608遵循块擦除,页写入的操作方式)
程序如下
******************************************************************************
单片机对Nand flash存储器K9F5608读写程序,本节所列程序包括:块擦除子程序、页写入子程序、页读取子程序、读状态寄存器子程序、读取ID子程序、
******************************************************************************
#include<eg51.h>
uchar addr0,addr1,addr2;
uchar dbuf[64]
//1单片机对K9f5608的控制位功能定义
sbit CE=P2.1 //片选信号
sbitWP=P2.2 //写保护
sbitALE=2.3 // 地址锁存
sbitCLE=2.4 //命令锁存
sbitWE=2.5 //写允许
sbitRE=2.6 //读允许
sbitBUSY=2.7 //工作状态
//主程序实现将64个字节数据写入K9f5608存储器地址为8888 A800开始的存储空间
Void main()
{
CE=0; //芯片初始未选定,低功耗,且写保护
WP=0;
addr0=0x00; //芯片存储单元指针
addr1=0x11;
addr2=0x00;
WP=1; //芯片可读可写
CLE=0; //以下为芯片初始为待工作状态
ALE=0;
WE=1;
RE=1;
CE=0;
command=0xff; //芯片复位
sendcom(command);
delay();
}
//以下为主程序中调用的子程序,每个子程序实现对K9F5608的部分操作功能,
//向K9F5608发送一个字节命令子程序
Void sendcom(uchar code)
{
While(BUSY=0)
{;}
CLE=1; //控制总线处于写命令状态
WE=0;
P0=code;
CLE=10; //控制总线恢复初始状态
WE=1;
}
//向K9f5608发送一个字节数据子程序
Void sendbyte(uchar data)
{
While(BUSY=0) 状态判断
{;}
WE=0; //控制总线处于写数据状态
P0=code;
WE=1; //控制总线恢复初始状态
}
//向K9F5608发送一个字节地址子程序
Void sendaddr(uchar add)
{
While(BUSY=0)
{;}
ALE=1; //控制总线处于写地状态
WE=0;
P0=addr; //控制总线恢复初始状态
WE=1;
}
//从K9F5608读取一个字节数据子程序
Void readbyte()
{
uchar temp;
while(BUSY=0)
{;}
RE=0; //控制总线处于读数据状态
Temp=P0;
RE=1; //控制总线恢复初始状态
return temp; 返回读取的数据
}
//从K9F5608读取528个字节数据子程序,也就是页读取操作,将对页地址为0011H页面最后16字节以及也地址为0012页面的前512字节数据进行读操作
void readpage()
{
sendcom(0x50) //发送页读取命令
sendaddr(add0) //发送地址0
sendaddr(add1) //发送地址1
sendaddr(add2) //发送地址2
do{;}
while(BUSY=0)
for(i=0,i<529;i++) //读取528字节数据
{
uchar tempdata
tempdata=readbyte()
}
}
//向K9F5608写入528个字节数据子程序,也就是页写入(编程)操作,将对页地址为0011H页面528字节单元写入数据01H
void writepage()
{
sendcom(0x80) //发送页写入命令1
sendaddr(add0) //发送地址0
sendaddr(add1) //发送地址1
sendaddr(add2) //发送地址2
for(i=0,i<529;i++) //读取528字节数据
{
sendbyte(0x01);
}
sendcom(0x10) //发送页写入命令2
do{;}
while(BUSY=0)
sendcom(0x70) //发送页写入命令2
temp=readbyte() //读取状态寄存器值
temp=temp&&0x01; //取状态寄存器最低位状态值
if(temp=0x01)
err(); //写入出错
else ok(); //写入完成
} |