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

📄 cpu_com.c

📁 keil下ISO7816规则的APDU程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//#include "type.h"
#include "reg51.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "INTRINS.H"
#include "CPU_COM.h"
unsigned char xdata OutData[255] _at_ 0x0200;
void main()
{          
	unsigned char idata pATR[1],InData[32]={0x05,0xAA,0x55,0x00,0x00,0x08};
	unsigned char ndata[2] = {0xAA,0x55};
	//unsigned char idata OutData[64];
	
	PLY_APDU();
	Inttime0();					//定时器0初始化
	com_Open();					//打开串口
//	SendCom()
	//cpu_Open();					//CPU卡上电并读ATR并把ATR通过串口发送,如果读ATR错误则输出FF
//	ICC_INS(&InData[1],OutData,*InData);
//	SendChar(0x36);
			//ICC_INS:输入数据指针*InData,输入数据长度lnin,输出数据指针*OutData,输出数据长度为*OutData
//	if (ICC_INS(&InData[1],OutData,*InData)!=TRUE)
//	{
//		OutData[0] = 1;
//  	OutData[1] = 0xff;
//	}
	while(1)
	{
		//SendCom(2,&InData[1]);
		if(readCom(InData) == TRUE)
		{
			if(!memcmp(ndata,InData+1,2))
			{
				SendCom(2,"OK");	
				break;
			}
			else
				SendCom(2,"ER");
		}
		else
			SendCom(2,"ER");
	}
	ndata[0]=0xaa;		
	while(1)
	{
		if(readCom(InData) == TRUE)
		{
			if(*InData == 1)
				continue;
		 	else
			{
				if (ICC_INS(&InData[1],*InData)!=TRUE)
				{
					OutData[0] = 1;
                   	OutData[1]=0xff;
				}
//				Extra_guardtime_N = Extra_guardtime_N_bak;
              	//if(OutData[0]<=64)
              		SendCom(OutData[0],&OutData[1]);
				//else
					//SendCom((OutData[0]-64),OutData1);
		  	}
		}
		else
		{
			OutData[0] = 1;
          	OutData[1]=0xff;
			SendCom(OutData[0],&OutData[1]);
		}

	}

}
//=============初始化定时器================================
void Inttime0()
{
	TMOD|=0x02;							/*定时器0为模式2(8位自动重装) */
	TR0=0;								//在发送或接收才开始使用
	TF0=0; 								//清定时器溢出标志
	TH0=0XA0; 							//9600是1000000/9600=104.167微秒104.167*11.0592/12=96  (256-96=0XA0)
	TL0=TH0;		
	ET0=1;								//开定时器中断
	EA=1;								//开CPU中断
}
//=========================================================
//=============定时器中断子程序============================
void IntTimer0() interrupt 1
{
	F_TM=1;								//定时器溢出引起中断,置标志位
}
//=========================================================
//=============发送一个字符传入发送数据返回是否发送正确====
//=============返回错误时则启用释放终端====================
unsigned char SendChar(unsigned char ch)
{
   	unsigned char i = 0,bak;			//p为1的个数
	unsigned char idata b=0;
	bit a = 0;
	//bak = ch;
	if(CPUCD_Format != 0)
		ch = ~ch;
	bak = ch;
	if(CPUCD_Format == 0)
	{
		F_TM=0;   						//关中断标志
start:
		BT_SND = 0; 					//发送起始位
		TH0 = 0xB6;
		TL0 = 0xB6;
		TR0 = 1;
		//TIMER0_ENABLE; 				//启动定时器
		while(!F_TM); 					//检测到中断标志后开始发送一个字符(8位)
		while(i<8)
  		{
			if(ch&1)
      		{
      			BT_SND = 1;
          		a=(~a);
      		}
      		else
      		{
      			BT_SND = 0;
				a = a; 
      		}
			TH0 = 0xBF;
			TIMER0_ENABLE;
			F_TM=0;						//发送一位之后关标志准备发送下一位
			while(!F_TM);
    		i++;
    		ch>>=1;
		}								//结束位(9+0.268)etu~(10+0.098)etu
		if(a)
		{
			BT_SND = 1; 				//数据位1的个数为偶数则发送0保证数据位和效验1的个数为偶数
		}
		else
		{
			BT_SND = 0;  				//数据位1的个数为奇数则发送1保证数据位和效验1的个数为偶数
		}
		TH0 = 0xAD;
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM);
		//上面是起始+8位数据+1位校验	//(10+0.098)etu
		BT_SND = 1;
		TH0 = 0xB2;
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM);

		TH0 = 0xA5;
		TIMER0_ENABLE;					//(11+0.135)etu   11etu处检测
		if(BT_SND == 0)					//如果IC卡有误
		{
			if(b == 4)
				return FALSE;
			F_TM=0;
			while(!F_TM);
//			BT_SND = 1;
			F_TM=0;
			while(!F_TM);
			F_TM=0;
//			TH0 = 0xFF;
//			TIMER0_ENABLE;					//(11+0.135)etu   11etu处检测
			i = 0;
			b++;
			ch = bak;
	 		goto start;
   		}
		TH0 = 0xB4;
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM);
 	    for(i=0;i<Extra_guardtime_N;i++)
		{	
			TH0 = 0xB6;
			TIMER0_ENABLE;
			F_TM=0;
			while(!F_TM);
		}
		TIMER0_DISABLE; 				//停止定时器
		return TRUE;
	}
	else
	{
		F_TM=0;   						//关中断标志
start1:
		BT_SND = 0; 					//发送起始位
		TH0 = 0x54;
		TL0 = 0x54;
		TR0 = 1;
		//TIMER0_ENABLE; 				//启动定时器
		while(!F_TM); 					//检测到中断标志后开始发送一个字符(8位)
		while(i<8)
  		{
			if(ch&0x80)
      		{
      			BT_SND = 1;
          		a=(~a);
      		}
      		else
      		{
      			BT_SND = 0;
				a = a;
      		}
			TH0 = 0x5F;
			TIMER0_ENABLE;
			F_TM=0;						//发送一位之后关标志准备发送下一位
			while(!F_TM);
    		i++;
    		ch<<=1;
		}								//结束位(9+0.268)etu~(10+0.098)etu
		if(a)
		{
			BT_SND = 0; 				//数据位1的个数为偶数则发送0保证数据位和效验1的个数为偶数
		}
		else
		{
			BT_SND = 1;  				//数据位1的个数为奇数则发送1保证数据位和效验1的个数为偶数
		}
		TH0 = 0x4E;
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM);
						//(10+0.098)etu
		BT_SND = 1;
		TH0 = 0x51;
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM);

		TH0 = 0x43;
		TIMER0_ENABLE;					//(11+0.135)etu
		if(BT_SND == 0)					//如果IC卡有误
		{
			if(b == 4)
				return FALSE;
			F_TM=0;
			while(!F_TM);
			F_TM=0;
			while(!F_TM);
//			TH0 = 0x45;
//			TIMER0_ENABLE;					//(11+0.135)etu   11etu处检测
			b++;
			ch = bak;
			goto start1;
   		}
		TH0 = 0x55;
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM);
 	    for(i=0;i<Extra_guardtime_N;i++)
		{	
			TH0 = 0x57;
			TIMER0_ENABLE;
			F_TM=0;
			while(!F_TM);
		}
		TIMER0_DISABLE; 				//停止定时器
		return TRUE;
	}
}
//=======================================================================
/*===接收一个字符(*ndata)返回如果为FALSE表示数据和校验位不符合将口线拉低后
//等待两个ETU后从新接收,但不包括接收ATR
FALSE1表示超时============================TRUE则成功==========*/
unsigned char GetChar(unsigned char *ndata1)
{   
	unsigned char i = 0,ch = 0,b = 0;//,a1;		//i:位计数,ch:接收的字符存储位置
    unsigned char idata count = 0;		//超时计数器
	unsigned int  idata count1 = 0;
	bit a = 0,a1 = 0;
	if(CPUCD_Format == 0)
	{
statr:
    	while(BT_REC)					//等待开始位
		{
			count++;
			if(count == 0xFF)
			{
//				count = 0;
				count1++;
				if(count1 == 0x0415)
				{
//					if(tc2 == 0)
						return FALSE1;			//等待起始位超时
//				 	else
//					{
//						count1 = 0;
//				  		tc2 = tc2-1;
//				  	}
				}
		   	}
			
		}

/*----接收一个字节的数据-----*/
		//TIMER0_ENABLE;				//启动定时器
		for(i=0;i<=1;i++);
		TH0 = 0x8F;
		TL0 = 0x8F;
//		TH0 = 0xA0;
//		TL0 = 0xA0;
		TR0 = 1;
		//TH0 = 0x9;
		//TH0=0XB0;
		//F_TM = 0;
    	while(i<10)
  		{
      		F_TM = 0; 
			while(!F_TM);				//等待溢出准备接收一个字节的数据
			ch>>=1;
        	if(BT_REC)
        	{	
				TH0 = 0xB2;
				TIMER0_ENABLE;
       			ch|=0x80;
           		a = (~a);
        	}
			else
			{
				TH0 = 0xB2;
				TIMER0_ENABLE;
				ch = ch;
				a = a;
			}
        	i++;
     	}
		//TH0=0XB0;
		//TIMER0_ENABLE;
		F_TM = 0; 
		while(!F_TM);					//等待溢出准备接收一个字节的数据
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		if(BT_REC)
			a1 = 1;
		else
			a1 = 0;
		TH0 = 0xB3; 
		TIMER0_ENABLE;
		F_TM = 0; 
		while(!F_TM);					//等待溢出准备接收一个字节的数据
  		if(a1!=a)
    	{	
			//TIMER0_DISABLE ;			//停止定时器
    		BT_REC = 0;					//10.5etu
			if(b == 4)
				return FALSE;
			b++;
			F_TM = 0; 
			while(!F_TM);				//等待溢出准备接收一个字节的数据
			F_TM = 0; 
			TH0 = 0xAE;
			TIMER0_ENABLE
			while(!F_TM);				//等待溢出准备接收一个字节的数据
			BT_REC = 1;
//			F_TM = 0;
//			TL0 = 0xF0;
//			while(!F_TM);				//等待溢出准备接收一个字节的数据
			//BT_REC =1;
			goto statr;					//接收数据发生错误
		}
		else
		{
			TR0=0;
    		*ndata1 = ch;					//将接收的数据以ndata指针返回 
			//BT_REC=1;
	 	}
   		return TRUE;					//正确接送数据
  	}
	else
	{
stara1:
    	while(BT_REC)					//等待开始位
		{
			count++;
			if(count == 0xFF)
			{
//				count = 0;
				count1++;
				if(count1 == 0x0430)
				{
					if(tc2 == 0)
						return FALSE1;			//等待起始位超时
				  	else
					{
			  			tc2--;
						count1 = 0;
				 	}
				}
		   	}
			
		}

/*----接收一个字节的数据-----*/
		//TIMER0_ENABLE;				//启动定时器
		for(i=0;i<=1;i++);
		TH0 = 0x00;
		TL0 = 0x00;
		TR0 = 1;
		//TH0 = 0x9;
		//TH0=0XB0;
		//F_TM = 0;
    	while(i<10)
  		{
      		F_TM = 0; 
			while(!F_TM);				//等待溢出准备接收一个字节的数据
			ch<<=1;
        	if(BT_REC)
        	{	
				TH0 = 0x50;
				TIMER0_ENABLE;
       			ch|=1;
           		a = (~a);
        	}
			else
			{	
				TH0 = 0x50;
				TIMER0_ENABLE;
				ch = ch;
				a = a;
			}
//			TH0=0XB4;
//			TIMER0_ENABLE;
        	i++;
     	}
		//TH0=0XB0;
		//TIMER0_ENABLE;
		F_TM = 0; 
		while(!F_TM);					//等待溢出准备接收一个字节的数据
		if(BT_REC)
			a1 = 1;
		else
			a1 = 0;
		TH0 = 0x50; 
		TIMER0_ENABLE;
		F_TM = 0; 
		while(!F_TM);					//等待溢出准备接收一个字节的数据
  		if(a1!=a)
    	{	
			//TIMER0_DISABLE ;			//停止定时器
    		BT_REC = 0;					//10.5etu
			if(b == 4)
				return FALSE;
			b++;
			F_TM = 0; 
			while(!F_TM);				//等待溢出准备接收一个字节的数据
			F_TM = 0; 
			while(!F_TM);				//等待溢出准备接收一个字节的数据
			BT_REC = 1;
//			F_TM = 0;
//			TL0 = 0xF0;
//			while(!F_TM);				//等待溢出准备接收一个字节的数据
			//BT_REC =1;
			goto stara1;				//接收数据发生错误
		}
		else
		{
			TR0 = 0;;
    		*ndata1 = ~ch;					//将接收的数据以ndata指针返回 
			//BT_REC=1;
	   	}
   		return TRUE;
	}
}
//触点激活子程序冷复位
/*///KTD1101
/*小机器
unsigned char cpu_Open(void)

⌨️ 快捷键说明

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