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

📄 psam.c

📁 接触式IC卡51驱动程序,适用于PSAM卡的设计,程序完全能用
💻 C
字号:
/*
**--------------文件信息------------------------------------------------------------------
**文   件   名: PSAM.c
**创   建   人: 李功周
**最后修改日期: 2008年9月9日
**描        述: 51内核7816驱动程序,KEIL C 编译
**
**--------------历史版本信息--------------------------------------------------------------
** 创建人: 李功周
** 版  本: V1.0
** 日 期: 2008年9月9日
** 描 述: 原始版
**--------------历史版本信息--------------------------------------------------------------
** 创建人: 李功周
** 版  本: V1.0
** 日 期: 2008年9月9日
** 描 述: 加入指令函数
**
*/
#include <REG54.H>
#include "PSAM.h"
#include "intrins.h"
//#include "UART\UART.h"
#define  	openclock			PSAMClock=0
#define		closeclock			PSAMClock=1
//#define		PSAMPowerEnable		PSAMPOWER=0;
//#define		PSAMPowerUEnable	PSAMPOWER=1;
#define		HALF		0
#define		FULL		1

typedef unsigned char byte;
typedef unsigned int  word;
typedef unsigned long dword;
//引脚设置
sbit	PSAMClock=P1^3;
sbit	PSAMData=P1^4;
sbit	PSAMRst=P1^7;
//sbit    PSAMPOWER=P2^6;



					    
void etutime(bit time) //etu=(372/f)=5376.3440860215053763440860215054=10752.688172043010752688172043011
{					   //2688.1720430107526881720430107527
	unsigned short	i;
	if(time)
	{
		for(i=0;i<42;i++);
		_nop_();_nop_();_nop_();		
	}
	else
	{
		for(i=0;i<18;i++);
		_nop_();_nop_();//_nop_();_nop_();		
	}
}
//取响应数据的保护时间
void SafeEtu()
{
	unsigned char i;
	for(i=0;i<17;i++)
	{
		etutime(FULL);	
	}
}
//read one byte
bit	PSAMReadOneByte(unsigned char *p)
{
	union{
			unsigned char	a;
			struct{
				unsigned char a0		:1;
				unsigned char a1		:1;
				unsigned char a2		:1;
				unsigned char a3		:1;
				unsigned char a4		:1;
				unsigned char a5		:1;
				unsigned char a6		:1;
				unsigned char a7		:1;
			}b1;
	}c1;
	unsigned short	n;
	bit	start,stop;
	n=50000;
	while(PSAMData&&(--n));
	if(n)
	{
		etutime(HALF);start=(byte)PSAMData;//0
		etutime(FULL);c1.b1.a0=(byte)PSAMData;//0
		etutime(FULL);c1.b1.a1=(byte)PSAMData;//0
		etutime(FULL);c1.b1.a2=(byte)PSAMData;//1
		etutime(FULL);c1.b1.a3=(byte)PSAMData;//1
		etutime(FULL);c1.b1.a4=(byte)PSAMData;//1
		etutime(FULL);c1.b1.a5=(byte)PSAMData;//1
		etutime(FULL);c1.b1.a6=(byte)PSAMData;//0
		etutime(FULL);c1.b1.a7=(byte)PSAMData;//0
		etutime(FULL);stop=(byte)PSAMData;
		etutime(FULL);stop=(byte)PSAMData;
		*p=c1.a;
		while(!PSAMData);
		return 1;
	}
	else return 0;
	return	1;
}
//发送一个字节
void PSAMSendOneByte(unsigned char dat)
{
	union{
			byte	a;
			struct{
				byte a0		:1;
				byte a1		:1;
				byte a2		:1;
				byte a3		:1;
				byte a4		:1;
				byte a5		:1;
				byte a6		:1;
				byte a7		:1;
			}b1;
	}c1;
	bit  parity;
	c1.a=dat;
	parity=0;
	if(c1.b1.a0)parity=~parity;
	if(c1.b1.a1)parity=~parity;
	if(c1.b1.a2)parity=~parity;
	if(c1.b1.a3)parity=~parity;
	if(c1.b1.a4)parity=~parity;
	if(c1.b1.a5)parity=~parity;
	if(c1.b1.a6)parity=~parity;
	if(c1.b1.a7)parity=~parity;

//	EA = 0 ;
		PSAMData=0;etutime(FULL);
		PSAMData=c1.b1.a0;etutime(FULL);
		PSAMData=c1.b1.a1;etutime(FULL);
		PSAMData=c1.b1.a2;etutime(FULL);
		PSAMData=c1.b1.a3;etutime(FULL);
		PSAMData=c1.b1.a4;etutime(FULL);
		PSAMData=c1.b1.a5;etutime(FULL);
		PSAMData=c1.b1.a6;etutime(FULL);
		PSAMData=c1.b1.a7;etutime(FULL);
		PSAMData=parity;etutime(FULL);
		PSAMData=1;etutime(FULL);
//	EA = 1;
}
//读数据串
unsigned char ReadData(unsigned char *p,unsigned char len)
{
	unsigned char i;
//	EA = 0 ;
	for(i=0;i<len;i++)
	{
		if(PSAMReadOneByte(&p[i])==0)return i;	
	}
//	EA = 1 ;
	return i;
}

//读取复应答  1成功,0失败
bit ReadATR()
{
	unsigned char idata aa[20];
	unsigned char i;
	EA = 0 ;
	if(ReadData(aa,4)<4)
	{	
		EA = 1;
		return 0;
	}
	i = aa[1]&0x0f;
	if(ReadData(&aa[4],i)<i)
	{
		EA = 1;
		return 0;
	}
	EA = 1 ;
	return 1;	
}
//发送指令
unsigned short SendCmd(	unsigned char CLA,
						unsigned char INS,
						unsigned char P1,
						unsigned char P2,
						unsigned char Lc,
						unsigned char Le,
						unsigned char *DATA,
						unsigned char RLen
						)
{
	unsigned char i;
	unsigned char a;
	EA = 0 ;
	PSAMSendOneByte(CLA);
	PSAMSendOneByte(INS);
	PSAMSendOneByte(P1);
	PSAMSendOneByte(P2);
	if(Lc!=0)
	{	
		PSAMSendOneByte(Lc);
		if(ReadData(&a,1)!=1)
		{
			EA = 1;
			return 0;	
		}
		SafeEtu();
		for( i = 0 ; i < Lc ; i++ )
		{
			PSAMSendOneByte(DATA[i]);	
		}
		if(Le==0)
		{
			i = ReadData(DATA,RLen);
			EA = 1;
			return (unsigned short)DATA[i-2]*0x100+DATA[i-1];
		}
	}
	if(Le!=0)
	{
		PSAMSendOneByte(Le);
		if(Lc==0)
		{
			if(ReadData(&a,1)!=1)
			{
				EA = 1;
				return 0;	
			}
		}
		i = ReadData(DATA,RLen+2);
//		SendStr(DATA,i);
		EA = 1;
		return (unsigned short)DATA[i-2]*0x100+DATA[i-1];
	}
	if((Lc==0)&&(Lc==0))
	{
		PSAMSendOneByte(0);
		i = ReadData(DATA,3);
		EA = 1;
		return (unsigned short)DATA[i-2]*0x100+DATA[i-1]; 	
	}
	EA = 1;				
}

//发送指令
unsigned short SendCmd1(	unsigned char CLA,
						unsigned char INS,
						unsigned char P1,
						unsigned char P2,
						unsigned char Lc,
						unsigned char Le,
						unsigned char *DATA,
						unsigned char RLen
						)
{
	unsigned char i;
	unsigned char a;
	EA = 0 ;
	SafeEtu();
	PSAMSendOneByte(CLA);
	PSAMSendOneByte(INS);
	PSAMSendOneByte(P1);
	PSAMSendOneByte(P2);
	PSAMSendOneByte(Lc);
	if(ReadData(&a,1)!=1)
	{
		EA = 1;
		return 0;	
	}
		SafeEtu();
	for( i = 0 ; i < Lc ; i++ )
	{
		PSAMSendOneByte(DATA[i]);	
	}
	Le = Le;
//	PSAMSendOneByte(Le);
	i = ReadData(DATA,RLen+2);
//	SendStr(DATA,i);
	EA = 1 ;
	return (unsigned short)DATA[i-2]*0x100+DATA[i-1];				
}
//取响应数据
unsigned short GetResponse(unsigned char *p,unsigned char len)
{
	unsigned char i,a;
	EA = 0 ;
	SafeEtu();
	PSAMSendOneByte(0x00);	
	PSAMSendOneByte(0xc0);
	PSAMSendOneByte(0x00);
	PSAMSendOneByte(0x00);
	PSAMSendOneByte(len);
	if(ReadData(&a,1)!=1)
	{
		EA = 1;
		return 0;	
	}
	EA = 1 ;
	i = ReadData(p,len+2);
	return (unsigned short)p[i-2]*0x100+p[i-1]; 
}	
//PSAM卡初始化	   应答:3B 6C 00 02 13 02 86 38 18 43 56 07 1E 10 2B 23
unsigned char PSAMInit()//
{
	bit a=1;
	unsigned char i;
	closeclock;
	PSAMRst=0;
	PSAMData=1;
	closeclock;
	for(i=0;i<50;i++)
	{
		etutime(FULL);	
	}
	openclock;
	for(i=0;i<50;i++)
	{
		etutime(FULL);	
	}
	PSAMRst = 1 ;
	if(ReadATR())
	{
		return 0;
	}
//	i = ReadData(aa,16);					//3b 6c 00 02 13 62 86 38 18 43 56 07 1e 10 2d 23 
//	SendStr(aa,i);							//3B 6C 00 02 13 62 86 38 18 43 56 07 1E 10 2D 23
	else
	{
		PSAMReadOneByte("1");
		ReadData("1",1);
		//发送指令
		SendCmd(1,1,1,1,1,1,"1",1);
		return 1;		
	}
}		

⌨️ 快捷键说明

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