⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45d041大容量ic卡 读写程序.c

📁 4442卡的底层操作程序 AT45D041大容量IC卡 读写程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------
*/
/*------------------------------------------------------------------------------
*/
/*                              文件名:   IC.c 
/*    
/* AT45D041大容量IC卡 读写程序
/* 存储器容量为4325376位,分为2048页,每页有264字节,与缓存器的容量相等。
/* 0~1页保存系统信息(目录表大小,文件分配表大小,数据区大小,页的大小等)
/* 2~17页文件目录表 (每条文件目录为32字节,根最大目录数为128)
/* 18~33页文件分配表 (FAT16格式,分配表长度可根据卡的容量改变,AT45D041需16页)
/* 34~47页系统保留
/* >=48页为数据区       
/*------------------------------------------------------------------------------
*/

#include <Reg51.h>
#include <String.h>

#define uchar unsigned char
#define WORD  unsigned int
#define DWORD unsigned long

//系统信息结构
typedef struct
{
uchar VersionName[8];     //版本名称
uchar Version[3];         //版本号
uchar ICName[10];         //IC卡名称
DWORD ICPages;            //IC卡共有多少页
WORD  PageBytes;          //每页包含的字节数
WORD  DirStart;           //根文件目录表开始页
WORD  DirLength;          //根文件目录表页面数
WORD  FatStart;           //文件分配表开始页
WORD  FatLength;          //文件分配表页面数
WORD  DataStart;          //数据区起始页
WORD  DataLength;         //数据区页面数
} _ICSysInfo;

//文件目录表结构,每条目录项32字节
typedef struct
    {
uchar FileName[8];       /* 文件名称 */
uchar FileExt[3];        /* 文件扩展名 */
uchar FileAttr;          /* 文件属性 */
uchar a[10];             /* 系统保留 */
WORD  UpdateTime;        /* 时间=小时*2048+分钟*32+秒+2 */
WORD  UpdateDate;  /* (年份-1980)*512+月份*32+日 */
WORD  FirstPage;      /* 文件首页号 */
DWORD FileSize;          /* 文件字节数 */
} ICDirInfo;

//AT45D041卡的操作命令定义
typedef enum 
{  
PageRead = 0x52,       //直接读页,缓存不变
Buf1Read = 0x54,       //缓存1读
Buf2Read = 0x56, //缓存2读
PageToBuf1 = 0x53,     //页读至缓存1
PageToBuf2 = 0x55,     //页读至缓存2
PageCmpBuf1 = 0x60,    //页与缓存1比较,比较结果在状态寄存器第6位
PageCmpBuf2 = 0x61,    //页与缓存2比较,比较结果在状态寄存器第6位
Buf1Write = 0x84,      //缓存1写
Buf2Write = 0x87,      //缓存2写
Buf1ToPageWithErase = 0x83,      //将缓存1写入页,包含页擦除动作
Buf2ToPageWithErase = 0x86,      //将缓存2写入页,包含页擦除动作
    Buf1ToPageWithoutErase = 0x88,   //将缓存1写入页,不包含页擦除动作
Buf2ToPageWithoutErase = 0x89,   //将缓存2写入页,不包含页擦除动作
PageWriteThroughBuf1 = 0x82,     //数据先写入缓存1,再写入页,包含页擦
PageWriteThroughBuf2 = 0x85,     //数据先写入缓存2,再写入页,包含页擦
PageRewriteThroughBuf1 = 0x58,   //页读入缓存1,然后缓存1写入页
PageRewriteThroughBuf2 = 0x59,   //页读入缓存2,然后缓存2写入页
StatusRead = 0x57                //读状态寄存器
} OpCode;

//文件分配表中页标记含义
const WORD code csFree = 0x0000;          //未用的页
const WORD code csReserved = 0xfff0;      //系统保留的页
const WORD code csError = 0xfff7;         //坏页标记
const WORD code csFileEnd = 0xfff8;       //文件中最后的页
const WORD code csNextMin = 0x0003;       //下一页标记最小值
const WORD code csNextMax = 0xffef;       //下一页标记最大值
const WORD code csEnd = 0xffff;           //文件分配表结束
const WORD code SysInfoPage = 0;          //保存系统信息的页
const WORD code DirStartPage = 2;         //文件目录区首页
_ICSysInfo  ICSysInfo;

/*------------------------------------------------------------------------------
*/
/*                           供外部模块调用函数                 
/*------------------------------------------------------------------------------
*/
uchar FileCreate(uchar *FileName);
uchar FileOpen(uchar *FileName);
void  FileClose(uchar *Handle);
int   FileRead(uchar Handle, uchar *Buffer, int Start, int Count);
int   FileWrite(uchar Handle, char *Buffer, int Start, int Count);
uchar FileExists(uchar* FileName);
bit   FileDelete(uchar* FileName);
bit   ICFormat();            /*格式化IC卡,并清除全部数据*/
bit   ICDeleteAll();         /*全部清除IC卡数据*/
DWORD ICFreeSize();          /*获取可用空间,字节数*/
DWORD ICUsedSize();          /*获取已使用空间,字节数*/
DWORD ICTotalSize();         /*获取总空间,字节数*/

/*------------------------------------------------------------------------------
*/
/*                        以下为内部函数,仅供模块内部调用                  
/*------------------------------------------------------------------------------
*/
void  ICReadDirInfo(uchar IndexOfDir, ICDirInfo *DirInfo);  /*读取目录信息*/
bit   ICWriteDirInfo(uchar IndexOfDir, ICDirInfo *DirInfo); /*写入目录信息*/
void  ICReadSysInfo(_ICSysInfo *ICInfo, WORD SysPage);      /*读取IC卡系统信息*/
bit   ICWriteSysInfo(_ICSysInfo *ICInfo, WORD SysPage);     /*写入IC卡系统信息*/
WORD  ICReadPageSign(WORD Page);           
/*读页标记*/
bit   ICWritePageSign(WORD Page,WORD Sign);          /*写页标记*/
WORD  ICFirstFreePage();                  
/*从头寻找第一个空闲的页*/
WORD  ICNextFreePage(WORD StartPage);  
/*寻找下一个空闲的页*/
uchar ICReadPageByte(WORD Page, WORD ByteAddr); 
/*直接读页内容*/
uchar ICReadBuf1Byte(WORD ByteAddr); 
/*读缓存1字节*/
uchar ICReadBuf2Byte(WORD ByteAddr); 
/*读缓存2字节*/
void  ICWriteBuf1Byte(WORD ByteAddr, uchar b); 
/*写缓存1字节*/
void  ICWriteBuf2Byte(WORD ByteAddr, uchar b); 
/*写缓存2字节*/
bit   ICBuf1CmpPage(WORD Page); /*比
较缓存1和页内容*/
bit   ICBuf2CmpPage(WORD Page); /*比
较缓存2和页内容*/
void  ICBuf1ToPage(WORD Page); /*缓
存1写入页*/
void  ICBuf2ToPage(WORD Page); /*缓
存2写入页*/
void  ICPageToBuf1(WORD Page); /*页
内容至缓存1*/
void  ICPageToBuf2(WORD Page); /*页
内容至缓存2*/
// 根据根目录项索引获得页面号及页内字节地址
void  ICDirIndexToPageByteAddr(uchar DirIndex, WORD *Page,WORD *ByteAddr);
bit   ICWriteToPage(uchar *p, uchar Count, WORD Page, WORD ByteAddr);/* 将字符串
写入页*/
void  ICWaitReady();                            /*等
待IC卡准备好*/
uchar ICCommand(OpCode cmd, WORD Page,WORD ByteAddr);   /* 所有命令的执行 */
uchar ICStatus();                               /*读
IC卡状态*/

/*------------------------------------------------------------------------------
*/
/*                           底层硬件操作函数                    
/*------------------------------------------------------------------------------
*/
sbit  sCLK = P0^0;
sbit  sDO = P0^1;
sbit  sDI = P0^2;
sbit  sCS = P0^3;
sbit  a0 = ACC^0;
sbit  a1 = ACC^1;
sbit  a2 = ACC^2;
sbit  a3 = ACC^3;
sbit  a4 = ACC^4;
sbit  a5 = ACC^5;
sbit  a6 = ACC^6;
sbit  a7 = ACC^7;
void  ICWriteNextByte(uchar b);                /*连续写下一个字节*/
uchar ICReadNextByte();                        /*连续读下一个字节*/
void  ICOutOpCode(OpCode cmd);                 /*发送命令字*/
void  ICOutPage(WORD Page);                    /*发送页面地址*/
void  ICOutByteAddr(WORD ByteAddr);            /*发送字节地址*/
void  ICOutXBits(uchar N);                     /*发送N个任意字符*/


/*------------------------------------------------------------------------------
*/
/*                           以下为函数实现部分                    
/*------------------------------------------------------------------------------
*/
//----------------------------------------------------------------------------
uchar FileExists(uchar *FileName)
{
uchar i = 1;
char c;
ICDirInfo tempDir;
uchar *p = (uchar*)(&tempDir);
do
{
ICReadDirInfo(i,&tempDir);
c = strncmp(p,FileName,sizeof(tempDir.FileName));//+sizeof
(ICDirInfo->FileExt));
if (c==0)
return (i);
else
i++;
}while(i<128);
return (0);
}

//----------------------------------------------------------------------------
uchar FileCreate(uchar *FileName)
{
uchar i ;
ICDirInfo tempDir;
uchar *p = (uchar*)(&tempDir);
i = FileExists(FileName);
if (i!=0)
{
FileDelete(FileName);
}
do
{
ICReadDirInfo(i,&tempDir);
if (*p == 0x00)
{
//找到空闲的页
//设置文件名称,然后写入
ICWriteDirInfo(i,&tempDir);
return (i);
}
} while(i<128);
return (0);
}

//----------------------------------------------------------------------------
uchar FileOpen(uchar *FileName)
{
    return (FileExists(FileName));
}

//----------------------------------------------------------------------------
void  FileClose(uchar *Handle)
{
*Handle = 0x00;
}

//----------------------------------------------------------------------------
int   FileRead(uchar Handle, uchar *Buffer, int Start, int Count)
{
int iResult = 0;
WORD iTemp,curPage,oldPage=0,numPage=0;
DWORD filelen;
ICDirInfo tempDir;

//判断文件句柄是否有效
if (Handle == 0x00)
 return (-1);

//读取文件目录信息
ICReadDirInfo(Handle,&tempDir);
filelen = tempDir.FileSize;
curPage = tempDir.FirstPage;
//读取文件字节数据
while(Count>0 && Start<filelen)
{
do 
{
iTemp = (numPage+1)*ICSysInfo.PageBytes;
if (Start > iTemp)
{
curPage = ICReadPageSign(curPage);
numPage++;
}
else
break;
} while(1);

if (oldPage != curPage)  //判断是否在同一页
{
*Buffer++ = ICReadPageByte(curPage,(Start%
ICSysInfo.PageBytes));
oldPage = curPage;
}
else
{
*Buffer++ = ICReadNextByte();
}
Start++;
Count--;
iResult++;  //读取字节数加一
}
return (iResult);
}

//----------------------------------------------------------------------------
int   FileWrite(uchar Handle, char *Buffer, int Start, int Count)
{
int iResult = 0;
WORD iTemp,curPage,oldPage=0,numPage=0;
DWORD filelen;
ICDirInfo tempDir;

//判断文件句柄是否有效
if (Handle == 0x00)
 return (-1);

//读取文件目录信息
ICReadDirInfo(Handle,&tempDir);
filelen = tempDir.FileSize;
curPage = tempDir.FirstPage;
//如果文件长度增加,分配空间,改变文件长度


//读取文件字节数据
while(Count>0)
{
do 
{
iTemp = (numPage+1)*ICSysInfo.PageBytes;
if (Start > iTemp)
{
curPage = ICReadPageSign(curPage);
numPage++;
}
else
{
break;
}
} while(1);

if (oldPage != curPage)  //判断是否在同一页
{
//更新缓存1数据至页
if (oldPage!=0)
{
ICBuf1ToPage(oldPage);
}
//读取新页内容至缓存1
ICPageToBuf1(curPage);
ICWriteBuf1Byte(Start%
ICSysInfo.PageBytes,*Buffer++);
oldPage = curPage;
}
else
{
ICWriteNextByte(*Buffer++);
}
Start++;
Count--;
iResult++;  //读取字节数加一
}
return (iResult);
}

//----------------------------------------------------------------------------
bit   FileDelete(uchar* FileName)
{
uchar i;
ICDirInfo tempDir;
uchar *p = (uchar *)(&tempDir);
WORD w,w1;
i = FileExists(FileName);
if (i!=0)
{
//根据文件分配表,将文件使用的页标记为空闲
ICReadDirInfo(i,&tempDir);
w = tempDir.FirstPage;
w1 = ICReadPageSign(w);
while (w1 != csFileEnd)
{
ICWritePageSign(w,csFree);
w = w1;
w1 = ICReadPageSign(w);
}
ICWritePageSign(w,csFree);
ICWritePageSign(w1,csFree);
//目录区标记文件删除,首字节置零
*p = 0x00;
ICWriteDirInfo(i,&tempDir);
}
return (1);
}

//----------------------------------------------------------------------------
bit ICFormat()            /*格式化IC卡,并清除全部数据*/
{
bit b;
ICWriteSysInfo(&ICSysInfo,SysInfoPage);     /*写入系统信息*/
ICDeleteAll();                           /*删除全部数据*/
return (b);
}

//------------------------------------------------------------------------------
bit ICDeleteAll()         /*全部清除IC卡数据*/
{
bit b = 1;
WORD i,j;

/*初始化写入文件目录表*/
for(i=ICSysInfo.DirStart;i<=ICSysInfo.DirLength;i++)
{
ICWriteBuf1Byte(i,0);
for(j=1;j<ICSysInfo.PageBytes;j++)
ICWriteNextByte(0);
ICBuf1ToPage(i);
ICWaitReady();
if (! ICBuf1CmpPage(i))
{
b = 0;
break;
}
}
if (!b) return (b);
/*初始化写入文件分配表*/
for(i=ICSysInfo.FatStart;i<=ICSysInfo.FatLength;i++)
{
ICWriteBuf1Byte(i,0);
for(j=1;j<ICSysInfo.PageBytes;j++)
ICWriteNextByte(0);
ICBuf1ToPage(i);
ICWaitReady();
if (! ICBuf1CmpPage(i))
{
b = 0;
break;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -