//*********************FileName:Main.c*********************//
//*********************Author:Steaven2000@163.com**********//
//********************Version:1.2*************************//
//******************LastUpdate:2004-11-03*****************//
#include
#include
#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
? 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[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]
? {if(temp[13]
? 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]
? 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]
?? 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]
?? 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[i]];
??? 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[i]=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;}
?? }?
?? }
}
評論
查看更多