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

📄 t2.c

📁 一个M1读卡器的驱动程序
💻 C
字号:
#include <AT89X52.h>
#include <INTRINS.H>
#include <string.h>

unsigned char  INBUF_LEN;   //数据长度
unsigned char  inbuf1[32];
unsigned char  count3;
unsigned int    i;
unsigned char   c0[9]={0x00,0x06,0x00,0x00,0x05,0x03,0x01,0x03,0x01};		   //初始相对卡号
unsigned char temp[9]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
unsigned char pass[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
bit           flag=0;                             //是否进行下一步的标志	   

//*********************************************************************************//
unsigned char  ledcode[] ={0xee,   //0     
                           0x28,   //1
                           0xcd,   //2
                           0x6d,   //3
                           0x2b,   //4
                           0x67,   //5
                           0xe7,   //6
                           0x2c,   //7
                           0xef,   //8
                           0x6f,   //9
                           0xaf,   //A
                           0xe3,   //B
                           0xc6,   //C
                           0xe9,   //D
                           0xc7,   //E
                           0x87};  //F
//数码管字符表																	   
//*********************************************************************************//

void delay(int j)	       // 延时
{
int a;
while (--j){a=1000;while(--a){;}}
}  

/***********************************************************************************/
void init_com(void) //初始化串口
{
	SCON=0x50;
	TMOD=0x20;//t0 timer
	TH1=0xfd;//9600bps
    TR1=1;
	ET1=0;
    ES=1;
  	EA=1; 
	IT0 =0;
    count3=0;           //串口计数清零
    INBUF_LEN=0x21;		//数据长度设为最大	
	
}


//向串口发送一个字符串,strlen为该字符串长度,连续发送
void send_string_com(unsigned char strlen)
{
 unsigned int t=0;
 RI=0;
 EA=0;
    do 
    {
        SBUF=inbuf1[t];
        while(TI==0);
		TI=0;
        t++;
    } while(t < strlen);
 EA=1;
}


//串口接收中断函数 ,连续接收
void serial () interrupt 4 using 3 
{  
unsigned int k=0;
EA=0;
    if(RI)
    {
	    while(inbuf1[count3]!=0x0D)
		{
        RI = 0;	
		if (inbuf1[count3]==0x3C ) 
		{count3=0;inbuf1[count3]=0x3C;count3++;}
		else count3++;
        inbuf1[count3]=SBUF;
		while (RI==0&&k<6000){k++;}  
		}  
    }
EA=1;
//INBUF_LEN=count3+1;
count3=0;
}
/***************************************************************/
unsigned char BCC(unsigned char *str,unsigned int strlen)  //数据校验
{ 
    unsigned char bcc1=0x00;
	i=0;
	while(i<strlen)
	{
	 bcc1^=str[i];
	 i++;
	}
	return bcc1;
}
/***************************************************************/

void searchcard()                              //这一步能正常通过了!
{
		  flag=0;
		  inbuf1[0]=0x3C;                 //下传命令:3C 04 01 70 00(寻卡模式00(IDLE)或01(ALL)) 00 BCC(49) 0D
	      inbuf1[1]=0x04; 
		  inbuf1[2]=0x01;
		  inbuf1[3]=0x70;
		  inbuf1[4]=0x01;
		  inbuf1[5]=0x00;
		  inbuf1[6]=BCC(inbuf1,6);		  //校验
		  inbuf1[7]=0x0D;   
		  INBUF_LEN=8; count3=0;         
          send_string_com(INBUF_LEN);           //向模块发送命令
		  delay(100);				            //等待模块回传信息
//		  send_string_com(INBUF_LEN);
		  if ( inbuf1[1]==0x05) 
			{
			   temp[0]=inbuf1[2];					 //获取相对卡号
			   temp[1]=inbuf1[3];
			   temp[2]=inbuf1[4];
			   temp[3]=inbuf1[5];
	           delay(50); 	  
			   flag=1;								 //寻卡成功,flag置位
		     }	else 
			 flag=0;
             count3=0;
			 return;
}


/**************************************************************/

void passcheck()                     //这一步好像有问题!不知道为什么!可能是延时太少么?
{		  
          unsigned int i;
		  flag=0;
		  inbuf1[0]=0x3C;						// 下传命令:3C 0E 01 6C 六字节密码 认证模式(00-A/01-B) 绝对块号 四字节卡号 校验位 0D
	      inbuf1[1]=0x0E; 						//eg:3C 0E 01 6C ff ff ff ff ff ff 00 02 74 09 49 C4 AD 0D
		  inbuf1[2]=0x01;
		  inbuf1[3]=0x6C;
		  for (i=0;i<6;i++){inbuf1[i+4]=pass[i];}
          inbuf1[10]=0x00;					       //认证模式(00-A/01-B) 使用A模式 只读不写
		  inbuf1[11]=0x01;					       //读块号1
		  for (i=0;i<4;i++) {inbuf1[i+12]=temp[i];}
		  inbuf1[16]=BCC(inbuf1,16);
		  inbuf1[17]=0x0D;   
		  INBUF_LEN=18;  count3=0;         
          send_string_com(INBUF_LEN);	        	 //向模块发送命令
		  delay(100);								//等待模块回传信息
//		  send_string_com(INBUF_LEN);				//测试点
		  if  (inbuf1[1]==0x02) 				    //这里只是根据返回命令的特征进行简单验证,为了程序更加健壮,应该要进行bcc校验
			   {
               delay(100);
		       flag=1;								 //密码验证成功,flag置位
			   } 
		 return;
}
/**************************************************************/

void readcard()
{
          
		
		  flag=0;						   
		  inbuf1[0]=0x3C;                            // 下传命令:3C 04 01 66 00(绝对块号) 00 BCC 0D
	      inbuf1[1]=0x04; 
		  inbuf1[2]=0x01;
		  inbuf1[3]=0x66;
		  inbuf1[4]=0x01;					    	 //绝对块号
		  inbuf1[5]=0x00;
		  inbuf1[6]=BCC(inbuf1,6);
		  inbuf1[7]=0x0D;   
		  INBUF_LEN=8; 
		  count3=0;          
          send_string_com(INBUF_LEN);	         	//向模块发送命令
		  delay(100);						       //等待模块回传信息
		  if (inbuf1[1]==0x12) 		 	   	   //这里只是根据返回命令的特征进行简单验证,为了程序更加健壮,应该要进行bcc校验
			   {
           	   for (i=0;i<10;i++) 
			   {temp[i]=inbuf1[i+3];	 
			   inbuf1[i]=temp[i];}
	           delay(20);
		       flag=1;								 //寻卡成功,flag置位
			   }
//		   INBUF_LEN=0x08; count3=0;
//		   send_string_com(INBUF_LEN);
		   delay(20);
		   return;  

}
/**************************************************************/
void cardcheck()	 //验证相对卡号
{ 
	flag=1;
    for(i=0;i<8;i++) 
	        {if (temp[i]!=c0[i]) 
			      flag=0;}
//	if (temp[8]>=c0[8])	 
//        	  c0[8]=temp[8];	  //卡号的最后一个字节是识别字节,用于用户换自己的卡,大数有效
//	        	else flag=0;
	}



	
/**************************************************************/

void closecard()          //  关闭卡片:3C 04 01 68 00 00 51 0D
{
          inbuf1[0]=0x3C;                       
	      inbuf1[1]=0x04; 
		  inbuf1[2]=0x01;
		  inbuf1[3]=0x68;
		  inbuf1[4]=0x00;
		  inbuf1[5]=0x00;
		  inbuf1[6]=0x51;
		  inbuf1[7]=0x0D;
		  INBUF_LEN=0x08;  
		  count3=0;         
          send_string_com(INBUF_LEN);

}
/**************************************************************/
void main(){
    unsigned int state;															    
    init_com();  //初始化串口和中断
	state=1;
	P1_7=1;
	P0=ledcode[0];
	delay(50);
    while(1)	 
    {	
//	    P1_2=0;	P0=ledcode[0];delay(50);
		switch(state){
		case 1:	  
		 P0=ledcode[state];delay(50);
		 searchcard(); 
		 if (flag) state++;else state=6;break;	
		//寻卡	           
         case 2:   
		 P0=ledcode[state];delay(50);
		 passcheck();
		  if (flag) state++;else state=6;break;      
	    //如果寻卡成功,获取绝对卡号,进行密码验证
        case 3:   
		 P0=ledcode[state];delay(50);
		readcard();  
		 if (flag) state++;else state=6;break;  
		//如果密码验证成功,读卡获取,获取相对卡号           
		case 4:    P0=ledcode[state];delay(50);
		cardcheck(); 
		 if (flag) state++;else state=6;break; 		           
		//	进行验证
		case 5:  
		 P0=ledcode[state];delay(500); 
		 P1_7=0;delay(1000);P1_7=1;state++;break; 	
	   // p1.7指示电动门锁执行开门动作 ,			  
		case 6:   P0=ledcode[state];delay(50); 
		closecard();state=1;break;                              
	   // 模拟时接led显示 及接在外部中断上,用以模拟正常开门时门磁动作 
	   }          	   	
     }


}


⌨️ 快捷键说明

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