📄 sm.c
字号:
#include <MSP430X14X.h>
#include <stdio.h>
#include "SM.h"
//全局变量
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -