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

网上看到这个源代码,虽然感觉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);
}
/****************************************************

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: FPGA(现场可编程门阵列)是一种基于可编程逻辑块(PLBs)的半定制集成电路,可以编程实现各种电路逻辑和功能。NAND Flash是一种非易失性存储芯片,广泛应用于移动设备、数字相机、USB存储器等电子产品中。FPGA和NAND Flash都是重要的电子元器件,可以实现高效的数据读写操作。 在FPGA中使用NAND Flash进行读写操作时,需要首先进行芯片编程和初始化设置。在编程时需要选取正确的接口和协议,并针对具体的NAND Flash芯片进行相应的设置和配置。在初始化时需要设置好相关的时序和地址映射关系,以便实现正确的数据传输和读取。 在实际的数据读写操作中,FPGA可以通过使用DMA(Direct Memory Access)模块实现高效的数据传输。DMA模块可以直接从NAND Flash读取或写入数据,并将结果传输到FPGA内部的存储器或外部设备中。为了实现更高的读写速度,还可以使用缓存和预取技术,提高数据传输的效率和带宽利用率。 总的来说,FPGA和NAND Flash都是重要的电子元器件,可以实现高效的数据读写操作。在进行NAND Flash读写时,需要进行正确的编程和初始化设置,并使用DMA模块和缓存技术实现高效的数据传输,以便实现更快的读写速度和更高的带宽利用率。 ### 回答2: FPGA可以通过内置的硬件控制器来读写NAND Flash,实现高效的数据存取。在进行FPGA与NAND Flash连接时,需要使用FPGA的IO口对NAND Flash进行时序控制,以确保数据能够正确地读写。具体来说,FPGA可以使用SPI、SDIO、MMC等接口协议,通过控制NAND Flash的命令、地址、数据线来进行读写操作。在读取数据时,FPGA需要先发送读命令、片选信号和地址信息,然后从数据线上读取数据。当FPGA需要向NAND Flash写入数据时,同样需要先发送写命令、片选信号、地址和数据信息,以确保数据能够被正确存储。 在使用FPGA读写NAND Flash时,需要注意以下几点: 1. FPGA应该与NAND Flash之间连接正确,且连接线路应该按照NAND Flash数据手册的要求进行设置。 2. FPGA应该正确配置时序控制信号,以确保数据能够准确读写。 3. 在进行写操作时,需要确保数据已经被正确地缓存,否则可能会导致数据丢失或者损坏。 4. 在进行读写时,需要确保FPGA与NAND Flash的电源相一致,以避免不必要的电压峰值导致损坏。 总的来说,FPGA与NAND Flash读写操作需要进行正确的时序控制,并且需要遵循NAND Flash数据手册的指导,以确保数据能够准确地存取。通过FPGA与NAND Flash读写操作,可以实现高速、可靠的数据存取,适用于各种工业控制、计算机、通讯等领域的应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值