51单片机控制K9K8G08U0C NAND Flash读写程序
时间:10-24
来源:互联网
点击:
#include STC12C5A60S2.H>
#include intrins.h>
#include SMG.h>
/********************************************/
sbit NF_CLE=P0^3; //命令锁存使能(输出) CLE D3
sbit NF_ALE=P3^4; //地址锁存使能(输出) ALE RS
sbit NF_WE=P1^3; //NAND Flash写使能(输出) /WE DB4
sbit NF_RE=P1^2; //NAND Flash读使能(输出) /RE DB3
sbit NF_CE=P3^7; //NAND Flash片选使能(输出)/CE RD
sbit NF_R_B=P3^5; //NAND Flash就绪/忙(输入) r/b R/D_LCDEN
sbit NF_WP=P3^6; //不用(已接到VCC) /WP
#define NF_DATA P2
/****************************************************/
sbit DIOLA=P2^5;
/**********************************************/
//unsigned int DataArray[10];
/*************************************************/
// 12c5A60S2单片机初始化
/*********************************************************/
void MCU_Init()
{
P0M0=0x00;
P0M1=0x00;
P1M0=0x00;
P1M1=0x00;
P2M0=0x00;
P2M1=0x00;
P3M0=0x00;
P3M1=0x00;
AUXR=0x00;
//TMOD=0x21;
}
/************************************************/
void TimerInit()
{
TMOD=0x20; //设置定时器1为工作方式2 (0x22;)
TH1=0xfd; //装入初值 (0xef;)
TL1=0xfd; //装入初值 (0xef;)
TR1=1; //启动定时器
REN=1; //允许串口接收位
SM0=1;SM1=0; //方式1
SCON=0x50;
///////
EA=1;
ES=1;
// PCON=0x80;
//PS=1;
//PT0=0;
} //晶振:22.1184M 波特率:19200
/**********************************************/
//延时
/*************************************************/
void delay(unsigned int z)//延时参数(z)无反回值的子程序(void表示无反值)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
/***************************************************
//模 块 名:51单片机控制K9K8G08U0C的读写程序
//功能描述:NANDFLASH读写程序
//兼容性 :适合大部分的NANDFLASH,如需要根据手册做简单修改即可
//芯片型号: STC89C516RD STC12C5A60S2等。
****************************************************/
// NANDFLASH使能信号初始化
////////////////////////////////////////////////////////////////
void NF_Initial()
{
NF_CLE=0;NF_ALE=0;NF_CE=1;
NF_WE=1;NF_RE=1;NF_WP=1;
}
/********************************************************/
/*****************************************************/
//命令函数 NAND Flash Command
//Read1 00h/01h
//Read2 50h
//读取芯片ID 90h
//RESET FFh
//写页 80h 10h
//块擦除 60h D0h
//读取状态 70h/7ah
//******************************************
void NF_Command(unsigned char command)
{
//P2=0xff;
NF_ALE=0;
//NF_CE=0;
NF_CLE=1;
NF_WE=0;
NF_ALE=0;
NF_DATA=command;
NF_WE=1;
NF_CLE=0;
// NF_ALE=1;
//P2=0xff;
}
/**************************************************/
/**********************************************************/
//读取芯片ID函数 NAND Flash Read_ID
//读取芯片ID 90h
//******************************************
unsigned char NF_ReadID()
{
unsigned char a,b,c,d;
NF_Initial();
NF_CE=0;
NF_Command(0x90); //输入命令
NF_ALE=1;
NF_WE=0;
NF_DATA=0x00; //address,1cycle
NF_WE=1;
NF_ALE=0;
NF_DATA=0xff;
NF_RE=0;
a=0xffNF_DATA; //ECH
NF_RE=1;
NF_DATA=0xff;
NF_RE=0;
b=0xffNF_DATA; //76H
NF_RE=1;
NF_DATA=0xff;
NF_RE=0;
c=0xffNF_DATA; //3fH
NF_RE=1;
NF_DATA=0xff;
NF_RE=0;
c=0xffNF_DATA; //00H
NF_RE=1;
NF_CE=1;
/*NF_RE=0;
a=0x00ffP2;
NF_RE=1;
P2=0xff;
NF_RE=0;
a=(P2*256)|a;
NF_RE=1;
NF_CE=1;
*/
return a;
}
/************************************************/
/***********************************************/
//命令函数 NAND Flash status
//读取状态 70h/7ah
//******************************************
unsigned char NF_ReadStatus()
{
unsigned char s;
NF_Initial();
NF_CE=0;
NF_Command(0x70);
NF_DATA=0xff;
NF_RE=0;_nop_();
s=NF_DATA0x01;
NF_RE=1;
NF_CE=1;
if(s==0x00) return (0xff); //正确
else return (0x00); //错误
}
/**************************************************/
/************************************************/
//块擦除芯片 NAND Flash EraseBlock
//块擦除 60h D0h
//******************************************
unsigned char NF_EraseBlock(unsigned char Pageadd)
{
unsigned char s=0; //用来取状态,其实可以不要
NF_Initial();
NF_CE=0;
NF_Command(0x60);
NF_ALE=1;
NF_WE=0;
NF_DATA=Pageadd0xff; //NF_DATA=((Pageadd%256)%256)0xff;
NF_WE=1;
NF_WE=0;
NF_DATA=(Pageadd>>8)0xff; //NF_DATA=((Pageadd%256)/256)0xff;
NF_WE=1;
NF_WE=0;
NF_DATA=(Pageadd>>16)0xff; // NF_DATA=(Pageadd/256)0xff;
NF_WE=1;
NF_ALE=0;
NF_Command(0xd0);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
return (s);
}
/********************************************************/
/**********************************************/
//发送地址 NAND Flash Send Addre
//******************************************
unsigned char NF_SendAddre(unsigned char Pageadd,unsigned char Columnadd)
{
NF_ALE=1;
NF_WE=0;
NF_DATA=Columnadd;
NF_WE=1;
//送地址第一个字节,列地址(其实就是那512个字节地地址)
NF_WE=0;
NF_DATA=Pageadd0xff; //NF_DATA=((Pageadd%256)%256)0xff;
NF_WE=1;
//送地址第二个字节,低五位是页地址,高三位是块地址的低三位(1block = 32page)
NF_WE=0;
NF_DATA=(Pageadd>>8)0xff; //NF_DATA=((Pageadd%256)/256)0xff;
NF_WE=1;
//送地址第三个字节,块地址
NF_WE=0;
NF_DATA=(Pageadd>>16)0xff; // NF_DATA=(Pageadd/256)0xff;
NF_WE=1;
//送地址第四个字节,块地址
NF_ALE=0;
P2=0xff;
}
/********************************************************/
/********************************************************/
//写入一个字节的数据 NAND Flash WirteByte
//写入命令 80h 10h
//******************************************
unsigned char NF_WirteByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char NF_dat)
{
unsigned char s=0;
NF_Initial();
NF_CE=0;
// NF_Command(0x50);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_Command(0x80);
NF_SendAddre(Pageadd,Columnadd);
NF_WE=0;
NF_DATA=NF_dat;
NF_WE=1;
NF_Command(0x10);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
}
/****************************************************/
/******************************************************/
//读取一个字节 NAND Flash ReadByte
//读取命令 00h/01h (half)
//******************************************
unsigned char NF_ReadByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char half)
{
unsigned char NF_dat,s=0;
NF_Initial();
NF_CE=0;
NF_Command(half);
NF_SendAddre(Pageadd,Columnadd);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_DATA=0xff;
NF_RE=0;
NF_dat=NF_DATA;
NF_RE=1;
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
return (NF_dat);
}
/***********************************************/
/**********************************************/
//写入多个字节的数据 NAND Flash WirteByte
//写入命令 80h 10h (PCS最大取512)
//************************************************
unsigned char NF_WirteNByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char *P_NF,unsigned char pcs)
{
unsigned char s,i;
NF_Initial();
NF_CE=0;
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_Command(0x00);
NF_Command(0x80);
NF_SendAddre(Pageadd,Columnadd);
for(i=0;i pcs;i++)
{
NF_WE=0;
NF_DATA=*P_NF;
NF_WE=1;
P_NF++;
}
NF_Command(0x10);
while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
}
/**************************************************/
/*************************************/
//读取多个字节 NAND Flash ReadByte
//读取命令 00h/01h (half)(PCS最大取512)
//******************************************
unsigned char NF_ReadNByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char half,unsigned char *P_NF,unsigned char pcs)
{
unsigned char i,s=0;
NF_Initial();
NF_CE=0;
NF_Command(half);
NF_SendAddre(Pageadd,Columnadd);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_DATA=0xff;
for(i=0;i pcs;i++)
{
NF_RE=0;
*P_NF=NF_DATA;
NF_RE=1;
P_NF++;
}
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
// return (NF_dat);
}
/****************************************************
#include intrins.h>
#include SMG.h>
/********************************************/
sbit NF_CLE=P0^3; //命令锁存使能(输出) CLE D3
sbit NF_ALE=P3^4; //地址锁存使能(输出) ALE RS
sbit NF_WE=P1^3; //NAND Flash写使能(输出) /WE DB4
sbit NF_RE=P1^2; //NAND Flash读使能(输出) /RE DB3
sbit NF_CE=P3^7; //NAND Flash片选使能(输出)/CE RD
sbit NF_R_B=P3^5; //NAND Flash就绪/忙(输入) r/b R/D_LCDEN
sbit NF_WP=P3^6; //不用(已接到VCC) /WP
#define NF_DATA P2
/****************************************************/
sbit DIOLA=P2^5;
/**********************************************/
//unsigned int DataArray[10];
/*************************************************/
// 12c5A60S2单片机初始化
/*********************************************************/
void MCU_Init()
{
P0M0=0x00;
P0M1=0x00;
P1M0=0x00;
P1M1=0x00;
P2M0=0x00;
P2M1=0x00;
P3M0=0x00;
P3M1=0x00;
AUXR=0x00;
//TMOD=0x21;
}
/************************************************/
void TimerInit()
{
TMOD=0x20; //设置定时器1为工作方式2 (0x22;)
TH1=0xfd; //装入初值 (0xef;)
TL1=0xfd; //装入初值 (0xef;)
TR1=1; //启动定时器
REN=1; //允许串口接收位
SM0=1;SM1=0; //方式1
SCON=0x50;
///////
EA=1;
ES=1;
// PCON=0x80;
//PS=1;
//PT0=0;
} //晶振:22.1184M 波特率:19200
/**********************************************/
//延时
/*************************************************/
void delay(unsigned int z)//延时参数(z)无反回值的子程序(void表示无反值)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
/***************************************************
//模 块 名:51单片机控制K9K8G08U0C的读写程序
//功能描述:NANDFLASH读写程序
//兼容性 :适合大部分的NANDFLASH,如需要根据手册做简单修改即可
//芯片型号: STC89C516RD STC12C5A60S2等。
****************************************************/
// NANDFLASH使能信号初始化
////////////////////////////////////////////////////////////////
void NF_Initial()
{
NF_CLE=0;NF_ALE=0;NF_CE=1;
NF_WE=1;NF_RE=1;NF_WP=1;
}
/********************************************************/
/*****************************************************/
//命令函数 NAND Flash Command
//Read1 00h/01h
//Read2 50h
//读取芯片ID 90h
//RESET FFh
//写页 80h 10h
//块擦除 60h D0h
//读取状态 70h/7ah
//******************************************
void NF_Command(unsigned char command)
{
//P2=0xff;
NF_ALE=0;
//NF_CE=0;
NF_CLE=1;
NF_WE=0;
NF_ALE=0;
NF_DATA=command;
NF_WE=1;
NF_CLE=0;
// NF_ALE=1;
//P2=0xff;
}
/**************************************************/
/**********************************************************/
//读取芯片ID函数 NAND Flash Read_ID
//读取芯片ID 90h
//******************************************
unsigned char NF_ReadID()
{
unsigned char a,b,c,d;
NF_Initial();
NF_CE=0;
NF_Command(0x90); //输入命令
NF_ALE=1;
NF_WE=0;
NF_DATA=0x00; //address,1cycle
NF_WE=1;
NF_ALE=0;
NF_DATA=0xff;
NF_RE=0;
a=0xffNF_DATA; //ECH
NF_RE=1;
NF_DATA=0xff;
NF_RE=0;
b=0xffNF_DATA; //76H
NF_RE=1;
NF_DATA=0xff;
NF_RE=0;
c=0xffNF_DATA; //3fH
NF_RE=1;
NF_DATA=0xff;
NF_RE=0;
c=0xffNF_DATA; //00H
NF_RE=1;
NF_CE=1;
/*NF_RE=0;
a=0x00ffP2;
NF_RE=1;
P2=0xff;
NF_RE=0;
a=(P2*256)|a;
NF_RE=1;
NF_CE=1;
*/
return a;
}
/************************************************/
/***********************************************/
//命令函数 NAND Flash status
//读取状态 70h/7ah
//******************************************
unsigned char NF_ReadStatus()
{
unsigned char s;
NF_Initial();
NF_CE=0;
NF_Command(0x70);
NF_DATA=0xff;
NF_RE=0;_nop_();
s=NF_DATA0x01;
NF_RE=1;
NF_CE=1;
if(s==0x00) return (0xff); //正确
else return (0x00); //错误
}
/**************************************************/
/************************************************/
//块擦除芯片 NAND Flash EraseBlock
//块擦除 60h D0h
//******************************************
unsigned char NF_EraseBlock(unsigned char Pageadd)
{
unsigned char s=0; //用来取状态,其实可以不要
NF_Initial();
NF_CE=0;
NF_Command(0x60);
NF_ALE=1;
NF_WE=0;
NF_DATA=Pageadd0xff; //NF_DATA=((Pageadd%256)%256)0xff;
NF_WE=1;
NF_WE=0;
NF_DATA=(Pageadd>>8)0xff; //NF_DATA=((Pageadd%256)/256)0xff;
NF_WE=1;
NF_WE=0;
NF_DATA=(Pageadd>>16)0xff; // NF_DATA=(Pageadd/256)0xff;
NF_WE=1;
NF_ALE=0;
NF_Command(0xd0);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
return (s);
}
/********************************************************/
/**********************************************/
//发送地址 NAND Flash Send Addre
//******************************************
unsigned char NF_SendAddre(unsigned char Pageadd,unsigned char Columnadd)
{
NF_ALE=1;
NF_WE=0;
NF_DATA=Columnadd;
NF_WE=1;
//送地址第一个字节,列地址(其实就是那512个字节地地址)
NF_WE=0;
NF_DATA=Pageadd0xff; //NF_DATA=((Pageadd%256)%256)0xff;
NF_WE=1;
//送地址第二个字节,低五位是页地址,高三位是块地址的低三位(1block = 32page)
NF_WE=0;
NF_DATA=(Pageadd>>8)0xff; //NF_DATA=((Pageadd%256)/256)0xff;
NF_WE=1;
//送地址第三个字节,块地址
NF_WE=0;
NF_DATA=(Pageadd>>16)0xff; // NF_DATA=(Pageadd/256)0xff;
NF_WE=1;
//送地址第四个字节,块地址
NF_ALE=0;
P2=0xff;
}
/********************************************************/
/********************************************************/
//写入一个字节的数据 NAND Flash WirteByte
//写入命令 80h 10h
//******************************************
unsigned char NF_WirteByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char NF_dat)
{
unsigned char s=0;
NF_Initial();
NF_CE=0;
// NF_Command(0x50);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_Command(0x80);
NF_SendAddre(Pageadd,Columnadd);
NF_WE=0;
NF_DATA=NF_dat;
NF_WE=1;
NF_Command(0x10);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
}
/****************************************************/
/******************************************************/
//读取一个字节 NAND Flash ReadByte
//读取命令 00h/01h (half)
//******************************************
unsigned char NF_ReadByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char half)
{
unsigned char NF_dat,s=0;
NF_Initial();
NF_CE=0;
NF_Command(half);
NF_SendAddre(Pageadd,Columnadd);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_DATA=0xff;
NF_RE=0;
NF_dat=NF_DATA;
NF_RE=1;
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
return (NF_dat);
}
/***********************************************/
/**********************************************/
//写入多个字节的数据 NAND Flash WirteByte
//写入命令 80h 10h (PCS最大取512)
//************************************************
unsigned char NF_WirteNByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char *P_NF,unsigned char pcs)
{
unsigned char s,i;
NF_Initial();
NF_CE=0;
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_Command(0x00);
NF_Command(0x80);
NF_SendAddre(Pageadd,Columnadd);
for(i=0;i pcs;i++)
{
NF_WE=0;
NF_DATA=*P_NF;
NF_WE=1;
P_NF++;
}
NF_Command(0x10);
while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
}
/**************************************************/
/*************************************/
//读取多个字节 NAND Flash ReadByte
//读取命令 00h/01h (half)(PCS最大取512)
//******************************************
unsigned char NF_ReadNByte(unsigned char Pageadd,unsigned char Columnadd,unsigned char half,unsigned char *P_NF,unsigned char pcs)
{
unsigned char i,s=0;
NF_Initial();
NF_CE=0;
NF_Command(half);
NF_SendAddre(Pageadd,Columnadd);
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
NF_DATA=0xff;
for(i=0;i pcs;i++)
{
NF_RE=0;
*P_NF=NF_DATA;
NF_RE=1;
P_NF++;
}
NF_R_B=1;while(!NF_R_B); //检查是否忙碌
s=NF_ReadStatus(); //读取状态:(0xff)正确 0x00)错误
NF_CE=1;
// return (NF_dat);
}
/****************************************************
51单片机 K9K8G08U0C NANDFlash 相关文章:
- 关于RTX51 TINY的分析与探讨(05-30)
- 浅析8051模块化编程技巧(05-28)
- 基于DSP和单片机通信的液晶显示设计方案(07-20)
- 锁相环控制及初始化简析(08-27)
- 基于MSP430自动胀管控制器的研究(09-07)
- 嵌入式C实现延时程序的不同变量的区别(03-01)