nand.c
资源名称:msp430.rar [点击查看]
上传用户:xs588588
上传日期:2021-03-30
资源大小:242k
文件大小:14k
源码类别:
DSP编程
开发平台:
C/C++
- #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; //设置CLE为输出管脚
- P4DIR |= BIT1; //设置CE~为输出管脚
- P4DIR |= BIT2; //设置ALE为输出管脚
- P4DIR |= BIT3; //设置RE~为输出管脚
- P4DIR |= BIT4; //设置WE~为输出管脚
- P1DIR &= ~(BIT1); //设置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,错误返回 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; //处理最高地址的时候必须注意的是其余没有用的位必须是 0
- CE_Enable();
- P5DIR = 0xff; //设置P5口为输出方向
- CLE_Enable();
- WE_Enable();
- P5OUT = 0x80; //页写命令
- 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; //设置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,错误返回 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; //处理最高地址的时候必须注意的是其余没有用的位必须是 0
- CE_Enable();
- P5DIR = 0xff; //设置P5口为输出方向
- CLE_Enable();
- WE_Enable();
- P5OUT = (unsigned char)(nCommand); //指针
- WE_Disable();
- CLE_Disable();
- CLE_Enable();
- WE_Enable();
- P5OUT = 0x80; //页写命令
- 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; //设置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,错误返回 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; //设置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; //设置P5口为输入方向
- RE_Enable();
- chrLow = P5IN;
- RE_Disable();
- CE_Disable();
- return chrLow;
- }
- ////////////////////////////////////////
- // 正确返回 1,错误返回 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; //设置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; //设置P5口为输入方向
- //RE_Enable();
- for(j = 0;j < 528;j++)
- {
- RE_Enable();
- pBuf[j] = P5IN;
- //for(i = 3;i > 0;i--); //是否需要延时
- RE_Disable();
- }
- //RE_Disable();
- CE_Disable();
- return nTemp;
- }
- ////////////////////////////////////////
- // 正确返回 1,错误返回 0
- int ReadID(unsigned char pBuf[2])
- {
- int nTemp = 0;
- int nMaker = 0;
- int nDevice = 0;
- // int nUniqueID = 0;
- // int nPlaneCode = 0;
- CE_Enable(); // 使能片选信号
- ALE_Disable();
- CLE_Disable();
- RE_Disable();
- WE_Disable();
- P5DIR = 0XFF; // 设置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; // 设置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,错误返回 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; //设置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; //设置P5口为输入方向
- RE_Enable();
- nTemp = P5IN;
- RE_Disable();
- CE_Disable();
- //printf("SM: nTemp = %x ,",nTemp);
- if(nTemp & 0x01) return 0;
- else return 1;
- }
- /////////////////////////////////////////////
- // 正确返回 1,错误返回 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; // 设置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,错误返回 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口设置为输出方向
- 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口设置为输入方向
- for(j = 0;j < 528;j++)
- {
- RE_Enable();
- pBuf[i][j] = P5IN;
- RE_Disable();
- }
- }
- CE_Disable();
- return 1;
- }
- ////////////////////////////////////////
- // 正确返回 1,错误返回 0
- int CopyToFlash(unsigned long nAddr)
- {
- return 1;
- }
- ////////////////////////////////////////
- // 正确返回 1,错误返回 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;
- // 关闭看门狗
- WDTCTL = WDTPW + WDTHOLD;
- // 关闭中断
- _DINT();
- // 初始化
- Init_CLK();
- SM_Port_Init();
- // 打开中断
- _EINT();
- // 擦除块地址为1024的块
- nAddr = 1024;
- BlockErase(nAddr);
- // 延迟一点时间
- for(j = 1000;j > 0;j--) ;
- // 判断擦除的块是否为0xFF,起始页地址为1024
- for(j = 0;j < 528;j++) pBuf0[j] = j;
- // 按页写入数据,地址为:1024
- PageWrite(0,1024,pBuf0);
- // 延迟一点时间
- for(j = 1000;j > 0;j--) ;
- //按页读操作
- PageRead(0,1024,pBuf1);
- //比较读出数据和写入数据是否相等
- 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; //将寄存器的内容清零
- //XT2震荡器开启
- //LFTX1工作在低频模式
- //ACLK的分频因子为1
- do
- {
- IFG1 &= ~OFIFG; // 清除OSCFault标志
- for (i = 0x20; i > 0; i--);
- }
- while ((IFG1 & OFIFG) == OFIFG); // 如果OSCFault =1
- BCSCTL2 = 0X00; //将寄存器的内容清零
- BCSCTL2 += SELM1; //MCLK的时钟源为TX2CLK,分频因子为1
- BCSCTL2 += SELS; //SMCLK的时钟源为TX2CLK,分频因子为1
- }