?? 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 + -