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

📄 test800m.c

📁 MF800M射频读写模块采用PHILIPS公司的Mifare技术设计的微型嵌入式、非接触式IC卡读写模块。内嵌ISO14443 Type A协议解释器,并可直接驱动射频天线
💻 C
字号:
/*******************************************************************************
*                    MF-800M模块测试程序
*功能:将Mifare_One卡的第一块写入数据0x00--0xFF
       将第二块初始化为钱包,做充值扣款
*现象:所有操作成功后,指示灯闪烁提示
*条件:Mifare_One卡的A密钥为6字节0xFF,且具有读写权限
*******************************************************************************/       
#include <reg52.h>
#include <string.h>


#define OSC_FREQ         11059200L
#define TIME0_10ms       65536L - OSC_FREQ/1200L

/*****************************************************************************
*端口定义
*****************************************************************************/
sbit     LEDR       =    P2^0;                                                     //指示灯
sbit     LEDG       =    P2^1;                                                     //指示灯

void InitializeSystem();                                                           //系统初始化
void SendCom(unsigned char *g_cCommand);                                           //向模块发送指令
void StartTime(unsigned int _MS);                                                  //启动计时,单位10ms
void StopTime();

//命令列表,不包含命令头0xaabb
//                                      长度字/命令码/数据
unsigned char code ComGetCsn[2]=        {0x02, 0x10 };                                        //寻卡指令

unsigned char code ComReadBlock1[10]=   {0x0A,0x11,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};  //读块指令:读第一块

unsigned char code ComWriteBlock1[26] = {0x1A,0x12,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                         0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,
                                         0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};                      //写块指令:写第一块,写入数据0x00--0xFF
                               
unsigned char code ComIntiPurse2[14]  = {0x0E,0x13,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,                             
                                         0x78,0x56,0x34,0x12};                                //初始化钱包:将第二块初始化为钱包格式,初始值为0x12345678
                               
unsigned char code ComReadPurse2[10]  = {0x0A,0x14,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};  //读钱包值:读第二块钱包值
                            
unsigned char code ComIncrPurse2[14]  = {0x0E,0x15,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                         0x02,0x00,0x00,0x00};                                //充值指令:将第二块钱包值加2
                               
unsigned char code ComDecrPurse2[14]  = {0x0E,0x16,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                                         0x01,0x00,0x00,0x00};                                //扣款指令:将第二块钱包值减1
              
unsigned char code ComRstMifarePro[2] = {0x02,0x20};                                          //复位Mifare_pro

unsigned char code ComCosMifarePro[7] = {0x07,0x21,0x00,0x84,0x00,0x00,0x04};                 //取随机数指令

                               
unsigned char code pursevalue[4]={0x79,0x56,0x34,0x12};
                            
unsigned char g_cReceBuf[60];                                      //接收通讯缓冲区
unsigned char g_cReceNum;                                          //接收的字节数
unsigned char g_cCommand;                                          //接收到的命令字
unsigned char g_cStatus;                                           //返回的状态字
unsigned char g_cWatchTime;                                        //计时参数
unsigned char g_cCardType;                                         //卡类型

bit   g_bReceCommandOk;                                            //接收到模块返回标志
bit   g_bReceAA;                                                   //接收到AA字节标志
bit   g_bSTI;
bit   g_bTimeOut;                                                  //计时溢出标记

void main() 
{
     InitializeSystem();
     
     
//延时1S以等待模块可靠复位  
     StartTime(100);                                       
     while(!g_bTimeOut);
     StopTime();

     while(1)
     {


//1.向模块发送寻卡指令,如果天线区内有M1卡执行步骤2,Mifare_Pro卡执行步骤8
//2.将Mifare_One卡的第一块写入数据0x00--0xFF
//2.读第一块并与写入的数据比较
//3.将第二块初始化为钱包格式,初始值为0x12345678 
//4.将第二块钱包值加2
//5.将第二块钱包值减1
//6.读第二块钱包值并检查值的正确性
//7.红色指示灯闪烁提示,返回步骤1循环
//8.复位Mifare_Pro卡
//9.向Mifare_Pro卡发送取随机数指令
//10.绿色指示灯闪烁提示,返回步骤1循环


//1.向模块发送寻卡指令,如果天线区内有M1卡执行步骤2,Mifare_Pro卡执行步骤6 
         g_cCardType = 0xFF;
         SendCom(ComGetCsn);                               //发送寻卡指令
         StartTime(8);                                     //启动计时
         while (!g_bReceCommandOk && !g_bTimeOut);         //等待接收,最大等待时间80ms
         StopTime();                                       //停止计时
         if ((g_cCommand==0x10) && (g_cStatus==0) && !g_bTimeOut)
         {    g_cCardType = g_cReceBuf[7];   }             //收到正确的返回
 
         while ((g_cCardType == 0) || (g_cCardType == 1))  //对Mifare_One卡操作                                
         {

//1.写第一块             
             SendCom(ComWriteBlock1);                
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x12) || (g_cStatus!=0) || g_bTimeOut)
             {    break;    }               
             
             
//2.读第一块并与上一步写入的数据比较             
             SendCom(ComReadBlock1);                 
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x11) || (g_cStatus!=0) || g_bTimeOut)
             {    break;    }
             if (memcmp(&ComWriteBlock1[10], &g_cReceBuf[3], 16) != 0)
             {    break;    }                 
             
             
//3.将第二块初始化为钱包格式,初始值为0x12345678             
             SendCom(ComIntiPurse2);                 
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x13) || (g_cStatus!=0) || g_bTimeOut)
             {    break;    }                 
             
             
//4.将第二块钱包值加2             
             SendCom(ComIncrPurse2);                 
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x15) || (g_cStatus!=0) || g_bTimeOut)
             {    break;    }      
             

//5.将第二块钱包值减1             
             SendCom(ComDecrPurse2);                 
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x16) || (g_cStatus!=0) || g_bTimeOut)
             {    break;    }  
              
                           
//6.读第二块钱包值             
             SendCom(ComReadPurse2);                
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x14) || (g_cStatus!=0) || g_bTimeOut)
             {    break;    }
             if (memcmp(&pursevalue[0],&g_cReceBuf[3],4) != 0)
             {    break;    }                  


//7.指示灯闪烁提示,返回步骤1循环            
             LEDR = 0;                    
             StartTime(20);                                
             while(!g_bTimeOut);
             LEDR = 1;     
             StopTime();
             break;            
         }
        
         while (g_cCardType == 2)
         {

//8.复位Mifare_Pro卡
             SendCom(ComRstMifarePro);                
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x20) || (g_cStatus != 0) || g_bTimeOut)
             {    break;    }   
             
//9.向Mifare_Pro卡发送取随机数指令  
             SendCom(ComCosMifarePro);                
             StartTime(8);
             while (!g_bReceCommandOk && !g_bTimeOut);
             StopTime();
             if ((g_cCommand!=0x21) || (g_cStatus != 0) || g_bTimeOut)
             {    break;    } 
             
//10.指示灯闪烁提示,返回步骤1循环            
             LEDG = 0;                    
             StartTime(20);                                
             while(!g_bTimeOut);
             LEDG = 1;   
             StopTime();
             break;            
         }    
     }             
       
}

        
/*****************************************************************************
*          系统初始化
*功能:BOUD=19200,由定时器1产生
*      T0设为16位计时器
*****************************************************************************/
void InitializeSystem()
{
    TMOD &= 0x0F; 
    TMOD |= 0x21; 
    PCON |= 0x80;
    SCON  = 0x50; 
    TH1   = 0xFD;
    TL1   = 0xFD; 
    TR1   = 1;
    IE   |= 0x90;
}

/*****************************************************************************
*功能:启动计时
*****************************************************************************/
void StartTime(unsigned int _MS)
{
    TH0 = (unsigned char)((TIME0_10ms>>8)&0xFF);
    TL0 = (unsigned char)(TIME0_10ms&0xFF);
    g_cWatchTime = _MS;
    g_bTimeOut = 0;
    ET0 = 1;
    TR0 = 1;
}	
/*****************************************************************************
*功能:T0中断-10MS
*****************************************************************************/
time0_int () interrupt 1 using 1
{
    
    IT0 = 0;
    TH0 = (unsigned char)((TIME0_10ms>>8) & 0xFF);
    TL0 = (unsigned char)(TIME0_10ms & 0xFF);
    if (g_cWatchTime--==0)
    {    g_bTimeOut = 1;    }
}
/*****************************************************************************
*功能:关闭计时
*****************************************************************************/
void StopTime()
{
    ET0 = 0;
    TR0 = 0;
}	

/*****************************************************************************
*功能:向模块发送指令
*****************************************************************************/
void SendCom(unsigned char *g_cCommand)
{    
     unsigned char i,chkdata,sendleg;

     g_bReceCommandOk = 0;
     sendleg = *g_cCommand;
     
     g_bSTI = 0;
     SBUF = 0xAA;
     while (!g_bSTI);
     
     g_bSTI = 0;
     SBUF = 0xBB;
     while(!g_bSTI);
     
     chkdata = 0;
     for(i=0; i<sendleg; i++)
     {    
     	  chkdata ^= *(g_cCommand+i);
     	  
     	  g_bSTI = 0;
     	  SBUF = *(g_cCommand+i);
     	  while(!g_bSTI);
          
          if (*(g_cCommand+i) == 0xAA)                     //除命令头外如遇到0xaa后跟一字节0x00以区分名头,长度字不变
          {  
              g_bSTI = 0;
              SBUF = 0;
              while(!g_bSTI);
          }
     }
     
     g_bSTI = 0;
     SBUF = chkdata;
     while (!g_bSTI);
   
     if (chkdata == 0xAA)
     {  
         g_bSTI = 0;
         SBUF = 0;
         while (!g_bSTI);
     }
     
}
/*****************************************************************************
*功能:串行中断,接收模块返回的数据
*      将接收到的命令去掉命令头及数据中补零的字节,存入g_cReceBuf
*****************************************************************************/
seri_int () interrupt 4 using 1
{
   unsigned char i;
   unsigned char rece_data = SBUF;
   unsigned char verify = 0;
   
   if(RI)
   {    
   	RI=0;
	if (g_bReceAA)                                      //前一个接收到的字节=AA
	{  
	     g_bReceAA = 0;
	     switch (rece_data)
	     {    
	     	  case 0x00:
	               break;
	          case 0xbb:
	               g_cReceNum = 0;
	               break;
	          default:
	               i = g_cReceNum;
	               g_cReceBuf[i] = rece_data;
	               break;
	     }
	}
	else
	{    
	     switch(rece_data)
	     {    
	     	  case 0xaa:
	               g_bReceAA = 1;
	          default:
	               i = g_cReceNum++;
	               g_cReceBuf[i] = rece_data;
	               break;
	     }
	}
	
	i = g_cReceBuf[0];                                 
        if(g_cReceNum==i+1)                                 //接收到的数据等于长度字,判断校验字
        {   
            for (i=0; i<g_cReceBuf[0]+1; i++)
            {
            	verify ^= g_cReceBuf[i];
            }
            if(!verify)                                     //校验字正确取命令码
            {   
                g_bReceCommandOk = 1;
                g_cCommand = g_cReceBuf[1];
                g_cStatus = g_cReceBuf[2]; 
                g_cReceNum = 0;
            }
        }
        
        if (g_cReceNum > sizeof(g_cReceBuf))                //接收数据溢出,清除
        {    g_cReceNum = 0;     }
    }
    
    if(TI)
    {   
        TI = 0; 
        g_bSTI = 1; 
    }
}

⌨️ 快捷键说明

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