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

📄 ic.c

📁 接触式IC卡
💻 C
📖 第 1 页 / 共 2 页
字号:
//***********IC卡引脚信号处理***************//
void RST(unsigned char PD)  //RST=PE^2
{if(PD==1)  PORTE|=0x04;//RST置1
 else       PORTE&=~0x04;//RST置0
}

void CLK(unsigned char  PD) //CLK=PE^1 
{
	if(PD==1)  PORTE|=0x02;//CLK置1
  else       PORTE&=~0x02;//CLK置0
}

void IO(unsigned char  PD)  //IO=PE^0
{
	if(PD==1)  PORTE|=0x01;//IO置1
  else       PORTE&=~0x01;//IO置0
}
 
void SetIO(unsigned char  i)//设置IO口属性
{if(i==1)   DDRE|=0x01;   //IO口输出:1111 0000带上拉输出
 else       DDRE&=~0x01; //IO口输如:1110 0000  不带上拉输入
 PORTE&=~0x01;//不带上拉电阻;
}

//**********延时函数(Us数量级)*********//
 void DelayUs(unsigned int  time)
 {  
      do
     time--;
    while(time>1);  
 }

//****************延时函数(Ms数量级)**//
void DelayMs(unsigned int  time)
{
    while(time!=0)
    {
      DelayUs(1000);    
      time--; 
    }
}


//****************接收数据**************//
unsigned char ReceiveData(void)
{unsigned char count;
 unsigned char value;
 unsigned char io_value;
 value=0;
 SetIO(0);//设置IO脚为输入; 
 CLK(0);
 for(count=0;count<8;count++)
  {value=value>>1; 
   io_value=PINE;
   if(io_value&0x01) value|=0x80;//判断IO脚是否为1
   else value&=0x7f;
   CLK(1);
   DelayUs(10);
   CLK(0);
   DelayUs(10);
  }
 return (value);
}
//****************复位**************//
void ResetIC(void)
{uchar count;
 SetIO(1); //设置IC卡引脚的属性 ,indata
 //DelayUs(70);
 RST(1);
 DelayUs(10);
 CLK(1);
 DelayUs(20);
 CLK(0);
 DelayUs(10);
 RST(0);
 DelayUs(10);
 count=ReceiveData();
 count=ReceiveData();
 count=ReceiveData();
 count=ReceiveData();
} 
//********************发送数据************// 
void SendData(unsigned char Xdata)  
{unsigned char count;
 unsigned char value;
 unsigned char i;
 SetIO(1);////设置IO脚为输出;
 for(count=8;count>0;count--)
 	{
	 value=Xdata;
	 i=value<<(count-1);
	 if(i&0x80)  IO(1);   //发送先发低位,后发高位
	 else IO(0);
	 CLK(1);
	 DelayUs(10);
	 CLK(0);
   DelayUs(10);	 
	 }
}

void power_on(void)
{
 //unsigned char count;
 SetIO(0); //设置IC卡引脚的属性 ,indata
 DelayUs(70);
 RST(1);
 DelayUs(10);
 CLK(1);
 DelayUs(30);
 CLK(0);
 DelayUs(10);
 RST(0);
 DelayUs(10);
 CLK(1);
 DelayUs(30);
 CLK(0);
 DelayUs(10);
 //for(count=4;count>0;count--)
 //	{*Xdata=ReceiveData();
 // Xdata+=1;}
}
//*******************Start条件****************//
void Start(void)
{SetIO(1);
 IO(1);
 CLK(1);
 DelayUs(10);
 IO(0);
 DelayUs(10);
 CLK(0);
}

//*******************Stop条件****************//
void Stop(void)
{
 SetIO(1);
 CLK(1);
 IO(0);
 DelayUs(10);
 IO(1);
 DelayUs(10);
}

//******************处理过程**************//
void Process(void)
{uint j,k;
 SetIO(1);//设置IO脚为输出脚
 CLK(0);
 DelayUs(10);
 IO(0);
 for(j=250;j>0;j--)
 {
 	 IO(0);
 	 CLK(1);
	 DelayUs(10);
	 CLK(0);
	 DelayUs(10);
	}
}

//****************说明*********************//
//*********输出模式接口命令,包括读主存储器30H,读保护存储器34H,读安全代码的接口命令31H***********//
//******处理模式数据接口命令,包括写主存储器38H,写保护存储器3CH,写安全代码39H,校验安全代码33H*******//

void Command(unsigned char Byte1,unsigned char Byte2,unsigned char Byte3)
{Start();
 SendData(Byte1);
 SendData(Byte2);
 SendData(Byte3);
 Stop();
}


/**********读主存储器**************/
void ReadMainMemory(unsigned char addr,unsigned char *p,unsigned char N)
{Command(0x30,addr,0xff);
 do{*p=ReceiveData();
    p++;}while(N--);
	  ResetIC();
	  
}

/************写主存储器************/
void WriteMainMemory(unsigned char Address,unsigned char *tt)
{Command(0x38,Address,*tt);
 Process();
}
/**************读安全存储器************/
void ReadSafeMemory(unsigned char *p)
{unsigned char i;
 Command(0x31,0xff,0xff);
 for(i=0;i<4;i++)
 	{*p=ReceiveData();
	 p++;}
	 ResetIC();
}

/*************写安全存储器***************/
void WriteSafeMemory(unsigned char Address,unsigned char tt)
{Command(0x39,Address,tt);//Address=0,1,2,3
 Process();
}



/**************校验密码*******************/
unsigned char VerifyPassword(unsigned char *p)
{unsigned char temp[4]={0,0,0,0};//暂存4字节保护密码;
 unsigned char i;
 ResetIC();
 ReadSafeMemory(temp);//读安全代码以取得错误计数器
 if((temp[0]&0x07)!=0)
   {
     if((temp[0]&0x07)==0x07)  i=0x06;
	   else if((temp[0]&0x07)==0x06)  i=0x04;
     else if((temp[0]&0x07)==0x04)  {i=0x00;return (0);}
	   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(1);
	}//if((temp[0]&0x07)!=0)
  return(0);
}
/*************检测是否有卡************************/
unsigned char IC_power(void)
{
	DDRE&=~0X08;       //PE3
  if((PINE&0X08)==0X00)
  {
     DelayMs(100);
     if((PINE&0X08)==0X00)
        return(1); 	
     else
        return(0);
  }
  else
     return(0);
}
/*****************************解锁写入  
************************************************************/  
void write_IC(unsigned char i)
{
    EEPROM_write(0x50,i);	
}
 /*****************************解锁读取  EEPROM地址:0x50   
************************************************************/   
void read_IC(void)
{
     IC_chok=EEPROM_read(0x50);
     if((IC_chok!=0x55)&&(IC_chok!=0xaa))//容错
       {
           IC_chok=0x55;
           write_IC(0x55);
       }
}


/*****************************区位密码读取  EEPROM地址:0x53
                                                        0x54  
************************************************************/   
unsigned int read_area(void)
{
	 unsigned int temp=0;
	 temp=EEPROM_read(0x53);
   temp=temp+(EEPROM_read(0x54)<<8);
   return (temp);
}


/*****************************区位密码写入  
************************************************************/  
void write_area(unsigned int ii)
{
	 unsigned char temp;
	 temp=(unsigned char)(ii);
   EEPROM_write(0x53,temp);	
   temp=(unsigned char)(ii>>8);
   EEPROM_write(0x54,temp);
}

/*******************************************/
//ic卡天数信息读出 地址为32/33,,一样的数
/*******************************************/ 
uchar IC_day_read(void)
{
   unsigned char *pp;	
   unsigned char temp1[2]={0,0};
   pp=&temp1[0];
   ReadMainMemory(32,pp,2);
   return (temp1[0]);
}
/*******************************************/
//ic卡天数信息写入
/*******************************************/ 
void IC_day_write(uchar DATA)
{
	 unsigned char temp0[2]={0,0};
	 unsigned char *aa;
	 unsigned char ii=0;
	 temp0[0]=DATA;
	 temp0[1]=DATA;
	 aa=&temp0[0];
   for(ii=0;ii<2;ii++,aa++)
   {
   	 WriteMainMemory(32+ii,aa); 
   }
   
   	
}
/****************读出IC卡信息(金额或区域码)***************/
unsigned int IC_information(unsigned char ADDress)
{
   unsigned int temp;
   unsigned char *pp;
   unsigned char temp1[2]={0,0};
   pp=&temp1[0];
   ReadMainMemory(ADDress,pp,2);
   temp=(unsigned int)(temp1[1]+(temp1[0]<<8));
   return (temp);
}

/****************写入IC卡信息(金额)***********************/
void WR_IC_information(unsigned int Information,unsigned char Address)
{
   unsigned char *aa;

⌨️ 快捷键说明

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