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

📄 main.c

📁 mcs51系列,如LPC764 访问IC卡的源码,符合ISO7816-3规范
💻 C
字号:
#include "cos.h"
#include "module.c"

void main()
{
	uchar i,j,n,dat;
        //int k=65535;

//	LDelay(2);
       	DIVM=0;    //1分频
        P2M1=0x02;	// P2.1 为输入 //P2.0为准双向口
	P2M2&=0xfd;
        P2M1 |=0x10;    //X2输出focs/6
        POWEROFF = 0; //系统电源开

        //测试低电压初始化
        PT0AD =0x02;//  禁止数字功能
        P0M1 |=0x02;//po.1设为输入
        P0M2 &=0x0FD;
          _nop_();
        SysInit();
        C2_RST=1;
        iComBuf=0;

        //TR0=1;
        //EX1=1;
      //  while(1);
        SYSPOWERON =0;

	if(CPUCardReset());//CARD_OK=1;
        _nop_();
/*
	//CARD_OK=0;
      	CARD_SEND=1;
        ETU_counter=2;
//        TR0=1;

        while(1){
        while(ETU_counter);
        C7_IO=~C7_IO;
        ETU_counter=2;
        }


        //iComBuf=7;
//0084000001

	CARD_SEND=1;//向CPU卡发送数据标志位
	//bit_counter=0;//在此作为ETU定时标志位,1:ETU定时到,0,未到

	EX1 = 0;//外部中断禁止
	ET0=0;//ETU定时器(T0)中断禁止
        //CARD_SEND=1;//向CPU卡发送标志位
        C7_IO=1;
        C7_IO=0;//起始位
		TR0=1;
		while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
                while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
         C7_IO=1;
         while(!TF0);
                TF0=0;
		while(!TF0);
                TF0=0;
               CARD_SEND=0;

        TR0=0;
        ET0=1;
        TL0 = HALF_ETU;
        ReceiveByte(2);
//       	ReceiveaByte();
//        ReceiveaByte();
*/



/*
        for(i=0;i<20;i++)  ComBuf[i]=0;
        //iComBuf=0;
        ETU_counter=20;
        ETU_data=0;
	EX1 = 0;//外部中断禁止
	//ET0=0;//ETU定时器(T0)中断禁止
        CARD_SEND=1;//向CPU卡发送标志位
        C7_IO=0;//起始位
	TR0=1;

        while(ETU_counter);
        C7_IO=1;
        ETU_counter=2;
        while(ETU_counter);
        CARD_SEND=0;
         TR0=0;
         TL0 = HALF_ETU;
 //        ET0=1;

       	ReceiveByte(2);
*/
	_nop_();

        if(CPUCardReset());//CARD_OK=1;
	//CARD_OK=0;
	_nop_();
	if(SelectFlie(00,02));//CARD_OK=1;
         _nop_();
//        while(1){
//        i=i+1;

//        j=i++;}




	//CMP1=0x38;	//电源1监测
	//test
	//iComBuf = StrComp("CONNECT",ModemConStr,7);
//	ComBuf[0] = 0x01;
//	ComBuf[1] = 0x02;
//	WEEPRom(MyAddInEeprom,ComBuf,2);
//	REEPRom(MyAddInEeprom,ComBuf+2,10);
	//test
        //SysActive = 1;//test 2003-12-18 21:27
	while(1){
 		//WDRST = 0x01E;
 		//WDRST = 0x0E1;
 		POWEROFF = 0; //系统电源开
 		//POWLED = 0;

/*
		if(WakenBySIO){
			ES = 0;
			Tx2RS1Ch('O');
			Tx2RS1Ch('K');
			WakenBySIO = 0;
			SysActive = 1;
			Delay20ms = 100;//Delay20ms = 100;   modify 2003.12.9
                        ES = 1;
			}
 */


		if((iComBuf >= LENMIN)){       //LENMIN
 			SysActive = 1;
			Delay20ms = 100;	//延时2s
                        //&&(iComBuf >= ComBuf[12]+19)
 			i = IsAPackFromPC();
 			if(i){  //收到正确数据包
                                ES = 0;
                                  if(i==DES3){
		
			             if(DES_ENC())Tx2RS(10);
                                     else{ ComBuf[0] = 0x69;
                                     ComBuf[1] = 0x00;
                                     Tx2RS(2);
                                } 
		
		       }//end //收到正确数据包
                                
 				RI =0;
 				TI = 0;
 				InitSIO();
 				//SysState = 0;
 				ES = 1;
 			}
 	     }//end if iComBuf

/* 		if(! SysState){
			InitSIO();
			DisableT0();	//关定时器0
                        LowBattery();

			POWEROFF = 1;	//2003-11-9

			POWER485OFF = 1;
			//POWLED = 1;
			//LOWBLED = 1;
			EX1 = 1;
			ES = 0;

	 		PCON |= 0x02;		//丢电

	 		_nop_();
	 		EnableT0();
	 		}
*/
 		}//end while
}//end main
//CPU卡复位程序
//返回说明:1为成功复位;0为复位失效。
uchar CPUCardReset(void)
{

	int k;

	SYSPOWERON=0;
	C2_RST=0;
        k=0;
	while(k<400){
        k++;}

	C2_RST=1;
	k=40000;

	for(iComBuf=0;iComBuf<13;iComBuf++){
		CARD_OK=0;
		if(ReceiveaByte()==0)break;
		}
	if(iComBuf==13)return 1;
	else return 0;
}

//接收CPU卡数据子程序
//接收数据长度为1,接收位置由iComBuf决定,放在ComBuf[iComBuf]中
//接收数据放在数组ComBuf中,最长为60
//返回说明:1为正确读出;0为超时返回
uchar ReceiveaByte(void)
{	int k=65535;

	IE1=0;
	EX1 = 1;
//	iComBuf=0;
//        while(iComBuf!=length);
//        return 1;


	while((!CARD_OK)&&(k--));
	EX1 = 0;
	if (CARD_OK)
	{

		return 1;
	}
	else
	{

		return 0;
	}
}
//发送CPU卡数据子程序
//发送数据长度为1,dat_to_cos为形参,是所要发送的数据

void SendaByte(uchar dat_to_cos)
{   uchar n,RECEVIE_OK;
                RECEVIE_OK=1;
		ACC=dat_to_cos;
                if(P)bitp =1;//奇偶校验位
                else bitp =0;

                TR0=1;
		C7_IO=0;//起始位
		
		for(n=0;n<8;n++){
                        dat_to_cos=dat_to_cos>>1;
		        bitio =CY;
                        while(!TF0);
                        TF0=0;
		        while(!TF0);
                         C7_IO = bitio ;
                        TF0=0;
                       
		}
                while(!TF0);
                TF0=0;
		while(!TF0);
                C7_IO=bitp ;
                TF0=0;

                while(!TF0); //奇偶校验位
                TF0=0;
                while(!TF0);
                C7_IO=1;
                TF0=0;

                while(!TF0);//停止位
                TF0=0;
                if(!C7_IO)   RECEVIE_OK=0;
                while(!TF0);
                TF0=0;
                TR0=0;
	//	TH0 = HALF_ETU;//ETU0_5
	 	TL0 = HALF_ETU;


}
//接收CPU卡数据子程序
//filename_h,uchar filename_l为所要选择的文件名

//返回说明:1为选择成功;0为超时返回
uchar SelectFlie(uchar filename_h,uchar filename_l)
{	uchar i;//,i,j;
	ComBuf[0] = 0x00;
	ComBuf[1] = 0xA4;//0x84;//
	ComBuf[2] = 0x00;
	ComBuf[3] = 0x00;
        ComBuf[4] = 0x02;//0x01;//
        ComBuf[5] = filename_h;
        ComBuf[6] = filename_l;
         ET0=0;
         EX1=0;
	for(i=0;i<7;i++){
	        SendaByte(ComBuf[i]);
	}
        ET0=1;
        
        for(iComBuf=0;iComBuf<2;iComBuf++){
		CARD_OK=0;
		if(ReceiveaByte()==0)break;
		}
       	if(iComBuf==2)return 1;
	else return 0;



}
//DES加密子程序
//返回说明:1为加密成功;0为加密失败
//加密成功,加密后的8位字节+9000放在ComBuf[0]开始的数组中
//加密失败, 错误返回码(两个字节)放在ComBuf[0]开始的数组中
uchar DES_ENC(void)
{   uchar i;//,i,j;
/*	ComBuf[0] = 0x00;//0088000108
	ComBuf[1] = 0x88;//0x84;//
	ComBuf[2] = 0x00;
	ComBuf[3] = 0x01;
        ComBuf[4] = 0x08;//0x01;//
        ComBuf[5] = 0x00;
        ComBuf[6] = 0x02;
*/
         ET0=0;
         EX1=0;
	for(i=0;i<13;i++){
		 SendaByte(ComBuf[i]);
	}

        ET0=1;
        //iComBuf=0;
       	for(iComBuf=0;iComBuf<10;iComBuf++){
		CARD_OK=0;
		if(ReceiveaByte()==0)break;
		}
       	if(iComBuf==10)return 1;
	else return 0;
}
//低电压测试,当电压低于某个设定值时,某管脚拉低,第一版硬件没有做
void LowBattery(void)
{
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
	CMP2|=0x38;	//电源2监测
        ACC = CMP2;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
	if((ACC & 0x02)!=0) LOWBLED = 1;
	else LOWBLED = 0;

	//CMP1=0x00;  //禁能比较器1
	CMP2&=0x0C0;  //禁能比较器2
}

void SysInit(void)
{
	DIVM=0;    //1分频

	AUXR1|=0x50; //低功耗

	WDCON=0x07; //看门狗

	CMP1=0x00;  //禁能比较器1
	CMP2=0x00;  //禁能比较器2

	PT0AD=0x00;   	// 数字渗入
	P0M1=0x00;	//准双向口
	P0M2=0x00;
	P0=0x0FF;	//输出为1

	P1M1=0x00;	//准双向口
	P1M2=0x00;
	P1=0x0FF;	//输出为1

//	P2M1=0x03;	//P2.0 P2.1 为输入
//	P2M2&=0xfc;

	KBI = 0; //禁止键盘中断

	//EX1 = 1;
	IT1 = 1;	//外部中断1 下降沿

	PS = 1;	//串行中断高

	Delay20ms = 0;
	EnableT0();
	EnableSIO();


	SysState = 0;

	InitSIO();

	
	//UCFIG1 = 01100111
	//UCFIG2 = 11000000

	


	EA = 1;

}
//定时器T0初始化为半个ETU时间的定时器
void EnableT0(void)
{

	 TMOD = 0x22;//8位重装载计数器

	 TH0 = HALF_ETU;//ETU1_5_H	;// 1.5ETU 时间,TIMER0H;
	 TL0 = HALF_ETU;//ETU1_5_L	;//TIMER0L;

	 ET0=1;


	 //WDCON=0x17; //start 看门狗
}

void DisableT0(void)
{
	TF0=0;

	TR0=0;
	ET0=0;	//关定时器0

	//WDCON=0x07; //stop 看门狗
}
//波特率定时器设定为9600无校验@7Mhz

void EnableSIO(void)
{
	 TMOD = 0x22;
	 TH1 = HWBAUDRATE; //BAUDRATE
	 TL1 = HWBAUDRATE;
	 ET1=0;
	 TR1=1;

	 SCON = 0x50;//0x0D0;//
	 RI = 0;
	 TI = 0;
	 ES = 1;
}

//外部中断, 由CPU卡的起始位触发,用于接收CPU卡数据的同步
void Service_EXT1(void) interrupt 2
{
        //IE1=0;
       // EnableT0();
	TR0=1;   //开ETU定时器
        CARD_IN=1;
	ETU_counter=3; //3

//	Delay200us = 10; //2ms
//	SysActive = 1;
//        ES = 1;
	EX1 = 0;
}
//T0中断服务程序,用于CPU卡数据接收
//接收数据放在
void Service_T0(void) interrupt 1
{       TF0=0;//清中断标志位
	ETU_counter--;

		if(CARD_IN==1){
			bit_counter=1;
			CARD_IN=0;
			ETU_data=0;
		}
	        //ETU_counter--;
	        //if(bit_counter<0x100)
		if(ETU_counter==0){
	                if(bit_counter<=0x100){
	                		if(C7_IO==1)      ETU_data|=bit_counter;
	        	                else 		  ETU_data&=~bit_counter;
	                bit_counter=bit_counter<<1;
	                ETU_counter=2;
	                }
	        }
	        if(bit_counter==0x200)
	        {	IE1=0;
	        	EX1=1;
	                TR0=0;
	                TH0 = HALF_ETU;//ETU1_5_H	;// 0.5ETU 时间
		        TL0 = HALF_ETU;//ETU1_5_L	;//TIMER0L;

	                ComBuf[iComBuf]=(uchar)ETU_data;
	                CARD_OK=1;
	        	//iComBuf++;

	        }

}



//串行中断 接收中断,发送查询
void Service_SIO(void) interrupt 4
{
	if(TI) {
		TI = 0;//??????
                return;
		}// end TI

  	if(RI) {
		RI = 0;
	  	AByteRec = SBUF;

		ACC = AByteRec;


		//if(RB8 == P){	//奇偶正确
		  	if(ComRec == 0 && ((AByteRec == COMHEAD1) || (AByteRec == COMHEAD2) || (AByteRec == COMHEAD3))){
                                     ComRec = 1;
                                     Delay20ms = 200;//2004-6-15 21:03
                                     //SIODelay = 1;
                        	}
		  	if(ComRec && (iComBuf < COMBUFLEN))ComBuf[iComBuf++] = AByteRec;
		//  	}



		}// end RI
}

//判断是否是一个数据包;待补充
uchar IsAPackFromPC(void)
{
	if(!(ComBuf[0] == COMHEAD1 || ComBuf[0]== COMHEAD2 || ComBuf[0]== COMHEAD3))return 0;
        if(ComBuf[0]== COMHEAD1 ){
	switch(ComBuf[1]){
		case DES3:
			if(iComBuf >= 13) return DES3;
			break;
		default:break;
	}
        }
        if(ComBuf[0]== COMHEAD2 ){


        }
        if(ComBuf[0]== COMHEAD3 ){
        }

	return 0;
}


//Under RS232 下的初始化
void InitSIO(void)
{
	

	for(iComBuf=0;iComBuf<COMBUFLEN;iComBuf++)
		ComBuf[iComBuf] = 0;
	iComBuf = 0;
	ComRec = 0;
}

// 串口发数据,待发送的数据放在 ComBuf数组中

⌨️ 快捷键说明

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