?? nand.c
字號(hào):
#include <MSP430X14X.h>
#include <stdio.h>
#include "Nand.h"
void Init_CLK(void);
//全局變量
extern int nSM_R_B;
void SM_Port_Init(void)
{
P4DIR = 0;
P4DIR |= BIT0; //設(shè)置CLE為輸出管腳
P4DIR |= BIT1; //設(shè)置CE~為輸出管腳
P4DIR |= BIT2; //設(shè)置ALE為輸出管腳
P4DIR |= BIT3; //設(shè)置RE~為輸出管腳
P4DIR |= BIT4; //設(shè)置WE~為輸出管腳
P1DIR &= ~(BIT1); //設(shè)置R/B為輸入管腳
return;
}
void CLE_Enable(void)
{
P4OUT |= BIT0;
return;
}
void CLE_Disable(void)
{
P4OUT &= ~(BIT0);
return;
}
void CE_Enable(void)
{
P4OUT &= ~(BIT1);
return;
}
void CE_Disable(void)
{
P4OUT |= BIT1;
return;
}
void ALE_Enable(void)
{
P4OUT |= BIT2;
return;
}
void ALE_Disable(void)
{
P4OUT &= ~(BIT2);
return;
}
void WE_Enable(void)
{
P4OUT &= ~(BIT4);
return;
}
void WE_Disable(void)
{
P4OUT |= BIT4;
return;
}
void RE_Enable(void)
{
P4OUT &= ~(BIT3);
return;
}
void RE_Disable(void)
{
P4OUT |= BIT3;
return;
}
int GetSMStatus(void)
{
int nTemp = 0;
return nTemp;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int PageWrite(int nCol,unsigned long nRow,char *pBuf)
{
int nTemp = 0;
int i;
int j;
unsigned nADD1;
unsigned nADD2;
unsigned nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) &0x00ff;
nADD3 = (nRow >> 16) & 0x00ff; //處理最高地址的時(shí)候必須注意的是其余沒(méi)有用的位必須是 0
CE_Enable();
P5DIR = 0xff; //設(shè)置P5口為輸出方向
CLE_Enable();
WE_Enable();
P5OUT = 0x80; //頁(yè)寫(xiě)命令
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol); // 行的起始地址
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD1;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD2;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD3;
WE_Disable();
ALE_Disable();
//WE_Enable();
for(j = 0;j < 528;j++)
{
WE_Enable();
P5OUT = pBuf[j];
//for(i = 3;i > 0;i--);
WE_Disable();
}
//WE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0x10;
WE_Disable();
CLE_Disable();
//等待R/B中斷
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
CLE_Enable();
WE_Enable();
P5OUT = 0x70;
WE_Disable();
CLE_Disable();
P5DIR = 0x00; //設(shè)置P5口為輸入方向
for(i = 1000;i > 0;i--)
{
RE_Enable();
nTemp = P5IN;
RE_Disable();
if(nTemp == 0xc0) break;
}
if(nTemp == 0xc0) return 1;
else return 0;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int WriteByte(int nCommand,int nCol,unsigned long nRow,char nValue)
{
int nTemp = 0;
int i;
unsigned nADD1;
unsigned nADD2;
unsigned nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) &0x00ff;
nADD3 = (nRow >> 16) & 0x00ff; //處理最高地址的時(shí)候必須注意的是其余沒(méi)有用的位必須是 0
CE_Enable();
P5DIR = 0xff; //設(shè)置P5口為輸出方向
CLE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCommand); //指針
WE_Disable();
CLE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0x80; //頁(yè)寫(xiě)命令
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol); // 行的起始地址
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD1;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD2;
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = nADD3;
WE_Disable();
ALE_Disable();
WE_Enable();
P5OUT = nValue;
WE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0x10;
WE_Disable();
CLE_Disable();
//等待R/B中斷
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
CLE_Enable();
WE_Enable();
P5OUT = 0x70;
WE_Disable();
CLE_Disable();
P5DIR = 0x00; //設(shè)置P5口為輸入方向
for(i = 1000;i > 0;i--)
{
RE_Enable();
nTemp = P5IN;
RE_Disable();
if(nTemp == 0xc0) break;
}
//printf("SM Write: nTemp = %x ,",nTemp);
if(nTemp == 0xc0) return 1;
else return 0;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
char ReadByte(int nCommand,int nCol,unsigned long nRow)
{
int i;
char chrLow = 0;
unsigned char nADD1;
unsigned char nADD2;
unsigned char nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) & 0x00ff;
nADD2 = (nRow >> 16) & 0x00ff;
CE_Enable();
P5DIR = 0xff; //設(shè)置P5口為輸出方向
CLE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCommand); //輸出讀命令代碼;
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD1);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD2);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD3);
WE_Disable();
ALE_Disable();
//等待R/B中斷
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
P5DIR = 0; //設(shè)置P5口為輸入方向
RE_Enable();
chrLow = P5IN;
RE_Disable();
CE_Disable();
return chrLow;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int PageRead(int nCol,unsigned long nRow,char *pBuf)
{
int nTemp = 0;
int i;
int j;
unsigned char nADD1;
unsigned char nADD2;
unsigned char nADD3;
nADD1 = nRow & 0x00ff;
nADD2 = (nRow >> 8) & 0x00ff;
nADD2 = (nRow >> 16) & 0x00ff;
CE_Enable();
P5DIR = 0xff; //設(shè)置P5口為輸出方向
CLE_Enable();
WE_Enable();
P5OUT = 0x00; //輸出讀命令代碼 0x00;
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nCol);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD1);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD2);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD3);
WE_Disable();
ALE_Disable();
//等待R/B中斷
//while(!nSM_R_B) ;
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
P5DIR = 0; //設(shè)置P5口為輸入方向
//RE_Enable();
for(j = 0;j < 528;j++)
{
RE_Enable();
pBuf[j] = P5IN;
//for(i = 3;i > 0;i--); //是否需要延時(shí)
RE_Disable();
}
//RE_Disable();
CE_Disable();
return nTemp;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int ReadID(unsigned char pBuf[2])
{
int nTemp = 0;
int nMaker = 0;
int nDevice = 0;
// int nUniqueID = 0;
// int nPlaneCode = 0;
CE_Enable(); // 使能片選信號(hào)
ALE_Disable();
CLE_Disable();
RE_Disable();
WE_Disable();
P5DIR = 0XFF; // 設(shè)置P5口為輸出方向
CLE_Enable();
//for(i = 3;i > 0;i--);
WE_Enable();
//for(i = 5;i > 0;i--);
P5OUT = 0x90; // 輸出命令代碼 0x90
WE_Disable();
CLE_Disable();
ALE_Enable();
//for(i = 3;i > 0;i--);
WE_Enable();
//for(i = 5;i > 0;i--);
P5OUT = 0x00; // 地址周期
WE_Disable();
ALE_Disable();
P5DIR = 0x00; // 設(shè)置P5口為輸入方向
RE_Enable();
nMaker = P5IN;
RE_Disable();
RE_Enable();
nDevice = P5IN;
RE_Disable();
//RE_Enable();
//nUniqueID = P5IN;
//RE_Disable();
//RE_Enable();
//nPlaneCode = P5IN;
//RE_Disable();
CE_Disable();
if(nMaker == 0xec)
{
if(nDevice == 0x76 || nDevice == 0x79)
{
nTemp = 1;
pBuf[0] = (unsigned char)(nMaker);
pBuf[1] = (unsigned char)(nDevice);
}
}
return nTemp;
}
/////////////////////////////////////////
//成功返回 1,錯(cuò)誤返回 0
int BlockErase(unsigned long nAddr)
{
int nTemp = 0;
int i;
unsigned char nADD1;
unsigned char nADD2;
unsigned char nADD3;
nADD1 = nAddr & 0x00ff;
nADD2 = (nAddr >> 8) & 0x00ff;
nADD3 = (nAddr >> 16) & 0x00ff;
CE_Enable();
P5DIR = 0xff; //設(shè)置P5口為輸出方向
CLE_Enable();
WE_Enable();
P5OUT = 0x60; //輸出塊擦出命令
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = (unsigned char)(nADD1);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD2);
WE_Disable();
//for(i = 3;i > 0;i--);
WE_Enable();
P5OUT = (unsigned char)(nADD3);
WE_Disable();
ALE_Disable();
CLE_Enable();
WE_Enable();
P5OUT = 0xd0;
WE_Disable();
CLE_Disable();
//等待R/B中斷
//while(!nSM_R_B);
//nSM_R_B = 0;
for(i = 200;i > 0;i--);
//CLE_Enable();
//WE_Enable();
//P5OUT = 0x70;
//WE_Disable();
//CLE_Disable();
P5DIR = 0; //設(shè)置P5口為輸入方向
RE_Enable();
nTemp = P5IN;
RE_Disable();
CE_Disable();
//printf("SM: nTemp = %x ,",nTemp);
if(nTemp & 0x01) return 0;
else return 1;
}
/////////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int VerifyValid(unsigned long nAddr)
{
int j;
int buf;
//char pBuf[528];
for(j = 0;j < 32;j++)
{
buf = ReadByte(0x50,5,(nAddr + j));
//printf("SM: buf = %x ,j = %d",buf,j);
if(buf != 0x00ff) break;
}
if(buf != 0x00ff) return 0;
else return 1;
}
void ResetSM(void)
{
int i;
CE_Enable();
P5DIR = 0xff; // 設(shè)置P5口為輸出方向
CLE_Enable();
WE_Enable();
P5OUT = 0xff; // 輸出RESET控制命令
WE_Disable();
CLE_Disable();
//while(!nSM_R_B);
//nSM_R_B = 0;
for(i = 100;i > 0;i--);
CE_Disable();
return;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int BlockRead(unsigned long nAddr,char pBuf[32][528])
{
int i,j;
int n;
unsigned char nADD1;
unsigned char nADD2;
unsigned char nADD3;
nADD1 = nAddr & 0x00ff;
nADD2 = (nAddr >> 8) & 0x00ff;
nADD3 = (nAddr >> 16) & 0x00ff;
CE_Enable();
P5DIR = 0xff; // 將P5口設(shè)置為輸出方向
for(i = nADD1;i < nADD1 + 32;i++)
{
ResetSM();
CLE_Enable();
WE_Enable();
P5OUT = 0x00;
WE_Disable();
CLE_Disable();
ALE_Enable();
WE_Enable();
P5OUT = 0x00;
WE_Disable();
WE_Enable();
P5OUT = (unsigned char)(i);
WE_Disable();
WE_Enable();
P5OUT = (unsigned char)(nADD2);
WE_Disable();
WE_Enable();
P5OUT = (unsigned char)(nADD3);
WE_Disable();
ALE_Disable();
//while(!nSM_R_B);
//nSM_R_B = 0;
for(n = 100;n > 0;n--);
P5DIR = 0x00; // 將P5口設(shè)置為輸入方向
for(j = 0;j < 528;j++)
{
RE_Enable();
pBuf[i][j] = P5IN;
RE_Disable();
}
}
CE_Disable();
return 1;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int CopyToFlash(unsigned long nAddr)
{
return 1;
}
////////////////////////////////////////
// 正確返回 1,錯(cuò)誤返回 0
int RealTimeBadMark(unsigned long nAddr)
{
int i;
int rg_stat;
for(i = 0;i < 32;i++)
{
rg_stat = WriteByte(0x50,5,nAddr + i,0x00f0);
//printf("rg_stat = %x i = %d",rg_stat,i);
if((rg_stat & 0x01) != 0) return 0;
}
ResetSM();
return 1;
}
int main(void)
{
unsigned long nAddr;
int j;
int n;
int nTemp;
char pBuf0[528];
char pBuf1[528];
int nCount_Err;
int nLen;
// 關(guān)閉看門(mén)狗
WDTCTL = WDTPW + WDTHOLD;
// 關(guān)閉中斷
_DINT();
// 初始化
Init_CLK();
SM_Port_Init();
// 打開(kāi)中斷
_EINT();
// 擦除塊地址為1024的塊
nAddr = 1024;
BlockErase(nAddr);
// 延遲一點(diǎn)時(shí)間
for(j = 1000;j > 0;j--) ;
// 判斷擦除的塊是否為0xFF,起始頁(yè)地址為1024
for(j = 0;j < 528;j++) pBuf0[j] = j;
// 按頁(yè)寫(xiě)入數(shù)據(jù),地址為:1024
PageWrite(0,1024,pBuf0);
// 延遲一點(diǎn)時(shí)間
for(j = 1000;j > 0;j--) ;
//按頁(yè)讀操作
PageRead(0,1024,pBuf1);
//比較讀出數(shù)據(jù)和寫(xiě)入數(shù)據(jù)是否相等
nCount_Err = 0;
for(j = 0;j < 528;j++)
{
if(pBuf0[j] != pBuf1[j])
{
nCount_Err += 1;
break;
}
}
return 0;
}
void Init_CLK(void)
{
unsigned int i;
BCSCTL1 = 0X00; //將寄存器的內(nèi)容清零
//XT2震蕩器開(kāi)啟
//LFTX1工作在低頻模式
//ACLK的分頻因子為1
do
{
IFG1 &= ~OFIFG; // 清除OSCFault標(biāo)志
for (i = 0x20; i > 0; i--);
}
while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1
BCSCTL2 = 0X00; //將寄存器的內(nèi)容清零
BCSCTL2 += SELM1; //MCLK的時(shí)鐘源為T(mén)X2CLK,分頻因子為1
BCSCTL2 += SELS; //SMCLK的時(shí)鐘源為T(mén)X2CLK,分頻因子為1
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -