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

📄 card_pro.c

📁 一些经常用到的单片机底层驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
#include  "include.h"

//sbit check_paper=P3^3;
sbit IC_CARD_IO=P4^1;     //用户卡的I/O
sbit SAM_CARD_IO=P1^0;    //SAM卡的I/O

#define BUZZ      P1_1
#define MAXPAGE   2048		//flash card 最大页数
#define MAXBYTE   264		//flash card 每页最大字节数
#define RW_FLASH_CARD	    //是否编译FLASH CARD 的相关程序

/*********************定义FLASH CARD的硬件接口模式******************/
//#define	SPI_MODE0	//select transmit mode
//#define	SPI_MODE3
#define	        POLARITY_LOW
//#define	POLARITY_HIGH

/*********************定义FLASH CARD的存储交换模式******************/
#define	FLASH_BUFFER
//#define	FLASH_PAGE
//#define	FLASH_ARRAY		//select read mode 

/*******************选择FLASH CARD交换缓冲区*****************/
#define	FLASH_BUFFER1	//select buffer1 or buffer2

#ifdef SPI_MODE0
	#define ARRAY_READ_COM	0xe8	//直接阵列方式读主存储区数据
	#define PAGE_READ_COM	0xd2	//直接页方式读主存储区数据
	#define STATUS_READ_COM	0xd7	//读FLASH CARD 状态
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0xd4	//从FLASH CARD缓冲区读数据
	#else
		#define BUFFER_READ_COM	0xd6
	#endif	//FLASH_BUFFER1
#endif

#ifdef SPI_MODE3
	#define	HIGH
	#define ARRAY_READ_COM	0xe8
	#define PAGE_READ_COM	0xd2
	#define STATUS_READ_COM	0xd7
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0xd4
	#else
		#define BUFFER_READ_COM	0xd6
	#endif	//FLASH_BUFFER1
#endif

#ifdef POLARITY_LOW
	#define ARRAY_READ_COM	0x68
	#define PAGE_READ_COM	0x52
	#define STATUS_READ_COM	0x57
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0x54
	#else
		#define BUFFER_READ_COM	0x56
	#endif	//FLASH_BUFFER1
#endif

#ifdef POLARITY_HIGH
	#define	HIGH
	#define ARRAY_READ_COM	0x68
	#define PAGE_READ_COM	0x52
	#define STATUS_READ_COM	0x57
	#ifdef	FLASH_BUFFER1
		#define BUFFER_READ_COM	0x54
	#else
		#define BUFFER_READ_COM	0x56
	#endif	//FLASH_BUFFER1
#endif

#ifdef	FLASH_BUFFER1
	#define BUFFER_SECTOR_COM	0x53	//将主存储区读到FLASH CARD缓冲区
	#define BUFFER_WRITE_COM	0x82	//写数据到FLASH CARD缓冲区
	#define BUFFER_RWRITE_COM	0x58	//将FLASH CARD缓冲区数据写到主存储区
	#define BUFFER_COMPARE_COM	0x60	//比较FLASH CARD缓冲区与主存储区的数据
#else
	#define BUFFER_SECTOR_COM	0x55
	#define BUFFER_WRITE_COM	0x85
	#define BUFFER_RWRITE_COM	0x59
	#define BUFFER_COMPARE_COM	0x61
#endif	//FLASH_BUFFER1

sbit FLASH_CARD_CLK=P4^1; //flash clk
sbit FLASH_DO=P4^0;      //flash out
//sbit FLASH_DI=PC^7;    //flash in
//sbit FLASH_CARD_CS=cpld8 //FLASH_CARD_CS


uchar xdata cpu_t,cpu_ta1,cpu_d,cpu_tc1,cpu_tc2;	//CPU CARD的复位应答特征数据
uchar xdata sam_t,sam_ta1,sam_d,sam_tc1,sam_tc2;	//SAM CARD的复位应答特征数据
uchar bdata r_w_byte;	//位变量,SPI,IIC总线使用
sbit HBIT=r_w_byte^7;
sbit LBIT=r_w_byte^0;
typedef union { uint word;
                struct{uchar Hi;uchar Lo;} byte;
              } UNST;



//===================================================================================
void En_cpu_clk(void)	
{
	PSD8xx_reg.PAGE|=0x20;
}
//===================================================================================
void Dis_cpu_clk(void)	
{
	PSD8xx_reg.PAGE&=0xdf;
}
//====================================================================================
void En_sam_clk(void)	
{
	PSD8xx_reg.PAGE|=0x10;
}
//====================================================================================
void Dis_sam_clk(void)	
{
	PSD8xx_reg.PAGE&= 0xef;
}
 
//=================================================================================
uchar rece_cpu_byte(void)
{
	uchar	i,j=4,m;
	uint	k;
	//cpudata=0;
	do
	{
		m=cpu_d;	//等待起始位960 X CPU_D X CPU_TC2
		do
		{
			i=cpu_tc2;
			do
			{
				k=9600;
				IC_CARD_IO=1;
				do	//10us
				{
					if(!IC_CARD_IO)	break;
				}while(--k);
				if(!IC_CARD_IO)	break;
			}while(--i);
			if(!IC_CARD_IO)	break;
		}while(--m);
		
		if(!m)
			return 1;	//超时出错
			
		delay_half_etu();
		i=8;
		do	//读出8数据位
		{
			delay_etu();
			if(cpu_t)
			{
				r_w_byte=r_w_byte>>1;
				HBIT=IC_CARD_IO;
				_nop_();
			}
			else
			{
				r_w_byte=r_w_byte<<1;
				LBIT=IC_CARD_IO;
				_nop_();
				_nop_();
				_nop_();
			}
		}while(--i);
	    
		delay_etu();	//接收奇偶校验码
		if(!cpu_t)	
			r_w_byte=~r_w_byte;
			
		ACC=r_w_byte;
		PSW1=P;         //ACC中1的个数 1为奇个数p=0
		F0=IC_CARD_IO;
		delay_half_etu();
		
		if(PSW1)
		{
			if(F0)	return 0;
		}
		else
		{
			if(!F0)	return 0;
		}

		delay_half_etu();
		IC_CARD_IO=0;	//10.5 * etu发送错误信号
		delay_etu();
		delay_etu();
		IC_CARD_IO=1;
	}while(--j);
	return 1;
}
//=====================================================================================
uchar send_cpu_byte(uchar send_data)
{
	uchar i,j=4;
	do
	{
		IC_CARD_IO=1;
		delay_etu();	//字符间隔时间
		delay_etu();
		delay_etu();
		delay_etu();
		IC_CARD_IO=1;
		if(!IC_CARD_IO)	return 1;
		if(cpu_tc1&&(cpu_tc1!=0xff))
		{
			i=cpu_tc1;
			do
			{
				delay_half_etu();
				delay_half_etu();
			}while(--i);
		}
	
		IC_CARD_IO=0;		//发送起始位
		r_w_byte=send_data;
		if(!cpu_t)	r_w_byte=~r_w_byte;
		i=8;
		do
		{
			delay_etu();
			if(cpu_t)
			{
				IC_CARD_IO=LBIT;
				r_w_byte=r_w_byte>>1;
				_nop_();
			}
			else
			{
				IC_CARD_IO=HBIT;
				r_w_byte=r_w_byte<<1;
				_nop_();
				_nop_();
				_nop_();
				_nop_();
			}
		}while(--i);

		delay_etu();
		ACC=send_data;
		_nop_();
		_nop_();
		IC_CARD_IO=P;	//发送奇偶校验位
		delay_etu();
		r_w_byte=5;
		while(--r_w_byte);
	
		IC_CARD_IO=1;		//检测错误信号
		delay_etu();
		r_w_byte=5;
		while(--r_w_byte);
		if(IC_CARD_IO)	return 0;	//11 * etu
		delay_half_etu();
	}while(--j);
	
	return 1;
}

//===========================================================================
/*SAM CARD*/
uchar rece_sam_byte(void)//一位保持时间为372/foc ,foc=3,67M 时间为100us
{
	uchar	i,j=4,m;//firstbit;
	uint	k;
	//samdata=0;
	do
	{
		m=sam_d;	//等待起始位960 X SAM_D X SAM_TC2
		do
		{
			i=sam_tc2;
			do
			{
				k=9600;
				SAM_CARD_IO=1;
				do	//10us
				{
					if(!SAM_CARD_IO)	break;
				}while(--k);
				if(!SAM_CARD_IO)	break;
			}while(--i);
			if(!SAM_CARD_IO)	break;
		}while(--m);
		if(!m){	return 1;}	//超时出错
		//delayms(1);     //晶振不一样此地要调整
		delay_half_etu();

		i=8;
	    k=0;
		do	//读出8数据位
		{
			delay_etu();
			if(sam_t)
			{
				//samdata=samdata>>1; //低位先传
			    r_w_byte=r_w_byte>>1;
				HBIT=SAM_CARD_IO;
			    _nop_();
			}
			else
			{
				r_w_byte=r_w_byte<<1;
				//if(SAM_CARD_IO)samdata|=0x01;
				LBIT=SAM_CARD_IO;
				_nop_();
			//	_nop_();
			//	_nop_();
			}
		}while(--i);
		
		delay_etu();	//接收奇偶校验码
		if(!sam_t)
			r_w_byte=~r_w_byte;
		ACC=r_w_byte;
		PSW1=P;
		F0=SAM_CARD_IO;
		
		if(PSW1)
		{
			if(F0)	return 0;
		}
		else
		{
			if(!F0)	return 0;
		}
		
		delay_half_etu();
		SAM_CARD_IO=0;	//10.5 * etu发送错误信号
		delay_etu();
		SAM_CARD_IO=1;
	}while(--j);
	return 1;
}
//=====================================================================================
//卡的接收定时用
//在广州五所测试时加
void delay_etu1(void)
{
	uchar i;
	_nop_();
	i=31;//104u
    while(--i);
}
//===================================================================================
uchar send_sam_byte(uchar send_data)
{
  	uchar i,j=4;
	do
	{
		SAM_CARD_IO=1;
		delay_etu();	//字节间隔时间
		delay_etu();
		delay_etu();
		delay_etu();
	
		SAM_CARD_IO=1;
		if(!SAM_CARD_IO)	return 1;
		if(sam_tc1&&(sam_tc1!=0xff))
		{
			i=sam_tc1;
			do
			{
				delay_half_etu();
				delay_half_etu();
			}while(--i);
		}
		//////////////////////
		EA=0;
		SAM_CARD_IO=0;		//发送起始位
		r_w_byte=send_data;
		
		if(!sam_t)	r_w_byte=~r_w_byte;
	
		i=8;
		//广州五所  2 个 NOP
		//_nop_();
		//_nop_();
//		_nop_();
		
		do
		{
			//delay_etu(); //bit 的宽度
			delay_etu1(); //bit 的宽度//在广州五所测试时加100us
			if(sam_t)
			{
				SAM_CARD_IO=LBIT;
				r_w_byte=r_w_byte>>1;
				_nop_();
			
			}
			else
			{
				SAM_CARD_IO=HBIT;
				r_w_byte=r_w_byte<<1;
				_nop_();
			}
		}while(--i);

		delay_etu1(); //在广州五所测试时加
		ACC=send_data;
		_nop_();
		_nop_();
	//	_nop_();
		
		SAM_CARD_IO=P;	//发送奇偶校验位
		delay_etu1();   //在广州五所测试时加
		
		
	//_nop_();
	//	_nop_();
		r_w_byte=5;
		while(--r_w_byte);
		
		SAM_CARD_IO=1;		//检测错误信号
		delay_etu();
		r_w_byte=5;
		while(--r_w_byte);
	   
		delay_half_etu();   //广州五所
		if(SAM_CARD_IO)	return 0;	//11 * etu
		delay_half_etu();
	}while(--j);
	return 1;
}

//=================================================================================
uchar atr_sam(uchar xdata *ptr)
{
	uchar	xdata i,temp,atr_len,error,cpu_tck=0,ti=0;
	uchar xdata *p;
	uint	j=1000;
	UNST	bw;
	//uchar  xdata r_w_byte=0;
	atr_len=0;
	p=ptr;
	bw.word=0;
    card_vcc(1);//samcard_vcc(1);
	sam_ta1=0x11,sam_d=1,sam_tc1=0,sam_tc2=10;
	EA=0;
    Writ_cpld(Sim_rst,0);//SAM_CARD_RST=0;

	do	//等待起始位
	{
		if(!SAM_CARD_IO)break;
	}while(--j);
   
	Writ_cpld(Sim_rst,1);//SAM_CARD_RST=1;

	sam_t=1;	      //以正向协议传输
    
	if(rece_sam_byte())	//TS
	{
		EA=1;
		return 1;	//非CPU卡
	}
	//else return 0;   //暂时认为卡有数据响应为卡复位成功
	if(r_w_byte==0x03)	//反向传输
	{
		sam_t=0;
		r_w_byte=0x3f;
	}
	else if(r_w_byte!=0x3b)	//正向传输
	{
		EA=1;
		return 1;//非CPU卡
	}
    *p=r_w_byte;
	p++;
	atr_len++;
	
	error=rece_sam_byte();	//接收T0
	if(error)
	{
		EA=1;
		return 1;
	}
	*p=r_w_byte;
	
	p++;
	atr_len++;
	bw.byte.Hi=r_w_byte&0x0f;	//保存历史字节数据长度
	if((r_w_byte&0x0f)>32)	    //历史字节数据超长出错
	{
		EA=1;
		return 1;
	}
	
atr_sam1:
	temp=r_w_byte>>4;
	i=4;
	do	//Td1...Tdi
	{
		if(temp&0x01)
		{
			error=rece_sam_byte();
			if(error)
			{
				
				EA=1;
				return 1;
			}
			*p=r_w_byte;
			p++;
			atr_len++;
			if(atr_len==32)	//数据超长出错
			{
				EA=1;
				
				return 1;
			}
			if(i==4)	//TAi
			{
				if(!ti)	sam_ta1=r_w_byte;	//TA1决定接收字符间最大时间
				else if(ti==1)	cpu_tck=1;	//TA2...N表示有TCK校验
			}
			else if(i==2)	//TCi
			{
				if(!ti)	sam_tc1=r_w_byte;	//TC1决定发送字符间最小时间
				else if(ti==1)	sam_tc2=r_w_byte;	//TC2决定接收字符间最大时间
			}
			else if(i==1)	//TDi---是否有TCK
			{
				if(r_w_byte&0x0f)	cpu_tck=1;	//TDi表示有TCK校验
				ti++;
				goto atr_sam1;
			}
		}
		temp=temp>>1;
	}while(--i);
	
	if(bw.byte.Hi)	//有历史数据
	{
		i=bw.byte.Hi;
		bw.byte.Hi+=atr_len;
		do		//读出历史字节:T1...Tk
		{
			error=rece_sam_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;
			}
		}while(--i);
	}
	else
		bw.byte.Hi=atr_len;

	if(cpu_tck)	//有TCK校验
	{
		error=rece_sam_byte();	//读出TCK校验值
		if(error)
		{
			bw.byte.Lo=error;
			EA=1;
		
			return bw.word;
		}
		*p=r_w_byte;
		p++;
		atr_len++;
		
		temp=0;	//TCK校验
		for(i=1;i<atr_len;i++)	temp^=ptr[i];
		if(temp)	//异或校验出错
		{
			EA=1;
			bw.byte.Lo=1;
			
			return bw.word;
		}
	}
		
	if(!sam_tc2)
		sam_tc2=10;
		
	switch(sam_ta1&0x0f)
	{
		case	1:
			sam_d=1;
			break;
		case	2:
			sam_d=2;
			break;
		case	3:
			sam_d=4;
			break;
		case	4:
			sam_d=8;
			break;
		case	5:
			sam_d=16;
			break;
		case	6:
			sam_d=32;
			break;
		case	8:
			sam_d=12;
			break;
		case	9:
			sam_d=20;
			break;
		default:
			break;
	}
	EA=1;
	return bw.word;
}
//=====================================================================================
uchar  Sam_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;

	UNST	bw;
	EA=0;
	card_vcc(1);
	le=0;
	lc=out_buf[4];

⌨️ 快捷键说明

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