51单片机控制K9K8G08U0C NAND Flash读写程序

来源:互联网 发布:数据库日志文件清理 编辑:程序博客网 时间:2024/05/21 09:18

网上看到这个源代码,虽然感觉51用到nandflash的情况不多,但是可以借鉴理解nandflash的读写流程

#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=0xff&NF_DATA;    //ECH
   NF_RE=1;

   NF_DATA=0xff;
   NF_RE=0;
   b=0xff&NF_DATA;    //76H
 
   NF_RE=1;

   NF_DATA=0xff;

   NF_RE=0;
   c=0xff&NF_DATA;    //3fH
  
   NF_RE=1;

   NF_DATA=0xff;

   NF_RE=0;   
   c=0xff&NF_DATA;    //00H
   NF_RE=1;

   NF_CE=1;

   /*NF_RE=0;
   a=0x00ff&P2;
   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_DATA&0x01;
   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=Pageadd&0xff;  //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=Pageadd&0xff;  //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);
}
/****************************************************

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一级消防工程师论坛 注册消防工程师考试难度 一级消防工程师考试题型 注册二级消防工程师 注册消防工程师论坛 一级注册消防工程师教材 注册消防工程师报名 二级消防工程师考试科目 消防工程师报考条件二级 二级注册消防工程师报考条件 一级注册消防工程师论坛 二级消防工程师好考吗 一级注册消防工程师招聘 注册消防工程师难考吗 考一级消防工程师有用吗 消防工程师难度 一消防工程师 一级消防工程师考试难度 一级消防工程师好考吗 消防工程师待遇 注册消防工程师一级二级区别 一级注册消防工程师好考吗 注册消防工程师好不好考 一级消防工程师难度 二级注册消防工程师考试科目 二级消防考试时间 一级消防工程师招聘 陕西二级消防工程师报名时间 2017消防工程师考试时间 消防工程师代报名 消防技术综合能力 一级注册消防工程师报考条件 河北二级消防工程师报名时间 二级消防工程师报名条件 消防员考试报考条件 消防技术实务 一级注册消防工程师报名时间 消防安全工程师考试时间 消防注册工程师报考条件 2017一级消防工程师报名时间 二级消防考试科目