⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysle4442.c

📁 利用syncmos单片机实现对sle4442卡片的识别
💻 C
字号:
#include <reg52.h>
#include <intrins.h>
//#include <AT89X55.H>

/*SLE4442命令字宏定义*/
#define		READ_MAIN_MEM   0x30 	/*read main memory of SLE 4442*/
#define		READ_PROT_MEM   0x34 	/*read protection memory of SLE 4442*/
#define		WRITE_MAIN_MEM  0x38 	/*write main memory of SLE 4442*/
#define		WRITE_PROT_MEM  0x3C 	/*write protection memory of SLE 4442*/
#define		READ_SECU_MEM   0x31 	/*read security memory of SLE 4442*/
#define		WRITE_SECU_MEM  0x39    /*write security memory of SLE 4442*/
#define		COMPARE_VERIFY  0x33 	/*compare verification data of SLE 4442*/
sfr WDTRST=0x0A6;
/*SLE4442卡校验密码*/
extern unsigned char PassWord[3];
extern unsigned char NewPassWord[3];
//#define PassWord0	0xEF
//#define PassWord1	0x37
//#define PassWord2	0x28

sbit	RST_IC=P1^6; 			/*IC card RESET port*/
sbit	CLOCK_PORT=P1^7; 		/*IC card */
sbit	DATA_IC=P1^5; 			/*IC card DATA port*/
sbit	POWER_IC=P1^4; 			/*port of IC power*/

unsigned char READ_IC_BYTE(void);
void DELAY_1_UNIT(void);
void DELAY_IC_OPERATION(void);
/****************************************************************/
/*	SLE4442 子程序						*/
/****************************************************************/
/*;============================================================================
;  SUBROUTINE_NAME:  START_TEST
; 1. FUNCTION:  测试下一个过程的开始
; 2. INPUT: nop
; 3. OUTPUT: nop
; 4. REGISTER USED: 
;============================================================================*/

void START_TEST(void){
	do { 
 		CLOCK_PORT=1;
 		
                DELAY_IC_OPERATION();
                
                CLOCK_PORT=0;
                
                DELAY_IC_OPERATION();
                
                DATA_IC=1;
          }
        while(DATA_IC==0);
        
        
	WDTRST=0x1E;
	WDTRST=0xE1;
}
/*;============================================================================
;  SUBROUTINE_NAME:  COMMAND_SEND
; 1. FUNCTION:发送命令字到IC卡
; 2. INPUT:     *command 命令字的起始地址指针
; 3. OUTPUT:    nop
;============================================================================*/

void	COMMAND_SEND(unsigned char *command){
unsigned char	BitCount,i;
unsigned char	BitData;

		DELAY_IC_OPERATION();
		
		DATA_IC=1;
		
		DELAY_IC_OPERATION();
		
                CLOCK_PORT=1;
                
                DELAY_IC_OPERATION();
                
                DATA_IC=0;
                
                DELAY_IC_OPERATION();
                
                CLOCK_PORT=0;
                
                DELAY_IC_OPERATION();
                
	WDTRST=0x1E;
	WDTRST=0xE1;
  for(i=0;i<3;i++,command++)
  {
   	BitData=*command;
              
	for(BitCount=0;BitCount<8;BitCount++)
	{
		if(BitData&0x01==1)
			DATA_IC=1;
		else
			DATA_IC=0;
		BitData>>=1;
		
		DELAY_IC_OPERATION();
		
		CLOCK_PORT=1;
		
		DELAY_IC_OPERATION();
		
		CLOCK_PORT=0;
	       
	        DELAY_IC_OPERATION();
	        
	WDTRST=0x1E;
	WDTRST=0xE1;
		
	}
   }

                DELAY_IC_OPERATION();
                
                DATA_IC=0;
                _nop_();		/*just for delay*/
               
                DELAY_IC_OPERATION();
                
                CLOCK_PORT=1;
                _nop_();		/*just for delay*/
              
               DELAY_IC_OPERATION();
               
               DATA_IC=1;
              
               DELAY_IC_OPERATION();
               
	WDTRST=0x1E;
	WDTRST=0xE1;
}
 
/*;============================================================================
;  SUBROUTINE_NAME:  READ_IC_BYTE
; 1. FUNCTION:  从IC卡读入一个字节
; 2. INPUT: nop
; 3. OUTPUT: nop
; 4. SUB_CALLED:
;============================================================================*/

unsigned char READ_IC_BYTE(void)
{
	unsigned char BitCount,BitData;
	//DATA_IC=1;
	
	for(BitCount=0;BitCount<8;BitCount++)
	{
	 BitData>>=1;/* >>= 右移位赋值*/
	if(DATA_IC==1)
	  BitData|=0x80;/* |= 逻辑或赋值*/
	else
	  BitData&=0x7F;/* &= 逻辑与赋值,其实它只不过是使I/O产生一个下降沿*/
	                  /*在前面运行的函数中已经有一个下降沿了,所以在该函数中开始的时候
	                  不需要下降沿*/
	CLOCK_PORT=1;     /*在时钟线上的第一个下降沿到来后,I/O线上的第一个数据位有效*/
	
	DELAY_IC_OPERATION();
	
	CLOCK_PORT=0;     /*以上3行产生一个下降沿是I/O口上的数据有效更新*/
	
	DELAY_IC_OPERATION();
	
	
	WDTRST=0x1E;  /*喂狗*/
	WDTRST=0xE1;
	}
	return(BitData);
	
}

/*;============================================================================
;  SUBROUTINE_NAME:  WRITE_IC_BYTE
; 1. FUNCTION:  写入一个字节到 SLE4442 MAIN memory
; 2. INPUT:     address 数据的写入地址, 
;		Data	写入的数据数据
; 3. OUTPUT: nop
; 4. REGISTER USED:
; 5. SUB_CALLED:
; WORD1_COMMAND
;============================================================================*/
void	WRITE_IC_BYTE(unsigned char address,unsigned Data){
unsigned char command[3];
	command[0]=WRITE_MAIN_MEM;
	command[1]=address;
	command[2]=Data;
	COMMAND_SEND(command);
	START_TEST();
}	

/*;============================================================================
;  SUBROUTINE_NAME:  WRITE_IC_PROBYTE
; 1. FUNCTION:  写入一个字节到 SLE4442 MAIN memory
; 2. INPUT:     address 数据的写入地址, 
;		Data	写入的数据数据
; 3. OUTPUT: nop
; 4. REGISTER USED:
; 5. SUB_CALLED:
; WORD1_COMMAND
;============================================================================*/
void	WRITE_IC_PROBYTE(unsigned char address,unsigned Data){
unsigned char command[3];
	command[0]=WRITE_PROT_MEM;
	command[1]=address;
	command[2]=Data;
	COMMAND_SEND(command);
	START_TEST();
}	


/*;============================================================================
;  SUBROUTINE_NAME:  RST_AND_ANSWER
; 1. FUNCTION:  IC卡复位,检测IC卡的应答.
; 2. INPUT:     nop
; 3. OUTPUT:    检测通过,返回1;否则,返回0。
;============================================================================*/
//*
void RST_AND_ANSWER(unsigned char *p){
unsigned char i;
		EA=0;
		//DATA_IC=0;
 		RST_IC=0;
 		
 		DELAY_IC_OPERATION();
 		
 		CLOCK_PORT=0;
 		
 		DELAY_IC_OPERATION();
		
	        RST_IC=1;
                
                DELAY_IC_OPERATION();
                
                CLOCK_PORT=1;
                
                DELAY_1_UNIT();
                
                CLOCK_PORT=0;
                
                DELAY_IC_OPERATION();
                
	WDTRST=0x1E;
	WDTRST=0xE1;
                
                RST_IC=0;
                _nop_();
		_nop_();
		_nop_();
		_nop_();
        	_nop_();
		_nop_();
	    	for(i=0;i<4;i++)
		    {
		    *p++=READ_IC_BYTE();
		    }
	    
		EA=1;                
}
//*/
/*;============================================================================
;  SUBROUTINE_NAME:  READ_EC
; 1. FUNCTION:  读取IC卡错误计数器
; 2. INPUT:     *pChar数据输出地址指针
; 3. OUTPUT:    1st byte: EC (pChar, pChar+1, pChar+2, pChar+3)
; 4. SUB_CALLED:    COMMAND_SEND, READ_IC_BYTE.
;============================================================================*/
void READ_EC(unsigned char *pChar){

unsigned char ByteCount;
unsigned char WordCommand[3]={ READ_SECU_MEM,0x00,0x00 };

                COMMAND_SEND(WordCommand);
                
                CLOCK_PORT=0;
                
                DELAY_IC_OPERATION();
                              
                
	for(ByteCount=0;ByteCount<4;ByteCount++,pChar++)
	
	{
	*pChar=READ_IC_BYTE();
		
        }
	
}         
/*;============================================================================
;  SUBROUTINE_NAME:  VERIFICATION
; 1. FUNCTION: 检测SLE4442的错误计数器,如果计数器的值为非零返回1,否则返回0
; 2. INPUT: nop
; 3. OUTPUT: 输出计数器的值
; 4. REGISTER USED: READ_EC, COMMAND_SEND, START_TEST,
; 5. SUB_CALLED:
;============================================================================*/
/*好像没用*/
/*
bit VERIFICATION(void){
unsigned char Word[4];
unsigned char i;
		EA=0;
		READ_EC(Word);                //read IC card error_counter
		
	if(Word[0]!=0)
		{
			i=0;
			if((Word[0]&0x01)!=0)
				i++;
			if((Word[0]&0x02)!=0)
				i++;
			if((Word[0]&0x04)!=0)
				i++;	
			return (i);
		}
	else
        {
            return 0;
        }
        EA=1;
     
	WDTRST=0x1E;
	WDTRST=0xE1;          	
  }
//*/
/*;============================================================================
;  SUBROUTINE_NAME:  COMPARISON_VD
; 1. FUNCTION: 校验4442的写入密码,如果密码正确,返回1;否则返回0
; 2. INPUT: nop
; 3. OUTPUT: OK: return to 1, else return 0
; 4. REGISTER USED:
; 5. SUB_CALLED:  COMMAND_SEND, START_TEST, READ_EC
;============================================================================*/

bit COMPARISON_VD(void){
unsigned char  Word[4];
unsigned char  cData;
unsigned char  Check;

	EA=0;
	
    START_TEST();              /* test start of processing*/
    READ_EC(Word);
    cData=Word[0];
	if((cData&0x01)!=0)
		{
		Check=0x06;
		goto	COMPARISON_Start;
		}
	else if((cData&0x02)!=0)
		{
		Check=0x05;			/*Check的值要修改为0x04*/
		goto	COMPARISON_Start;
		}
	else if((cData&0x04)!=0)
		{
		Check=0x03;		/*Check的值要修改为0x00*/
		}
	else	return 0;
	
COMPARISON_Start:

	Word[0]=WRITE_SECU_MEM;
	Word[1]=0x00;
	Word[2]=Check;	
        COMMAND_SEND(Word);
        START_TEST();		/*test start of processing*/
                
	 Word[0]=COMPARE_VERIFY;
	 Word[1]=0x01;
	 Word[2]=PassWord[0];
	 COMMAND_SEND(Word);
	 START_TEST();
	 
	 Word[0]=COMPARE_VERIFY;
	 Word[1]=0x02;
	 Word[2]=PassWord[1];
	 COMMAND_SEND(Word);
	 START_TEST();
	 
	 Word[0]=COMPARE_VERIFY;
	 Word[1]=0x03;
	 Word[2]=PassWord[2];
	 COMMAND_SEND(Word);
	 START_TEST();
	 
	 Word[0]=WRITE_SECU_MEM;
         Word[1]=0x00;
         Word[2]=0x0ff;
         COMMAND_SEND(Word);
	 START_TEST();              /* test start of processing*/
         READ_EC(Word);
	    cData=Word[0];
	
        if(cData==0x07)
	 {
	 	EA=1;
	 	return 1;
					/*密码校验通过*/
	  }
        else
        	{
        	EA=1;
        	return 0;
        	}
  
}
		


/*;============================================================================
;  SUBROUTINE_NAME:  READ_IC_INFOR
; 1. FUNCTION: 读SLE4442的主存储区.
; 2. INPUT:     Address 数据的起始地址
;               DataNum 数据的个数
;		RamAddr 数据存放的地址指针(CPU 内部RAM)
; 3. SUB_CALLED:     COMMAND_SEND, READ_IC_BYTE
;============================================================================*/

void READ_IC_INFOR(unsigned char Address,   
		   unsigned char DataNum,
		   unsigned char ChData[]) /*读主存储器*/
		   { 
unsigned char ByteCount;  /*设置要读取的字节数*/               
unsigned char WordCommand[3];/*存放命令内容数组*/

		WordCommand[0]=READ_MAIN_MEM;/*读主存储器命令的控制字*/
		WordCommand[1]=Address;      /*读主存储器命令的地址字*/
		WordCommand[2]=0x00;         /*读主存储器命令的数据字可以不写*/
		COMMAND_SEND(WordCommand);   /*发送命令到IC卡*/
		             /*在COMMAND_SEND函数完成后CLOCK_PORT为'1',因此在READ_IC_BYTE
		             函数中对读取第一位的有效数据时可以不对CLOCK_PORT置'0'*/
		CLOCK_PORT=0;/*在时钟线上的第一个下降沿到来后,I/O线上的第一个数据位有效
		               ,方可读位数据*/
				
 for(ByteCount=0;ByteCount<DataNum;ByteCount++)
     {		
		ChData[ByteCount]=READ_IC_BYTE();/*读IC卡主存储数据*/
     }

//  for(ByteCount=0;ByteCount<255;ByteCount++)
	//{	READ_IC_BYTE();		
	//}
		
		CLOCK_PORT=1;       /*增加额外的时钟脉冲,使I/O口成为高阻态*/
                _nop_();                             /* just for delay*/
                _nop_();
                _nop_();
                _nop_();
                CLOCK_PORT=0;
                _nop_();
                _nop_();
}

/*;============================================================================
;  SUBROUTINE_NAME: MODIFY_IC_PSW
; 2. INPUT:     密码存放地址 
; 1. FUNCTION:  修改IC卡的密码
; 3. OUTPUT: nop
; 4. REGISTER USED:
; 5. SUB_CALLED:  COMMAND_SEND 
;============================================================================*/
void MODIFY_IC_PSW(void) 
{	
unsigned char command[3];

	EA=0;

	if(COMPARISON_VD()==1)
	{
	 	PassWord[0]=NewPassWord[0];
		PassWord[1]=NewPassWord[1];
		PassWord[2]=NewPassWord[2];

		
		command[0]=WRITE_SECU_MEM;
		command[1]=0x00;
		command[2]=0x0FF;
		COMMAND_SEND(command);
		START_TEST();

		command[0]=WRITE_SECU_MEM;
		command[1]=0x01;
		command[2]=PassWord[0];
		COMMAND_SEND(command);
		START_TEST();

		command[0]=WRITE_SECU_MEM;
		command[1]=0x02;
		command[2]=PassWord[1];
		COMMAND_SEND(command);
		START_TEST();

		command[0]=WRITE_SECU_MEM;
		command[1]=0x03;
		command[2]=PassWord[2];
		COMMAND_SEND(command);
		START_TEST();

	
	}
    		
        EA=1;
}

/*;=====================================================*/
/*  SUBROUTINE_NAME:延时子程序  DELAY 50MS		*/
/*======================================================*/

void DELAY_1_UNIT(void)
{
unsigned char i,j;
	for(i=0;i<8;i++)
	   for(j=0;j<255;j++)
	   {
	   _nop_();
	   _nop_();
	   }
}	

 
/*               
void DELAY_2(void){
unsigned char i,j;
	for(i=0;i<0x80;i++)
	   for(j=0;j<255;j++)
	   {
	   _nop_();
	   _nop_();
	   }   
}
//*/
/********** IC 操作延时程序************/

void DELAY_IC_OPERATION(void)
 {
unsigned char j;
	   for(j=0;j<4;j++)
	   {
	   _nop_();
	   _nop_();
	    }
}	             

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -