#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)//延時參數(shù)(z)無反回值的子程序(void表示無反值) { unsigned int x,y; for(x=z;x>0;x--) for(y=100;y>0;y--); } /******************************************************************** //模 塊 名:51單片機控制K9K8G08U0C的讀寫程序 //功能描述:NANDFLASH讀寫程序 //兼容性 :適合大部分的NANDFLASH,如需要根據(jù)手冊做簡單修改即可 //芯片型號: STC89C516RD STC12C5A60S2等。 ********************************************************************/ // NANDFLASH使能信號初始化 //////////////////////////////////////////////////////////////// void NF_Initial() { NF_CLE=0;NF_ALE=0;NF_CE=1; NF_WE=1;NF_RE=1;NF_WP=1; } /***********************************************************************/ /***********************************************************************/ //命令函數(shù) NAND Flash Command //Read1 00h/01h //Read2 50h //讀取芯片ID 90h //RESET FFh //寫頁 80h 10h //塊擦除 60h D0h //讀取狀態(tài) 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函數(shù) 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; } /***********************************************************************/ /***********************************************************************/ //命令函數(shù) NAND Flash status //讀取狀態(tài) 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; //用來取狀態(tài),其實可以不要 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(); //讀取狀態(tài):(0xff)正確 0x00)錯誤 NF_CE=1; return (s); } /***********************************************************************/ /***********************************************************************/ //發(fā)送地址 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; //送地址第一個字節(jié),列地址(其實就是那512個字節(jié)地地址) NF_WE=0; NF_DATA=Pageadd&0xff; //NF_DATA=((Pageadd%256)%256)&0xff; NF_WE=1; //送地址第二個字節(jié),低五位是頁地址,高三位是塊地址的低三位(1block = 32page) NF_WE=0; NF_DATA=(Pageadd>>8)&0xff; //NF_DATA=((Pageadd%256)/256)&0xff; NF_WE=1; //送地址第三個字節(jié),塊地址 NF_WE=0; NF_DATA=(Pageadd>>16)&0xff; // NF_DATA=(Pageadd/256)&0xff; NF_WE=1; //送地址第四個字節(jié),塊地址 NF_ALE=0; P2=0xff; } /***********************************************************************/ /***********************************************************************/ //寫入一個字節(jié)的數(shù)據(jù) 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(); //讀取狀態(tài):(0xff)正確 0x00)錯誤 NF_CE=1; } /***********************************************************************/ /***********************************************************************/ //讀取一個字節(jié) 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(); //讀取狀態(tài):(0xff)正確 0x00)錯誤 NF_CE=1; return (NF_dat); } /***********************************************************************/ /***********************************************************************/ //寫入多個字節(jié)的數(shù)據(jù) 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(); //讀取狀態(tài):(0xff)正確 0x00)錯誤 NF_CE=1; } /***********************************************************************/ /***********************************************************************/ //讀取多個字節(jié) 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(); //讀取狀態(tài):(0xff)正確 0x00)錯誤 NF_CE=1; // return (NF_dat); } /*********************************************************************************************/