📄 iccard.c
字号:
//*对IC卡的读写操作在IC卡的读写器上完成,此时用户需要读写器进行交互式处理。首先*/
//*系统核对IC卡的厂商代码和卡型,如果正确,则在空白卡上写入发行商的代码,并确定*/
//*次卡有效。然后应用系统应该提供交互界面,让用户从键盘输入自己的用户密码。在密*/
//*码写入后,系统在提供用户对密码核实和再修改的机会。确认无误后,软件发出熔断命*/
//*令,熔断熔丝,完成IC卡的个人进程。随后,系统再对IC卡的数据区写入初始化数据。*/
/* 有AT90LS8535单片机构成的IC卡读写器如图所示
//***********************************************************************/
/*
AT90LS8535 IC卡接口
PA0 ------------> sCLK
PA1 <------------ sDO
PA2 ------------> sDI
PA3 ------------> sCS
//*图中单片机通过PA1将数据按按位送出至sDO口,通过PA2口将数据按位从sDI输入,*/
//*其中的sCLK和sCS分别接PA0和PA3 。 */
/*ICcard.c
日期:2004-09-16
单元作者:张志华
权限:四川华讯
功能:IC卡模块接口的实现
avr-gcc -mmcu=at90s8535 -mint8 -Os -fno-reorder-blocks -o ICcard.elf ICcard.c
avr-objcopy -O ihex ICcard.elf ICcard.hex
*/
#include <avr/io.h>#include <avr/io8535.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define BIT BV
/*********************************************************************************/
//定义的子函数
uchar FileExists(uchar *FileName);
uchar FileCreate(uchar *FileName);//创建文件
uchar FileOpen(uchar *FileName);//打开文件
void FileClose(uchar *Handle);//关闭文件
int FileRead(uchar Handle,uchar *Buffer,int Start,int Count);
int FlieWrite(uchar Handle ,char *Buffer, int Start ,int Count);//写文件
uchar FileDelete(uchar *FileName);//删除文件
uchar ICFormat();//格式化IC卡
uchar ICDeleteAll();//清除IC卡数据
ulong ICFreeSize();//获取可用空间字节数
ulong ICUsedSize();//获取已用空间字节数
ulong ICTotalSize();//获取总空间字节数
void ICReadDirInfo(uchar IndexOfDir,ICDirInfo *DirInfo);//读取目录信息
uchar ICWriteDirInfo(uchar IndexOfDir,ICDirInfo *DirInfo);//写入目录信息
void ICReadSysInfo(_ICSysInfo *ICInfo,uint SysPage);//读取IC卡系统信息
uchar ICWriteSysInfo(_ICSysinfo *ICInfo,uint SysPage);//写入IC卡系统信息
uint ICReadPageSign(uint Page);//读页标记
uchar ICWritePageSign(uint Page,uint Sign);//写页标记
uint ICFirstFreePage();//寻找第一个空闲的页
uint ICNextFreePage(uint StartPage);//寻找下一个空闲的页
void ICDirIndexToPageByteAddr(uchar DirIndex,uint *Page ,uint *ByteAddr);
uchar ICWriteToPage(uchar *p ,uchar Count ,uint Page ,uint ByteAddr);
uchar ICReadPageByte(uint Page ,uint ByteAddr);
void ICWriteBuf1Byte(uint ByteAddr,uchar b);
void ICWriteBuf2Byte(uint ByteAddr,uchar b);
uchar ICReadBuf1Byte(uint ByteAddr);//读缓存1数据
uchar ICReadBuf2Byte(uint ByteAddr);//读缓存2数据
uchar ICBuf1CmpPage(uint Page);//页与缓存1比较
uchar ICBuf2CmpPage(uint Page);//页与缓存2比较
void ICBuf1ToPage(uint Page);//缓存1写入页
void ICBuf2ToPage(uint Page);//缓存2写入页
void ICPageToBuf1(uint Page);//页写入缓存1
void ICPageToBuf2(uint Page);//页写入缓存2
void ICWaitReady();//等待IC卡准备好
uchar ICStatus();//读IC卡状态
unsigned char ICCommand(OpCode cmd,uint Page,uint ByteAddr);//IC卡命令选择执行
void ICWriteNextByte(uchar b);//连续写下一个字节
uchar ICReadNextByte();//连续读下一个字节
void ICOutOpCode(OpCode cmd);//发送命令字
void ICOutPage(uint Page);//发送页面地址
void ICOutByteAddr(uint ByteAddr);//发送字节地址
void ICOutXBits(uchar x);//发送X个任意字符
/*********************************************************************************/
//文件目录
typedef struct
{
uchar FileName[8]; //文件名称
uchar FileExt[3]; //文件扩展名
uchar FileAttr; //文件属性
uchar a[10];
uchar UpdateTime; //文件更新时间
uchar FirstPage; //文件首页号
uchar FileSize; //文件字节数
}ICDirInfo;
//信息结构
typedef struct
{
uchar VersionName[8]; //版本名称
uchar Version[3]; //版本号
uchar ICName[8];
uchar ICPages;
uchar PageBytes;
uchar DirStart; //根文件目录开始页
uchar DirLength; //根文件目录表页长度
uchar FatStart;
uchar FatLength;
uchar DataStart;
uchar DataLength;
}ICSysInfo;
//文件分配表中页标记含义
const uint code csFree=0x0000; //未用的页
const uint code csReserved=0xfff0; //系统保留的页
const uint code csError=0xfff7; //坏页的标记
const uint code csFileEnd=0xfff8; //文件中最后的页
const uint code csNextMin=0x0003; //下一标记中最小值
const uint code csNextMax=0xffef; //下一标记中最大值
const uint code csEnd=0xffff; //文件分配表结束
const uint code SysInfoPage=0; //保存系统信息的页
const uint code DirStartPage=2; //文件目录区首页
//ICSysInfo _ICSysinfo;
//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写入页
PageWriteThrougthBuf1=0x82, //数据先写入缓存1,再写入页
PageWriteThrougthBuf2=0x85, //数据先写入缓存2,再写入页
PageRewriteThrougthBuf1=0x58, //页读入缓存1,然后缓存1写入页
PageRewriteThrougthBuf2=0x59, //页读入缓存2,然后缓存2写入页
StatusRead=0x57, //读状态寄存器
}OpCode;
uchar FileExists(uchar *FileName)
{
uchar i=1;
uchar c;
ICDirInfo tempDir;
uchar *p=(uchar*)(&tempDir);
do
{
ICReadDirinfo(i,&tempDir);
c=strncmp(p,FileName,sizeof(tempDir,FileName));
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;
uint iTemp,curPage,oldPage=0,numPage=0;
ulong 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++;
}
}
while(1);
if (oldPage!=curPage) //判断是否在同一页
{
*Buffer++=ICReadPageByte(curPage,(Start&ICSysinfo.PageBytes));
oldPage=curPage;
}
else
{
*Buffer++=ICReadNextByte();
}
Start++;
Count--;
iResult++;// 读取字节数加1
}
return(iResult);
}
//写文件
int FlieWrite(uchar Handle ,char *Buffer, int Start ,int Count)
{
int iResult=0;
uint iTemp,currPage,oldPage=0,numPage=0;
ulong FileLen;
ICDirInfo tempDir;
if (Handle==0x00) //判断文件句柄是否有效
return(-1);
ICReadDirInfo(Handle,&tempDir);//读取文件目录信息
FileLen=tempDir.FileSize;
currPage=tempDir.FirstPage;
while(Count>0) //读取文件字节数
{
do
{
iTemp=(numPage+1)*ICSysInfo.PageBytes;
if (Start>iTemp)
{
currPage=ICReadPageSign(currPage);
numPage++;
}
else
{
break;
}
}
while(1);
}
if (oldPage!=currPage)//判断是否在同一页
{
if (oldPage!=0)
{
ICBuf1ToPage(oldPage);
}
ICPageToBuf1(oldPage);
ICWriteBuf1Byte(Start&ICSysinfo.PageBytes,*Buffer++);
oldPage=currPage;
}
else
{
ICWriteNextByte(*Buffer++);
}
Start++;
Count--;
iResult++; //读取字节数+1
return (iResult);
}
//删除文件
uchar FileDelete(uchar *FileName)
{
uchar i;
ICDirInfo tempDir;
uchar *p=(uchar *)(&tempDir);
uint 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=ICWritePageSign(w);
}
ICWritePageSign(w,csFree);
ICWritePageSign(w1,csFree);
*p=0x00;
ICWriteDirInfo(i,&tempDir);
}
return (1);
}
//格式化IC卡
uchar ICFormat()
{
uchar b;
ICWriteSysInfo(*ICSysInfo,SysInfoPage); //写入系统信息
ICDeleteAll();
return(b);
}
//清除IC卡数据
uchar ICDeleteAll()
{
uchar b=1;
uint i,j;
//初始化写入文件目录
for (i=ICSysInfo.DirStart;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;
}
}
return(b);//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;
}
}
return(b);
}
//获取可用空间字节数
ulong ICFreeSize()
{
uint curPage=0;
ulong lResult=0;
do
{
curPage=ICNextFreePage(curPage);
if (curPage>0)
lResult++;
else
break;
}
while(1);
lResult*=ICSysInfo.PageBytes;
return(lResult);
}
//获取已使用空间字节数
ulong ICUsedSize()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -