AVR单片机IC卡程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
//**********界说全局变量*******************//
//查表0123456789EFPOFF
uchartable[14]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x79,0x71,0x73,0x00};
ucharICCode[4];//界说IC卡复位时读出的4字节代码;
ucharICcontent[14];//界说IC卡有用信息;
ucharMoney[5];//界说IC卡内金额;
ucharEEEEE[5]={0x79,0x79,0x79,0x79};
ucharFFFFF[5]={0x71,0x71,0x71,0x71};
ucharNum_Flag;//数标志;
ucharAdd_Flag;//加标志
ucharSub_Flag;//减标志
ucharInit_Flag;//初始化标志
ucharRepair_Flag;//修卡标志;
ucharEnter_Flag;//承认标志
ucharPoint_Flag;//。标志
ucharKey_Flag;//按键标志;
//***********IC卡引脚信号处理***************//
voidVoice(ucharPD)//Voice=PD^7
{if(PD==1)PORTD|=0x80;//Voice置1
elsePORTD&=~80;//Voice置0
}
voidRST(ucharPD)//RST=PD^6
{if(PD==1)PORTD|=0x40;//RST置1
elsePORTD&=~0x40;//RST置0
}
voidCLK(ucharPD)//CLK=PD^5
{if(PD==1)PORTD|=0x20;//CLK置1
elsePORTD&=~0x20;//CLK置0
}
voidIO(ucharPD)//IO=PD^4
{if(PD==1)PORTD|=0x10;//IO置1
elsePORTD&=~0x10;//IO置0
}
voidSeTIO(uchari)//设置IO口特点
{if(i==1)DDRD=0xf0;//IO口输出:11110000
elseDDRD=0xe0;//IO口输如:11100000
PORTD=0x00;//不带上拉电阻;
}
//**********延时函数(Us数量级)*********//
//单周期指令执行时间,执行时间1/8us*分频系数(取8分频则刚好1us);
voidDelayUs(uchari)
{for(;i!=0;i–)
NOP();
}
//****************延时函数(Ms数量级)*********//
voidDelayMs(uinTI)
{ucharj,k;
for(;i!=0;i–)
{for(k=0;k《4;k++)
{for(j=250;j!=0;j–)NOP();}
}
}
//****************接纳数据**************//
ucharReceivEDAta(void)
{ucharcount;
ucharvalue;
uchario_value;
value=0;
SeTIO(0);//设置IO脚为输入;
CLK(0);
//IO=1;
for(count=0;count《8;count++)
{value=value》》1;
CLK(1);
DelayUs(2);
io_value=PIND;
CLK(0);
DelayUs(2);
if(io_value&0x10==0x10)value|=0x80;//判别IO脚是否为1
elsevalue&=0x7f;
}
return(value);
}
//********************发送数据************//
voidSendData(ucharXdata)
{ucharcount;
ucharvalue;
SeTIO(1);////设置IO脚为输出;
value=Xdata;
for(count=8;count!=0;count–)
{CLK(0);
if((Xdata《《(count-1))&0x80)IO(1);
elseIO(0);
CLK(1);
DelayUs(2);
CLK(0);}
}
//****************IC卡复位************************//
voidResetIC(uchar*Xdata)
{ucharcount;
SetIO(1);//设置IC卡引脚的特点
RST(0);
CLK(0);
IO(1);
DelayUs(5);
RST(1);
DelayUs(5);
CLK(1);
DelayUs(5);
CLK(0);
DelayUs(5);
RST(0);
for(count=4;count!=0;count–)
{*Xdata=ReceiveData();
Xdata+=2;}
}
//*******************Start条件****************//
voidStart(void)
{SetIO(1);
CLK(0);
IO(0);
DelayUs(2);
CLK(1);
IO(1);
DelayUs(2);
IO(0);
CLK(0);
}
//*******************Stop条件****************//
voidStop(void)
{CLK(0);
IO(0);
DelayUs(2);
CLK(1);
IO(0);
DelayUs(2);
IO(1);
DelayUs(2);
IO(0);
}
//******************处理进程**************//
voidProcess(void)
{uintj;
SetIO(1);//设置IO脚为输出脚
CLK(0);
DelayUs(5);
IO(0);
for(j=255;j》0;j–)
{CLK(1);
DelayUs(5);
CLK(0);
DelayUs(5);
}
IO(1);
}
//****************阐明*********************//
//*********输出形式接口指令,包含读主存储器30H,读维护存储器34H,读安全代码的接口指令31H***********//
//******处理形式数据接口指令,包含写主存储器38H,写维护存储器3CH,写安全代码39H,校验安全代码33H*******//
voidCommand(ucharByte1,ucharByte2,ucharByte3)
{Start();
SendData(Byte1);
SendData(Byte2);
SendData(Byte3);
Stop();
}
/**********读主存储器**************/
voidReaDMAinMemory(ucharaddr,uchar*p,ucharN)
{Command(0x30,addr,0xff);
do{*p=ReceiveData();
p++;}while(–N);
}
/**********读维护存储器***********/
voidReadProtectMemory(uchar*p)
{uchari=4;
Command(0x34,0xff,0xff);
do{*p=ReceiveData();
p++;}while(i–);
}
/************写主存储器************/
voidWriteMainMemory(ucharAddress,ucharData)
{Command(0x38,Address,Data);
Process();
}
/**************写维护存储器**********/
voidWriteProtectMemory(ucharAddress,ucharData)
{Command(0x3c,Address,Data);
Process();
}
/**************读安全存储器************/
voidReadSafeMemory(uchar*p)
{uchari;
Command(0x31,0xff,0xff);
for(i=0;i《4;i++)
{*p=ReceiveData();
p++;}
}
/*************写安全存储器***************/
voidWriteSafeMemory(ucharAddress,ucharData)
{Command(0x39,Address,Data);//Address=0,1,2,3
Process();
}
/**************校验暗码*******************/
ucharVerifyPassword(uchar*p)
{uchartemp[4];//暂存4字节维护暗码;
uchari;
ReadSafeMemory(temp);//读安全代码以获得过错计数器
if((temp[0]&0x07)!=0)
{if((temp[0]&0x07)==0x07)i=0x06;
if((temp[0]&0x07)==0x06)i=0x04;
if((temp[0]&0x07)==0x04)i=0x00;
WriteSafeMemory(0,i);
for(i=1;i《4;i++,p++)
{Command(0x33,i,*p);
Process();}
WriteSafeMemory(0,0xff);
ReadSafeMemory(temp);
if((temp[0]&0x07)==0x07)return(0x1);
}
return(0);
}
//*************SLE4442函数完毕*****************//
//*************数据改换**********//
voidChange(uchar*Source,uchar*Destination,ucharN)
{uchari,temp;
for(i=0;i{temp=Source[i];
Destination[i]=temp》》4;
Destination[2*i+1]=temp&0x0f;}
}
//***********暗码过错报警***********************//
voidBuzzle_Password(void)
{uchari;
for(i=0;i《2;i++)
{Voice(0);
DelayMs(1000);
Voice(1);
DelayMs(1000);}
}
//**********不合法卡过错报警*************************//
voidBuzzle_Card(void)
{uchari;
for(i=0;i《2;i++)
{Voice(0);
DelayMs(3000);}
}
//*************余额缺乏报警**********************//
voidBuzzle_Money(void)
{uchari;
for(i=0;i《1;i++)
{Buzzle_Password();
Buzzle_Card();}
}
//*********************读卡函数********************//
//阐明:
//函数运用的数组参数用来寄存读出的余额值;
//返回值信息:
//0:卡坏!
//1:不合法卡(特征值不正确)
//2:不合法卡(特征值正确,帐号不正确)
//3:读卡成功!
ucharRead_Card(uchar*p)
{uchari,tag=0,temp[4];
ReadSafeMemory(temp);
if(temp[0]==0x07)
{ReadMainMemory(32,p,14);//读主存储器14字节:32-35特征码;36-3A帐号;3B-3F余额
if(p[0]==0x00&&p[1]==0x0f&&p[2]==0xf0&&p[3]==0xff)//特征码:0x00,0x0f,0xf0,0xff
{for(i=0;i《10;i++)
if((p[i+4]》=0&&p[i+4]《=9))tag=tag+1;
if(tag!=10)return(2);
elsereturn(3);
}
else
return(1);
}
elsereturn(0);
}
//*********************卡初始化函数********************//
//阐明:
//函数运用的数组参数用来寄存写入的的ID值;
//返回值信息:
//2:初始化失利!
//3:初始化成功!
ucharInitial_Card(uchar*p)
{ucharPsw[3]={0xff,0xff,0xff};
uchari,j,temp=0;
uchartp[20];
//ResetIC(ICcode);//IC卡复位,读出复位后的厂家信息代码A2131091;
j=VerifyPassword(Psw);
WriteMainMemory(32,0x00);//写特征码:
WriteMainMemory(33,0x0f);
WriteMainMemory(34,0xf0);
WriteMainMemory(35,0xff);
for(i=0;i《5;i++)//写帐号
WriteMainMemory(36+i,p[i]);//从32+i地址开端写5字节帐号;
for(i=0;i《5;i++)
WriteMainMemory(41+i,0);//从32+i地址开端写5字节初始化金额0000.0
j=Read_Card(tp);
if(j==3)
{for(i=0;i《10;i++)
if(p[i]==tp[i+4])temp=temp+1;
}
if(temp==10)return(3);
elsereturn(2);
}
//***************卡修正函数********************//
//阐明:
//返回值信息:
//0:修正失利!
//1:修正成功!
ucharRepair_Card(void)
{ucharPsw[3]={0xff,0xff,0xff};
uchari,j,temp;
i=VerifyPassword(Psw);
return(i);
}
//********************加卡函数***********//
voidAdd_Card(uchar*p)
{uchari;
uchartemp[14];
i=Read_Card(temp);
if(i==3)
{temp[13]=temp[13]+p[4];
if(temp[13]》9){temp[13]=temp[13]-10;temp[12]=temp[12]+1;}
temp[12]=temp[12]+p[3];
if(temp[12]》9){temp[12]=temp[12]-10;temp[11]=temp[11]+1;}
temp[11]=temp[11]+p[2];
if(temp[11]》9){temp[11]=temp[11]-10;temp[10]=temp[10]+1;}
temp[10]=temp[10]+p[1];
if(temp[10]》9){temp[10]=temp[10]-10;temp[9]=temp[9]+1;}
WriteMainMemory(41,temp[9]);
WriteMainMemory(42,temp[10]);
WriteMainMemory(43,temp[11]);
WriteMainMemory(44,temp[12]);
WriteMainMemory(45,temp[13]);
}
}
//********************减卡函数***********//
voidSub_Card(uchar*p)
{uchari,B_Flag;
uchartemp[14];
i=Read_Card(temp);
if((i==3)&&(!(temp[9]{if(temp[13]elsetemp[13]=temp[13]-p[4];
//以上处理小数点右边的数字;
if(B_Flag==1)
{if(temp[12]==0){temp[12]=9;B_Flag=0;}
elsetemp[12]=temp[12]-1;}
//以上对存在借位状况时对小数点左面第一位进行预处理;
if(temp[12]elsetemp[12]=temp[12]-p[3];
//以上处理小数点小数点左面第一位数字;
if(B_Flag==1)
{if(temp[11]==0){temp[11]=9;B_Flag=0;}
elsetemp[11]=temp[11]-1;}
//以上对存在借位状况时对小数点左面第二位进行预处理;
if(temp[11]elsetemp[11]=temp[11]-p[2];
//以上处理小数点小数点左面第二位数字;
if(B_Flag==1)
{if(temp[10]==0){temp[10]=9;B_Flag=0;}
elsetemp[10]=temp[10]-1;}