//*********************FileName:Main.c*********************//
//*********************Author:[email protected]**********//
//********************Version:1.2*************************//
//******************LastUpdate:2004-11-03*****************//
#include <io8535v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
//**********定义全局变量*******************//
//查表0 1 2 3 4 5 6 7 8 9 E F P OFF
uchar table[14]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x79,0x71,0x73,0x00};
uchar ICcode[4];//定义IC卡复位时读出的4字节代码;
uchar ICcontent[14];//定义IC卡有效信息;
uchar Money[5];//定义IC卡内金额;
uchar EEEEE[5]={0x79,0x79,0x79,0x79};
uchar FFFFF[5]={0x71,0x71,0x71,0x71};
uchar IC_Flag;//定义IC卡上电标志;
uchar Num_Flag;//数标志;
uchar Add_Flag;//加标志
uchar Sub_Flag;//减标志
uchar Init_Flag;//初始化标志
uchar Repair_Flag;//修卡标志;
uchar Enter_Flag;//确认标志
uchar Point_Flag;//.标志
uchar Key_Flag; //按键标志;
//***********IC卡引脚信号处理***************//
void Voice(uchar PD) //Voice=PD^7
{if(PD==1) PORTD|=0x80;//Voice置1
else PORTD&=~80; //Voice置0
}
void RST(uchar PD) //RST=PD^6
{if(PD==1) PORTD|=0x40;//RST置1
else PORTD&=~0x40;//RST置0
}
void CLK(uchar PD) //CLK=PD^5
{if(PD==1) PORTD|=0x20;//CLK置1
else PORTD&=~0x20;//CLK置0
}
void IO(uchar PD) //IO=PD^4
{if(PD==1) PORTD|=0x10;//IO置1
else PORTD&=~0x10;//IO置0
}
void SetIO(uchar i)//设置IO口属性
{if(i==1) DDRD=0xf0; //IO口输出:1111 0000
else DDRD=0xe0; //IO口输如:1110 0000
PORTD=0x00;//不带上拉电阻;
}
//**********延时函数(Us数量级)*********//
//单周期指令执行时间,执行时间1/8us*分频系数(取8分频则刚好1us);
void DelayUs(uchar i)
{for(;i!=0;i--)
NOP();
}
//****************延时函数(Ms数量级)*********//
void DelayMs(uint i)
{uchar j,k;
for(;i!=0;i--)
{for(k=0;k<4;k++)
{for(j=250;j!=0;j--) NOP();}
}
}
//****************接收数据**************//
uchar ReceiveData(void)
{uchar count;
uchar value;
uchar io_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
else value&=0x7f;
}
return (value);
}
//********************发送数据************//
void SendData(uchar Xdata)
{uchar count;
uchar value;
SetIO(1);////设置IO脚为输出;
value=Xdata;
for(count=8;count!=0;count--)
{CLK(0);
if((Xdata<<(count-1))&0x80) IO(1);
else IO(0);
CLK(1);
DelayUs(2);
CLK(0);}
}
//****************IC卡复位************************//
void ResetIC(uchar *Xdata)
{uchar count;
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条件****************//
void Start(void)
{SetIO(1);
CLK(0);
IO(0);
DelayUs(2);
CLK(1);
IO(1);
DelayUs(2);
IO(0);
CLK(0);
}
//*******************Stop条件****************//
void Stop(void)
{CLK(0);
IO(0);
DelayUs(2);
CLK(1);
IO(0);
DelayUs(2);
IO(1);
DelayUs(2);
IO(0);
}
//******************处理过程**************//
void Process(void)
{uint j;
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*******//
void Command(uchar Byte1,uchar Byte2,uchar Byte3)
{Start();
SendData(Byte1);
SendData(Byte2);
SendData(Byte3);
Stop();
}
/**********读主存储器**************/
void ReadMainMemory(uchar addr,uchar *p,uchar N)
{Command(0x30,addr,0xff);
do{*p=ReceiveData();
p++;}while(--N);
}
/**********读保护存储器***********/
void ReadProtectMemory(uchar *p)
{uchar i=4;
Command(0x34,0xff,0xff);
do{*p=ReceiveData();
p++;}while(i--);
}
/************写主存储器************/
void WriteMainMemory(uchar Address,uchar Data)
{Command(0x38,Address,Data);
Process();
}
/**************写保护存储器**********/
void WriteProtectMemory(uchar Address,uchar Data)
{Command(0x3c,Address,Data);
Process();
}
/**************读安全存储器************/
void ReadSafeMemory(uchar *p)
{uchar i;
Command(0x31,0xff,0xff);
for(i=0;i<4;i++)
{*p=ReceiveData();
p++;}
}
/*************写安全存储器***************/
void WriteSafeMemory(uchar Address,uchar Data)
{Command(0x39,Address,Data);//Address=0,1,2,3
Process();
}
/**************校验密码*******************/
uchar VerifyPassword(uchar *p)
{uchar temp[4];//暂存4字节保护密码;
uchar i;
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函数结束*****************//
//*************数据变换**********//
void Change(uchar *Source,uchar *Destination,uchar N)
{uchar i,temp;
for(i=0;i<N;i++)
{temp=Source[i];
Destination[i]=temp>>4;
Destination[2*i+1]=temp&0x0f;}
}
//***********密码错误报警***********************//
void Buzzle_Password(void)
{uchar i;
for(i=0;i<2;i++)
{Voice(0);
DelayMs(1000);
Voice(1);
DelayMs(1000);}
}
//**********非法卡错误报警*************************//
void Buzzle_Card(void)
{uchar i;
for(i=0;i<2;i++)
{Voice(0);
DelayMs(3000);}
}
//*************余额不足报警**********************//
void Buzzle_Money(void)
{uchar i;
for(i=0;i<1;i++)
{Buzzle_Password();
Buzzle_Card();}
}
//*********************读卡函数********************//
//说明:
//函数使用的数组参数用来存放读出的余额值;
//返回值信息:
//0:卡坏!
//1:非法卡(特征值不正确)
//2:非法卡(特征值正确,帐号不正确)
//3:读卡成功!
uchar Read_Card(uchar *p)
{uchar i,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);
else return(3);
}
else
return(1);
}
else return(0);
}
//*********************卡初始化函数********************//
//说明:
//函数使用的数组参数用来存放写入的的ID值;
//返回值信息:
//2:初始化失败!
//3:初始化成功!
uchar Initial_Card(uchar *p)
{uchar Psw[3]={0xff,0xff,0xff};
uchar i,j,temp=0;
uchar tp[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);
else return(2);
}
//***************卡修复函数********************//
//说明:
//返回值信息:
//0:修复失败!
//1:修复成功!
uchar Repair_Card(void)
{uchar Psw[3]={0xff,0xff,0xff};
uchar i,j,temp;
i=VerifyPassword(Psw);
return(i);
}
//********************加卡函数***********//
void Add_Card(uchar *p)
{uchar i;
uchar temp[