#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; Destination=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);//从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==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[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]); } } //********************减卡函数***********// void Sub_Card(uchar *p) {uchar i,B_Flag; uchar temp[14]; i=Read_Card(temp); if((i==3)&&(!(temp[9]<p[0]))) {if(temp[13]<p[4]) {temp[13]=temp[13]+10-p[4];B_Flag=1;} else temp[13]=temp[13]-p[4]; //以上处理小数点右边的数字; if(B_Flag==1) {if(temp[12]==0) {temp[12]=9;B_Flag=0;} else temp[12]=temp[12]-1;} //以上对存在借位情况时对小数点左边第一位进行预处理; if(temp[12]<p[3]) {temp[12]=temp[12]+10-p[3];B_Flag=1;} else temp[12]=temp[12]-p[3]; //以上处理小数点小数点左边第一位数字; if(B_Flag==1) {if(temp[11]==0) {temp[11]=9;B_Flag=0;} else temp[11]=temp[11]-1;} //以上对存在借位情况时对小数点左边第二位进行预处理; if(temp[11]<p[2]) {temp[11]=temp[11]+10-p[2];B_Flag=1;} else temp[11]=temp[11]-p[2]; //以上处理小数点小数点左边第二位数字; if(B_Flag==1) {if(temp[10]==0) {temp[10]=9;B_Flag=0;} else temp[10]=temp[10]-1;} //以上对存在借位情况时对小数点左边第三位进行预处理; if(temp[10]<p[1]) {temp[10]=temp[10]+10-p[1];B_Flag=1;} else temp[10]=temp[10]-p[1]; //以上处理小数点小数点左边第三位数字; if(B_Flag==1) {if(temp[9]==0) {temp[9]=0;B_Flag=0;} else temp[9]=temp[9]-1;} //以上对存在借位情况时对小数点左边第二位进行预处理; temp[9]=temp[9]-p[0]; //以上处理小数点小数点左边第二位数字; WriteMainMemory(41,temp[9]); WriteMainMemory(42,temp[10]); WriteMainMemory(43,temp[11]); WriteMainMemory(44,temp[12]); WriteMainMemory(45,temp[13]); } } //*****************数码管显示函数********************// void Display(uchar *p) {uchar sel,i; sel=0x01; for(i=0;i<6;i++) {PORTA=table[p]; PORTB=sel; DelayMs(2); sel=sel<<1;} } //****************键盘扫描函数***********************// uchar Key_Scan(void) {uchar sccode,recode; PORTC=0xf0; if((PINC&0xf0)!=0xf0) {DelayMs(10); if((PINC&0xf0)!=0xf0) {sccode=0xfe; while(sccode&0x10!=0x00) {PORTC=sccode; //对第一行键盘测试 if((PINC&0xf0)!=0xf0) {recode=(PINC&0xf0)|0x0f; return((~sccode)+(~recode));} else sccode=(sccode<<1)|0x01; } } } return(0x00); } //******************按键处理函数*******************// void Key_Process(uchar *p) {uchar temp,value; temp=Key_Scan(); switch(temp) {case 0x11:value=9;Num_Flag=1;break; case 0x21:value=8;Num_Flag=1;break; case 0x41:value=7;Num_Flag=1;break; case 0x12:value=6;Num_Flag=1;break; case 0x22:value=5;Num_Flag=1;break; case 0x42:value=4;Num_Flag=1;break; case 0x14:value=3;Num_Flag=1;break; case 0x24:value=2;Num_Flag=1;break; case 0x44:value=1;Num_Flag=1;break; case 0x18:value=0;Num_Flag=1;break; case 0x28:Point_Flag=1;break; case 0x82:Add_Flag=1;Sub_Flag=0;Key_Flag=1;break; case 0x84:Sub_Flag=1;Add_Flag=0;Key_Flag=1;break; case 0x48:Repair_Flag=1;Key_Flag=1;break; case 0x81:Init_Flag=1;Key_Flag=1;break; case 0x88:Enter_Flag=1;Key_Flag=0;break; default: NOP(); } if(Num_Flag==1){p[4]=p[3];p[3]=p[2];p[2]=p[1];p[1]=value;Num_Flag=0;} if(Point_Flag==1){p[0]=value;Point_Flag=0;} if(Add_Flag==1) {Add_Flag=1;Sub_Flag=0;} if(Sub_Flag==1) {Sub_Flag=1;Add_Flag=0;} if(Init_Flag==1) {Init_Flag=1;} if(Repair_Flag==1) {Repair_Card();Repair_Flag=0;} if(Enter_Flag==1) {if(Add_Flag==1) {Add_Card(p);Enter_Flag=0;Add_Flag=0;} if(Sub_Flag==1) {Sub_Card(p);Enter_Flag=0;Sub_Flag=0;} if(Init_Flag==1) {Initial_Card(p);Init_Flag=0;}} } //***************中断处理********************// //**********定时器2:16ms中断显示一次*******// #pragma interrupt_handler TIMER1_INT:9 void TIMER1_INT(void) {uchar temp[5],i; for(i=0;i<5;i++) temp=ICcontent[9+i]; if(IC_Flag==0) Display(EEEEE); if(IC_Flag==1) Display(FFFFF); if(IC_Flag==3) {if(Key_Flag==1)//显示此次操作金额; {Money[1]|=0x80;//显示时加上小数点; Display(Money);} else //显示卡内余额; {temp[4]|=0x80; Display(temp);} } } //*************系统初始化*************// void Initial_System(void) {//系统初始化 //SPL=0x5f;//AT90S8535的堆栈指针指向最高RAM地址; //SPH=0x02; //IO口初始化; DDRA=0xff; //A口输出高电平 PORTA=0xff; DDRB=0xff; //B口输出低电平 PORTB=0x00; DDRC=0x0f; //C口高四位输入(不带上拉电阻)低四位输出0 PORTC=0xf0; DDRD=0xff; //D口输出低电平 PORTD=0x00; //中断系统初始化(定时器1中断) SREG=SREG|0x80; //I(SREG^7)全局中断使能置位 TIMSK=TIMSK|0x40;//TOIE1(TIMSK^2)T/C1溢出中断使能置位 TIFR=TIFR|0x40;//TOV1(TIFR^2)T/C1溢出中断标志位写"1"清0 //定时器初始化 TCCR1B=TCCR1B|0x20;//定时器时钟分频=CLK/8 (1uS计数) TCNT1H=0xc1;//需要计数16000=0x3E80次, TCNT1L=0x7f;//计数初值0xff-0x3e80=0xc17f; //显示系统初始化 IC_Flag=0;//如果IC卡没有上电,则显示的是8.8.8.8.,否则显示IC卡的内容 } void main(void) {uchar i,j; Initial_System(); while(IC_Flag==1) {DelayMs(5); ResetIC(ICcode); i=Read_Card(ICcontent); if(i==0) {IC_Flag=0; Buzzle_Password();} //显示EEEE,提示卡坏 if((i==1)|(i==2)) {IC_Flag=1;Buzzle_Card();} //显示FFFF,提示非法卡 if(i==3) {if(ICcontent[12]<5) {IC_Flag=3;Buzzle_Money();} else {do Key_Process(Money); while(Enter_Flag!=0); Enter_Flag=0;} } } }