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

📄 card_pro.c

📁 一些经常用到的单片机底层驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	for(i=0;i<5;i++)	buf[i]=out_buf[i];
	if(!lc)	//只读数据
	{
		le=out_buf[7];
		buf[4]=le;
	}
	
	lout=le;
	ins=buf[1];

	pp=(uchar*)&out_buf[5];
	out=*pp;
	pp=(uchar*)&in_buf[1];
	in=*pp;
   
	bw.word=0;
	while(1)
	{
		if(!send_flag)	//发送命令
		{
			send_flag=1;
			//if(testbuf[0]==0xaa)send_str(5,buf);
			for(i=0;i<5;i++)
			{
				error=send_sam_byte(buf[i]);
				if(error)	//奇偶错
				{
					EA=1;
					return error;
				}
			}
		}
		
		error=rece_sam_byte();	//读ACK1
		//if(testbuf[0]==0xaa){send_char(r_w_byte);} //A4 61 C0 90 A4 61 C0 90 B0 
		if(error)
		{
			EA=1;
			return error;
		}
		bw.byte.Hi=r_w_byte;
		if(r_w_byte==0x60)	continue;	//CPU卡忙
		
		if(((r_w_byte&0xf0)==0x60)||((r_w_byte&0xf0)==0x90))	//此时SW1=ACK1
		{
			error=rece_sam_byte();	//读SW2
		    //if(testbuf[0]==0xaa)send_char(r_w_byte);
			if(error)
			{
				EA=1;
				return error;
			}
			bw.byte.Lo=r_w_byte;
			send_flag=0;
			if(bw.byte.Hi==0x61)	//lc,le同时有效 获得回应的数据
			{//读取数据长度与文件实际长度不匹配,重发
				buf[0]=0;
				buf[1]=0xc0;
				buf[2]=0;
				buf[3]=0;
				buf[4]=r_w_byte;
				le=r_w_byte;
				lout=le;
				ins=buf[1];
				
				continue;
			}
			else if(bw.byte.Hi==0x6c)	//没有lc时有效
			{//读取剩余数据
				buf[4]=r_w_byte;
				le=r_w_byte;
				lout=le;
				continue;
			}
			else
			{
				if(lout==le)	lout=0;	//没有读取到数据
				in_buf[0]=lout;
				in_buf[3]=bw.byte.Hi;
				in_buf[4]=bw.byte.Lo;
				//send_str(10,in_buf);//0C 06 72 90 00  
				EA=1;
				return 0;
			}
		}//SW1,SW2--0x60-0x9f
		
		if(r_w_byte==ins)	//命令完成,可以传输数据块
		{
           // card_vcc(1);
			if(lc)	//写数据
			{
				do
				{
                   //if(testbuf[0]==0xaa)send_char(*out);
					error=send_sam_byte(*out);
					if(error)	//奇偶错
					{
						EA=1;
						return error;
					}
					out++;
				}while(--lc);
				continue;
			}
			else if(le)	//读本记录的有效存储数据
			{
				do
				{
					error=rece_sam_byte();	//读数据
					//if(testbuf[0]==0xaa)send_char(r_w_byte);
					if(error)
					{
						EA=1;
						return error;
					}
					delay_half_etu();
					*in=r_w_byte;
					in++;
				}while(--le);
				
				continue;
			}
			continue;
		}//SW1==ins
		
		r_w_byte=~r_w_byte;
		if(r_w_byte==ins)	//命令完成,只可以传输单字节数据
		{
			if(lc)	//写数据
			{
				error=send_sam_byte(*out);
				if(error)	//奇偶错
				{
					EA=1;
					return error;
				}
				out++;
				--lc;
				continue;
			}
			else if(le)	//读1字节本记录的有效存储数据
			{
				error=rece_sam_byte();	//读数据
				if(error)
				{
					EA=1;
					return error;
				}
				delay_half_etu();
				*in=r_w_byte;
				in++;
				--le;
				continue;
			}
			continue;
		}//SW1==/ins
		ins++;
		if(r_w_byte==ins)	//卡类型错
		{
			EA=1;
			return 1;
		}//SW1==/(ins+1)
		r_w_byte=~r_w_byte;
		if(r_w_byte==ins)	//卡类型错
		{
			EA=1;
			return 1;
		}//SW1==ins+1;
		else	//通信出错
		{
			EA=1;
			return 1;
		}
	}//while(1)
}
//===============================================================================
uchar  Cpu_Apdu(uchar xdata *out_buf,uchar xdata *in_buf)
{
	uchar	data ins;
	uchar	i,lc,le,lout,error,send_flag=0;
	uchar	xdata buf[10];
	uchar   xdata *out,*in;
	uchar   xdata **pp;
	//uchar  xdata r_w_byte=0;
	UNST	bw;

    EA=0;
	card_vcc(1);
	le=0;
	lc=out_buf[4];
	for(i=0;i<5;i++)	buf[i]=out_buf[i];
	if(!lc)	//只读数据
	{
		le=out_buf[7];
		buf[4]=le;
	}
	lout=le;
	ins=buf[1];
	
	pp=(uchar *)&out_buf[5];
	out=*pp;
	pp=(uchar *)&in_buf[1];
	in=*pp;

	bw.word=0;
	while(1)
	{
		if(!send_flag)	//发送命令
		{
			send_flag=1;
            //if(testbuf[0]==0xaa)send_str(5,buf);
			for(i=0;i<5;i++)
			{
				error=send_cpu_byte(buf[i]);
				if(error)	//奇偶错
				{
					EA=1;
					return error;
				}
			}
		}
		
		error=rece_cpu_byte();	//读ACK1
	    //if(testbuf[0]==0xaa)send_char(r_w_byte); 
		if(error)                       
		{                             // E4 61 04 C0 00 19 
			EA=1;
			return error;
		}
		bw.byte.Hi=r_w_byte;
		if(r_w_byte==0x60)	continue;	//CPU卡忙
		
		if(((r_w_byte&0xf0)==0x60)||((r_w_byte&0xf0)==0x90))	//此时SW1=ACK1
		{
			error=rece_cpu_byte();	//读SW2
			//if(testbuf[0]==0xaa){send_char(bw.byte.Hi);send_char(r_w_byte); }
			if(error)
			{
				EA=1;
				return error;
			}
			bw.byte.Lo=r_w_byte;
			send_flag=0;
			if(bw.byte.Hi==0x61)	//lc,le同时有效 从CPU卡取响应数据 与
			                        //uchar GetResponse(uchar which_card, uchar len, uchar *content)
									//作用相同
			{//读取数据长度与文件实际长度不匹配,重发
				buf[0]=0;
				buf[1]=0xc0;
				buf[2]=0;
				buf[3]=0;
				buf[4]=r_w_byte;
				le=r_w_byte;
				lout=le;
				ins=buf[1];
				continue;
			}
			else if(bw.byte.Hi==0x6c)	//没有lc时有效
			{//读取剩余数据
				buf[4]=r_w_byte;
				le=r_w_byte;
				lout=le;
				continue;
			}
			else
			{
				if(lout==le)	lout=0;	//没有读取到数据
				in_buf[0]=lout;
				//if(testbuf[0]==0xaa)send_char(in_buf[0]);
				in_buf[3]=bw.byte.Hi;
				in_buf[4]=bw.byte.Lo;
				EA=1;
				return 0;
			}
		}//SW1,SW2--0x60-0x9f
		if(r_w_byte==ins)	//命令完成,可以传输数据块
		{
			if(lc)	//写数据
			{
				do
				{
				   //if(testbuf[0]==0xaa)send_char(*out);
					error=send_cpu_byte(*out);
					if(error)	//奇偶错
					{
						EA=1;
						return error;
					}
					out++;
				}while(--lc);
				continue;
			}
			else if(le)	//读本记录的有效存储数据
			{
			    
				do
				{
					error=rece_cpu_byte();	//读数据
					if(error)
					{
						EA=1;
						return error;
					}
					delay_half_etu();
					*in=r_w_byte;
					in++;
					
				}while(--le);
				continue;
			}
			continue;
		}//SW1==ins
		
		r_w_byte=~r_w_byte;
		if(r_w_byte==ins)	//命令完成,只可以传输单字节数据
		{
			if(lc)	//写数据
			{
				error=send_cpu_byte(*out);
				if(error)	//奇偶错
				{
					EA=1;
					return error;
				}
				out++;
				--lc;
				continue;
			}
			else if(le)	//读1字节本记录的有效存储数据
			{
				error=rece_cpu_byte();	//读数据
				if(error)
				{
					EA=1;
					return error;
				}
				delay_half_etu();
				*in=r_w_byte;
				in++;
				--le;
				continue;
			}
			continue;
		}//SW1==/ins
		ins++;
		if(r_w_byte==ins)	//卡类型错
		{
			EA=1;
			return 1;
		}//SW1==/(ins+1)
		r_w_byte=~r_w_byte;
		if(r_w_byte==ins)	//卡类型错
		{
			EA=1;
			return 1;
		}//SW1==ins+1;
		else	//通信出错
		{
			EA=1;
			return 1;
		}
	}//while(1)
}


//=========================================================
// 函 数 名:card_send_cmd
//
//
//
    //*buf_cmd --
    //length   --

//
    //rbuf
    //*len_r
// 返 回 值:0--成功;

//=========================================================
/*uchar card_send_cmd(uchar card_type,uchar xdata *buf_cmd)
                
{
	uchar xdata out_bufdata[8];
	uchar xdata in_bufdata[5];
	uchar xdata *len_r;
	uchar xdata *rbuf;
	uchar  x;
	memcpy(out_bufdata,buf_cmd+3,5);

	out_bufdata[5]=(uchar)((uint)&buf_cmd[8]>>8);  //cpu输出
	out_bufdata[6]=(uchar)(&buf_cmd[8]);
	out_bufdata[7]=buf_cmd[5+buf_cmd[7]];
  
  
	in_bufdata[0]=0;
	in_bufdata[1]=(uchar)((uint)&rbuf[0]>>8);
	in_bufdata[2]=(uchar)(&rbuf[0]);
	in_bufdata[3]=0;
	in_bufdata[4]=0;
	if(card_type==0)   //税控卡
	{   x=Sam_Apdu(out_bufdata,in_bufdata);
		if(x)
		{//send_char(x);
        	return 1;
		}
       //send_str(5,in_buf);
	}
  	else 
	{
		if(Cpu_Apdu(out_bufdata,in_bufdata))
        return 1;
		//send_str(5,in_buf);
	}
  
	*len_r=in_bufdata[0]+2;
	rbuf[in_bufdata[0]]=in_bufdata[3];
	rbuf[in_bufdata[0]+1]=in_bufdata[4];
	//send_str(10,rbuf);
  
	if(*len_r>2)
    {
		memcpy(buf_cmd+3,rbuf+1,in_bufdata[0]);
		buf_cmd[1]=in_bufdata[0];
	}
	buf_cmd[in_bufdata[0]+3]=0x90;
	buf_cmd[in_bufdata[0]+4]=0x0;
	return 0;
}*/
//=================================================================================
uchar card_send_cmd(unsigned char card_type,const unsigned char xdata *buf_cmd,
                unsigned char *len_r,unsigned char xdata *rbuf)
{
	uchar out_buf[8];
	uchar in_buf[5];
  
	memcpy(out_buf,buf_cmd,5);

	out_buf[5]=(uchar)((uint)&buf_cmd[5]>>8);
	out_buf[6]=(uchar)(&buf_cmd[5]);
	out_buf[7]=buf_cmd[5+buf_cmd[4]];
  
	in_buf[0]=0;
	in_buf[1]=(uchar)((uint)&rbuf[0]>>8);//指向*rbuf 的地址 UINT 型
	in_buf[2]=(uchar)(&rbuf[0]);
	in_buf[3]=0;
	in_buf[4]=0;
  
	if(card_type==0)
	{ 
		if(Sam_Apdu(out_buf,in_buf))
        	return 1;
		//send_str(5,in_buf);
	}
	else 
	{
		if(Cpu_Apdu(out_buf,in_buf))
        	return 1;
		//send_str(5,in_buf);
	}
  
	*len_r=in_buf[0]+2;
	//if(testbuf[0]==0xaa)send_char(*len_r);
	rbuf[in_buf[0]]=in_buf[3];  //sw1
	rbuf[in_buf[0]+1]=in_buf[4];//sw2

	return 0;
}

//=================================================================================
uchar id_iso(uchar xdata *ptr)
{
	if(Card_coumm(1,ptr))
		return 1;
		
	return 0;
}

//================================================================================
uchar sam_iso(uchar xdata *ptr)
{
	if(Card_coumm(0,ptr))
		return 1;
		
	return 0;
}
//===================================================================================
uchar Card_coumm(uchar card_type,uchar *cmdbuf)
{
	uchar i;
	uchar len_r;
	uint error;
	uchar xdata buf_cmd[300];
	uchar xdata buf_r[300]; 
	//write_data_flg=1;
	len_r = cmdbuf[cmdbuf[1]+1];
	if(cmdbuf[1]<9)       //补成统一格式
	{
    	i=9-cmdbuf[1];
    	cmdbuf[10]=cmdbuf[cmdbuf[1]+1];
		for(len_r=0;len_r<i;len_r++)cmdbuf[cmdbuf[1]+1+len_r]=0;
    }

	for(i=0;i<4;i++)
		buf_cmd[i]=cmdbuf[i+3];

	if(cmdbuf[7])
	{
    	buf_cmd[4]=cmdbuf[7];
		memcpy(&buf_cmd[5], cmdbuf+8, cmdbuf[7]);

		//if(cmdbuf[10])
		//buf_cmd[5+cmdbuf[7]]=cmdbuf[10];
		if(cmdbuf[buf_cmd[4]+8])
			buf_cmd[5+cmdbuf[7]]=cmdbuf[buf_cmd[4]+8];
     
		//if(testbuf[0]==0xcc){send_str2(77,buf_cmd);while(1);}
		//len = gst_apdu.lc+5;
	}
	else//此时必有le不等于0
	{
    	buf_cmd[4]=cmdbuf[7];
    	buf_cmd[5]=cmdbuf[10];
	}
  
	/*if(cmdbuf[1]<10)
	len_r = cmdbuf[10]+2;
	else  len_r = cmdbuf[cmdbuf[1]+1];//注册命令
	*/
	if(low_pwr==1) {shut_bat(0);}
	error = card_send_cmd(card_type,buf_cmd,&len_r,buf_r);
	if(error) 
	{
		//write_data_flg=0;  
		return error;
	}
	cmdbuf[1]=len_r-2;
	//if(testbuf[0]==0xaa)send_char(cmdbuf[1]);
	cmdbuf[len_r+1]=buf_r[len_r-2];
	cmdbuf[len_r+2]=buf_r[len_r-1];

	if(len_r>2)
	{
		memcpy(cmdbuf+3,buf_r,(len_r-2));
	}
	// write_data_flg=0;
	return 0;
}
//================================================================================
uchar atr_cupcard(uchar xdata *ptr)
{
    char	xdata i,temp,atr_len,error,cpu_tck=0,ti=0;
	uchar xdata *p;
	uint  j=10000;
	UNST	bw;
	atr_len=0;
	p=ptr;
	bw.word=0;

    card_vcc(1);
	cpu_ta1=0x11,cpu_d=1,cpu_tc1=0,cpu_tc2=10;
	EA=0;
	Writ_cpld(Sm_rst,0);
	
	do	//等待起始位
	{
		if(!IC_CARD_IO)	break;
	}while(j--);
	
	Writ_cpld(Sm_rst,1);
	
    cpu_t=1;	//以正向协议传输
	if(rece_cpu_byte())	//TS
	{
		EA=1;
		bw.byte.Lo=1;	//非CPU卡
		return bw.word;
	}
	
	if(r_w_byte==0x03)	//反向传输
	{
		cpu_t=0;
		r_w_byte=0x3f;
	}
	else if(r_w_byte!=0x3b)	//正向传输
	{
		EA=1;
		bw.byte.Lo=1;	//非CPU卡
		return bw.word;
	}
	*p=r_w_byte;
	p++;
	atr_len++;
	
	error=rece_cpu_byte();	//接收T0
	if(error)
	{
		bw.byte.Lo=error;
		EA=1;
		return bw.word;
	}
	*p=r_w_byte;
	p++;
	atr_len++;
	bw.byte.Hi=r_w_byte&0x0f;	//保存历史字节数据长度
	if((r_w_byte&0x0f)>32)	//历史字节数据超长出错
	{
		EA=1;
		bw.byte.Lo=1;
		return bw.word;
	}
	
atr_cpu1:
	temp=r_w_byte>>4;
	i=4;
	do	//Td1...Tdi
	{
		if(temp&0x01)
		{
			error=rece_cpu_byte();
			if(error)
			{
				bw.byte.Lo=error;
				EA=1;
				return bw.word;
			}
			*p=r_w_byte;
			p++;
			atr_len++;
			if(atr_len==32)	//数据超长出错
			{
				EA=1;
				bw.byte.Lo=1;
				return bw.word;
			}
			if(i==4)	//TAi
			{
				if(!ti)	cpu_ta1=r_w_byte;	//TA1决定接收字符间最大时间
				else if(ti==1)	cpu_tck=1;	//TA2...N表示有TCK校验

⌨️ 快捷键说明

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