zoukankan      html  css  js  c++  java
  • 【RFID-RC522】51单片机 RFID-RC522 IC卡读写


      项目源代码  提取码:1111

    一、项目实现功能

    利用51单片机加载RFID-RC522模块,读取IC卡内容或者向IC卡写入内容。然后,在将51单片机获得的数据通过USB送入电脑进行进一步处理。

    二、开发工具

    单片机:   STC89C52
    无线射频模块:  RFID-RC522
    编写单片机程序:  Keil uVisio5
    烧录51程序等其他辅助软件:  百度网盘链接,  提取码:1111

    三、程序实现

    3.1 RFID简介


    RFID: (Radio Frequency Identification)无线射频技术。简单来讲就是识别系统与识别目标之间不需要建立机械接触或者光学联系而是利用微波建立通信系统。完整的RFID系统包括读卡器和电子标签以及数据处理程序三部分组成。RFID的工作原理:当电子标签进入读写器可以读写的范围的时候,电子标签可以接收到读写器发出的射频信号,凭借感应电流产生的能量,又将自己的信息发送出去。或者是由标签主动的讲自身的信息发送出去。接下来,接收器通过解码接收到的数据,在发送给更高层的应用进行处理。

    3.2 rc-522芯片简介

     rc522芯片是高度集成的非接触式的(工作在13.56MHZ)读写卡芯片,该模块利用调制和解调的原理,并将它们完全集成到各种非接触式通信和方法和协议中。支持 ISO14443A 的多层应用。其内部发送器部分可驱动读写器天线与ISO 14443A/MIFARE卡和应答机的通信,无需其它的电路。接收器部分提供一个坚固而有效的解调和解码电路,用于处理 ISO14443A 兼容的应答器信号。数字部分处ISO14443A 帧和错误检测(奇偶 &CRC)。此外,它还支持快速 CRYPTO1 加密算法,用于验证MIFARE系列产品。MFRC522 支持 MIFARE更高速的非接触式通信,双向数据传输速率高达 424kbit/s。
    工作模式图:

    芯片机械图:

    芯片电路图:

    3.3RFID-RC522模块引脚连接及其作用

    3.3.1引脚简介
    SDA SCK MOSI MISO IRQ GND RET 3.3V
    选择设备 时钟信号 主出从入(数据) 主入从出(数据) 中断 接地 置位 电源
    3.3.2引脚连接


    在程序里面的引脚定义:

    //////////////////////////////////
    //引脚定义
    //////////////////////////////////
    //RFID-RC522
    sbit     MF522_NSS  =    P1^4;			//片选
    sbit     MF522_SCK  =    P1^1;
    sbit     MF522_SI   =    P1^0;
    sbit     MF522_SO   =    P1^2;
    sbit     MF522_RST  =    P1^3; 
    

      注意:1、中断接口并没有连接。2、这里的引脚定义,是自己选择单片机上面暴露出来的引脚接口,当然是要可以写程序的引脚。因为单片机上面的几乎每一个引脚都有其他的作用,我们复用引脚的时候要注意,保留自己程序将要用到的其他引脚。比如这个程序接下来还需要uart串口中断程序,所以串口中断的引脚要保留下来。3、引脚连接的线是单独购买的杜邦线。

    3.4 设备工作

    3.4.1 RFID-RC522程序

      学过一点嵌入式开发的或者计算机原理再或者学习过汇编的同学应该会有一个感受。往寄存器中写入一串串有意义的二进制数据就可以让计算机运行起来。所以,相对底层的编程就是按照设备规定的规则来对寄存器进行操作。而支持对寄存器进行操作的高级语言无疑就是C语言。
      一般我们获取设备相关编程信息都是从数据手册上面来的。如果看会了数据手册一般编程就没什么大问题,但是通常情况下数据手册都是英文的,我们要看懂就要求我们的英语要过的去。数据手册提取码:1111。学习计算机组成原理的时候,我们学习过每一条指令它除了包含只能本身的作用编码,还有就是操作地址编码。这边的指令也是一样的效果。一般我们的单片机和RC522共同作用都包含几个步骤:唤醒RC522、待写入的命令,将要用到的数据、返回到51单片机的值。这几部的具体实现就是完全按照数据手册进行的,一下是封装的头文件信息:

    展开查看代码---头文件
      
    #ifndef __MFRC522_H__
    #define __MERC522_H_
    /////////////////////////////////////////////////////////////////////
    //待实现函数
    /////////////////////////////////////////////////////////////////////
    void WriteRawRC(unsigned char Address,unsigned char value);
    unsigned char ReadRawRC(unsigned char Address); 
    void SetBitMask(unsigned char reg,unsigned char mask); 
    void ClearBitMask(unsigned char reg,unsigned char mask); 
    char PcdReset(void);
    void PcdAntennaOn(void);
    void PcdAntennaOff(void);
    char PcdRequest(unsigned char req_code,unsigned char *pTagType);   
    char PcdAnticoll(unsigned char *pSnr);
    char PcdSelect(unsigned char *pSnr);         
    char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr);     
    char PcdRead(unsigned char addr,unsigned char *pData);     
    char PcdWrite(unsigned char addr,unsigned char *pData);    
    char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue);   
    char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr);                                 
    char PcdHalt(void);
    char PcdComMF522(unsigned char Command, 
                     unsigned char *pInData, 
                     unsigned char InLenByte,
                     unsigned char *pOutData, 
                     unsigned int  *pOutLenBit);
    void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData);
    char M500PcdConfigISOType(unsigned char type);
    /////////////////////////////////////////////////////////////////////
    //MF522命令字
    /////////////////////////////////////////////////////////////////////
    #define PCD_IDLE              0x00             
    #define PCD_AUTHENT           0x0E             
    #define PCD_RECEIVE           0x08              
    #define PCD_TRANSMIT          0x04              
    #define PCD_TRANSCEIVE        0x0C             
    #define PCD_RESETPHASE        0x0F            
    #define PCD_CALCCRC           0x03              
    /////////////////////////////////////////////////////////////////////
    //Mifare_One(M1卡)命令字
    /////////////////////////////////////////////////////////////////////
    #define PICC_REQIDL           0x26               
    #define PICC_REQALL           0x52             
    #define PICC_ANTICOLL1        0x93              
    #define PICC_ANTICOLL2        0x95             
    #define PICC_AUTHENT1A        0x60               
    #define PICC_AUTHENT1B        0x61              
    #define PICC_READ             0x30             
    #define PICC_WRITE            0xA0              
    #define PICC_DECREMENT        0xC0              
    #define PICC_INCREMENT        0xC1             
    #define PICC_RESTORE          0xC2              
    #define PICC_TRANSFER         0xB0              
    #define PICC_HALT             0x50              
    /////////////////////////////////////////////////////////////////////
    //MF522 FIFO长度定义
    /////////////////////////////////////////////////////////////////////
    #define DEF_FIFO_LENGTH       64                 //FIFO size=64byte
    /////////////////////////////////////////////////////////////////////
    //MF522寄存器定义
    /////////////////////////////////////////////////////////////////////
    // PAGE 0
    #define     RFU00                 0x00    
    #define     CommandReg            0x01    
    #define     ComIEnReg             0x02    
    #define     DivlEnReg             0x03    
    #define     ComIrqReg             0x04    
    #define     DivIrqReg             0x05
    #define     ErrorReg              0x06    
    #define     Status1Reg            0x07    
    #define     Status2Reg            0x08    
    #define     FIFODataReg           0x09
    #define     FIFOLevelReg          0x0A
    #define     WaterLevelReg         0x0B
    #define     ControlReg            0x0C
    #define     BitFramingReg         0x0D
    #define     CollReg               0x0E
    #define     RFU0F                 0x0F
    // PAGE 1     
    #define     RFU10                 0x10
    #define     ModeReg               0x11
    #define     TxModeReg             0x12
    #define     RxModeReg             0x13
    #define     TxControlReg          0x14
    #define     TxAutoReg             0x15
    #define     TxSelReg              0x16
    #define     RxSelReg              0x17
    #define     RxThresholdReg        0x18
    #define     DemodReg              0x19
    #define     RFU1A                 0x1A
    #define     RFU1B                 0x1B
    #define     MifareReg             0x1C
    #define     RFU1D                 0x1D
    #define     RFU1E                 0x1E
    #define     SerialSpeedReg        0x1F
    // PAGE 2    
    #define     RFU20                 0x20  
    #define     CRCResultRegM         0x21
    #define     CRCResultRegL         0x22
    #define     RFU23                 0x23
    #define     ModWidthReg           0x24
    #define     RFU25                 0x25
    #define     RFCfgReg              0x26
    #define     GsNReg                0x27
    #define     CWGsCfgReg            0x28
    #define     ModGsCfgReg           0x29
    #define     TModeReg              0x2A
    #define     TPrescalerReg         0x2B
    #define     TReloadRegH           0x2C
    #define     TReloadRegL           0x2D
    #define     TCounterValueRegH     0x2E
    #define     TCounterValueRegL     0x2F
    // PAGE 3      
    #define     RFU30                 0x30
    #define     TestSel1Reg           0x31
    #define     TestSel2Reg           0x32
    #define     TestPinEnReg          0x33
    #define     TestPinValueReg       0x34
    #define     TestBusReg            0x35
    #define     AutoTestReg           0x36
    #define     VersionReg            0x37
    #define     AnalogTestReg         0x38
    #define     TestDAC1Reg           0x39  
    #define     TestDAC2Reg           0x3A   
    #define     TestADCReg            0x3B   
    #define     RFU3C                 0x3C   
    #define     RFU3D                 0x3D   
    #define     RFU3E                 0x3E   
    #define     RFU3F		  0x3F
    /////////////////////////////////////////////////////////////////////
    //MF522通信时返回的错误代码
    /////////////////////////////////////////////////////////////////////
    #define MI_OK                          0
    #define MI_NOTAGERR                    (-1)
    #define MI_ERR                         (-2)
    #endif
     
    展开查看代码---相应源代码
    
    #include 
    #include 
    #include "mfrc522.h"
    #include "system.h"
    #define MAXRLEN 18
    //////////////////////////////////
    //引脚定义
    //////////////////////////////////
    //RFID-RC522
    sbit     MF522_NSS  =    P1^4;	
    sbit     MF522_SCK  =    P1^1;
    sbit     MF522_SI   =    P1^0;
    sbit     MF522_SO   =    P1^2;
    sbit     MF522_RST  =    P1^3; 
    

    //////////////////////////////////////////////////////////////////////
    //读MFRC522中的数据
    //////////////////////////////////////////////////
    char M500PcdConfigISOType(unsigned char type){
    if (type == 'A') //ISO14443_A
    {
    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(ModeReg,0x3D);//3
    WriteRawRC(RxSelReg,0x86);//
    WriteRawRC(RFCfgReg,0x7F); //4F
    WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);
    WriteRawRC(TPrescalerReg,0x3E);
    delay(1);
    PcdAntennaOn();
    }
    else{ return -1; }

    return MI_OK;
    }
    /////////////////////////////////////////////////
    //MFRC中写入信息
    /////////////////////////////////////////////////
    void WriteRawRC(unsigned char Address,unsigned char value)
    {
    unsigned char i,ucAddr;
    MF522_SCK=0;
    MF522_NSS=0;
    ucAddr = (Address<<1)&0x7E;
    for(i=8;i>0;i--)
    {
    MF522_SI = ((ucAddr & 0x80)0x80);
    MF522_SCK = 1;
    ucAddr<<=1;
    MF522_SCK = 0;
    }
    for(i=8;i>0;i--)
    {
    MF522_SI = ((value&0x80)
    0x80);
    MF522_SCK = 1;
    value <<= 1;
    MF522_SCK = 0;
    }
    MF522_NSS = 1;
    MF522_SCK = 1;
    }
    //////////////////////////////////////////////
    //读RC522返回的数据
    //////////////////////////////////////////////
    unsigned char ReadRawRC(unsigned char Address)
    {
    unsigned char i,ucAddr;
    unsigned char res;
    MF522_SCK = 0;
    MF522_NSS = 0;
    ucAddr = (((Address<<1)&0x7e)|0x80);
    for(i=8;i>0;i--)
    {
    MF522_SI=((ucAddr&0x80)==0x80);
    MF522_SCK = 1;
    ucAddr<<=1;
    MF522_SCK=0;
    }
    for(i=8;i>0;i--)
    {
    MF522_SCK = 1;
    res<<=1;
    res|=(bit)MF522_SO;
    MF522_SCK=0;

    }
    MF522_NSS = 1;
    MF522_SCK = 1;
    return res;
    

    }
    /////////////////////////////////////////////////
    ////////////////////////////////////////////////
    void SetBitMask(unsigned char reg,unsigned char mask)
    {
    unsigned char tmp = 0x00;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp | mask); // clear bit mask
    }

    void ClearBitMask(unsigned char reg,unsigned char mask)
    {
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask); // clear bit mask
    }

    /////////////////////////////////////////////////////////////////////
    //选卡
    /////////////////////////////////////////////////////////////////////
    char PcdSelect(unsigned char *pSnr)
    {
    char status;
    unsigned char i;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x70;
    ucComMF522Buf[6] = 0;
    for (i=0; i<4; i++)
    {
    	ucComMF522Buf[i+2] = *(pSnr+i);
    	ucComMF522Buf[6]  ^= *(pSnr+i);
    }
    CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
    
    ClearBitMask(Status2Reg,0x08);
    
    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
    
    if ((status == MI_OK) && (unLen == 0x18))
    {   status = MI_OK;  }
    else
    {   status = MI_ERR;    }
    
    return status;
    

    }
    char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
    {
    char status;
    unsigned int unLen;
    unsigned char i,ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = auth_mode;
    ucComMF522Buf[1] = addr;
    for (i=0; i<6; i++)
    {    ucComMF522Buf[i+2] = *(pKey+i);   }
    for (i=0; i<6; i++)
    {    ucComMF522Buf[i+8] = *(pSnr+i);   }
    status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
    if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
    {   status = MI_ERR;   }   
    return status;
    

    }
    /////////////////////////////////////////////////////////////////////
    //读MFRC中的信息
    /////////////////////////////////////////////////////////////////////
    char PcdRead(unsigned char addr,unsigned char *pData)
    {
    char status;
    unsigned int unLen;
    unsigned char i,ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_READ;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
    
    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
    if ((status == MI_OK)&& unLen == 0x90)
    {
        for (i=0; i<16; i++)
        {    
    				*(pData+i) = ucComMF522Buf[i];
    			}
    }
    else
    {
    
    			status = MI_ERR;   
    	}
    
    return status;
    

    }
    char PcdWrite(unsigned char addr,unsigned char *pData)
    {
    char status;
    unsigned int unLen;
    unsigned char i,ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_WRITE;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
    
    if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {   status = MI_ERR;   }
     
    if (status == MI_OK)
    {
        for (i=0; i<16; i++)
        {    ucComMF522Buf[i] = *(pData+i);   }
        CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);
    
        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);
        if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {   status = MI_ERR;   }
    }
    
    return status;
    

    }
    /////////////////////////////////////////////////////////////////////
    //寻卡
    /////////////////////////////////////////////////////////////////////
    char PcdRequest(unsigned char req_code,unsigned char *pTagType)
    {
    char status;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ClearBitMask(Status2Reg,0x08);//
    WriteRawRC(BitFramingReg,0x07);
    SetBitMask(TxControlReg,0x03);//

    ucComMF522Buf[0] = req_code;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);

    if ((status == MI_OK) && (unLen == 0x10))
    {
    *pTagType = ucComMF522Buf[0];
    *(pTagType+1) = ucComMF522Buf[1];
    }
    else
    { status = MI_ERR; }

    return status;
    }
    /////////////////////////////////////////////////////////////////////
    //防冲撞
    /////////////////////////////////////////////////////////////////////
    char PcdAnticoll(unsigned char *pSnr)
    {
    char status;
    unsigned char i,snr_check=0;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x00);
    ClearBitMask(CollReg,0x80);
    
    ucComMF522Buf[0] = PICC_ANTICOLL1;
    ucComMF522Buf[1] = 0x20;
    
    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);
    
    if (status == MI_OK)
    {
    	 for (i=0; i<4; i++)
         {   
             *(pSnr+i)  = ucComMF522Buf[i];
             snr_check ^= ucComMF522Buf[i];
         }
         if (snr_check != ucComMF522Buf[i])
         {   status = MI_ERR;    }
    }
    
    SetBitMask(CollReg,0x80);
    return status;
    

    }
    ///////////////////////////////////////////////////
    //RC522和M1进行通讯
    ////////////////////////////////////////////////////
    char PcdComMF522(unsigned char Command,
    unsigned char *pInData,
    unsigned char InLenByte,
    unsigned char *pOutData,
    unsigned int *pOutLenBit)
    {
    char status = MI_ERR;
    unsigned char irqEn = 0x00;
    unsigned char waitFor = 0x00;
    unsigned char lastBits;
    unsigned char n;
    unsigned int i;
    switch (Command)
    {
    case PCD_AUTHENT:
    irqEn = 0x12;
    waitFor = 0x10;
    break;
    case PCD_TRANSCEIVE:
    irqEn = 0x77;
    waitFor = 0x30;
    break;
    default:
    break;
    }

    WriteRawRC(ComIEnReg,irqEn|0x80);			
    ClearBitMask(ComIrqReg,0x80);					
    WriteRawRC(CommandReg,PCD_IDLE);			
    SetBitMask(FIFOLevelReg,0x80);				
    
    for (i=0; i<InLenByte; i++)
    {   
    		WriteRawRC(FIFODataReg, pInData[i]);		
    }		
    WriteRawRC(CommandReg, Command);
    
    
    if (Command == PCD_TRANSCEIVE)
    {    
    		SetBitMask(BitFramingReg,0x80);  				//start TX
    	}		
    	
    i = 600;//¸ù¾ÝʱÖÓƵÂʵ÷Õû£¬²Ù×÷M1¿¨×î´óµÈ´ýʱ¼ä25ms
    do 
    {
         n = ReadRawRC(ComIrqReg);	
         i--;
    }
    while((i!=0) && !(n&0x01) && !(n&waitFor));
    	
    ClearBitMask(BitFramingReg,0x80);		//stop TX
          
    if (i!=0)
    {    
         if(!(ReadRawRC(ErrorReg)&0x1B))		
         {
             status = MI_OK;
             if (n & irqEn & 0x01)
             {   status = MI_NOTAGERR;   }
             if (Command == PCD_TRANSCEIVE)
             {
               	n = ReadRawRC(FIFOLevelReg);		
              	lastBits = ReadRawRC(ControlReg) & 0x07;		
                if (lastBits)
                {   *pOutLenBit = (n-1)*8 + lastBits;   }
                else
                {   *pOutLenBit = n*8;   }
                if (n == 0)
                {   n = 1;    }
                if (n > MAXRLEN)
                {   n = MAXRLEN;   }
                for (i=0; i<n; i++)
                {   pOutData[i] = ReadRawRC(FIFODataReg);    }		
            }
         }
         else
         {   status = MI_ERR;   }
    

    }
    SetBitMask(ControlReg,0x80); // stop timer now
    WriteRawRC(CommandReg,PCD_IDLE);
    return status;
    }
    /////////////////////////////////////////////////////////////////////
    //CRC计算
    /////////////////////////////////////////////////////////////////////
    void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
    {
    unsigned char i,n;
    ClearBitMask(DivIrqReg,0x04);
    WriteRawRC(CommandReg,PCD_IDLE);
    SetBitMask(FIFOLevelReg,0x80);
    for (i=0; i<len; i++)
    { WriteRawRC(FIFODataReg, *(pIndata+i)); }
    WriteRawRC(CommandReg, PCD_CALCCRC);
    i = 0xFF;
    do
    {
    n = ReadRawRC(DivIrqReg);
    i--;
    }
    while ((i!=0) && !(n&0x04)); //¼ì²âCRCÍê³É±ê־λ
    pOutData[0] = ReadRawRC(CRCResultRegL); //¶ÁCRC¼ÆËã½á¹û
    pOutData[1] = ReadRawRC(CRCResultRegM);
    }
    /////////////////////////////////////////////////////////////////////
    //命令卡片进入休眠状态
    /////////////////////////////////////////////////////////////////////
    char PcdHalt(void)
    {
    char status;
    unsigned int unLen;
    unsigned char ucComMF522Buf[MAXRLEN];

    ucComMF522Buf[0] = PICC_HALT;
    ucComMF522Buf[1] = 0;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
    
    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
    
    return MI_OK;
    

    }
    /////////////////////////////////////////////////////////////////////
    //重置
    /////////////////////////////////////////////////////////////////////
    char PcdReset(void)
    {
    MF522_RST=1;
    nop();
    MF522_RST=0;
    nop();
    MF522_RST=1;
    nop();
    WriteRawRC(CommandReg,PCD_RESETPHASE);
    nop();

    WriteRawRC(ModeReg,0x3D);       		
    WriteRawRC(TReloadRegL,30);       	   
    WriteRawRC(TReloadRegH,0);
    WriteRawRC(TModeReg,0x8D);					
    WriteRawRC(TPrescalerReg,0x3E);			
    WriteRawRC(TxAutoReg,0x40);				
    
    return MI_OK;
    

    }
    /////////////////////////////////////////////////////////////////////
    //打开天线
    /////////////////////////////////////////////////////////////////////
    void PcdAntennaOn(){
    unsigned char i;
    i = ReadRawRC(TxControlReg);
    if (!(i & 0x03))
    {
    SetBitMask(TxControlReg, 0x03);
    }
    }
    /////////////////////////////////////////////////////////////////////
    //关闭代码
    /////////////////////////////////////////////////////////////////////
    void PcdAntennaOff()
    {
    ClearBitMask(TxControlReg, 0x03);
    }

      代码的头文件实现,并不是我自己写的,是在网上找的一份代码。单片机是我在学习的嵌入式后自学的,所以在看数据手册的时候还是有一些吃力,建议大家在看完芯片的基本工作模式后,可以根据头文件的相关函数来读芯片手册,这样会对新手友好一点。
    3.4.2 uart中断函数

    要让RC522工作起来,必须的顺序是:寻卡--->防冲撞--->选卡--->开天线--->读/写卡。主函数的编写必须要按照这样的顺序,否者设备不会工作。
      因为51当中就这样写程序,将没有办法看到RC522读取到的数据,所以,我在写了一个串口中断程序。利用串口通信助手来检查是否读取到正确的数据。

    串口中断头文件
    
    #ifndef _UART_H_
    #define _UART_H_
    void initUart();
    #endif
    
    串口中断源文件
    
    #include "uart.h"
    #include "reg52.h"
    ///////////////////////////////////////////////////
    //初始化串口中断
    //////////////////////////////////////////////////
    void initUart()
    {
    	SCON=0X50;			
    	TMOD=0X20;			
    	PCON=0X00;			
    	TH1=0XFA;		    
    	REN = 1;
    	ES=1;						
    	EA=1;						
    	TR1=1;				
    }
    

      注:这些串口中断的相关配置,后面我会在写单片机学习的时候在写。

    3.4.3 主函数其他函数
    头文件
    
    #ifndef _SYSTEM_H_
    #define _SYSTEM_H_
    #define OSC_FREQ          22118400L
    #define  RCAP2_50us      65536L - OSC_FREQ/40417L
    #define  RCAP2_1ms       65536L - OSC_FREQ/2000L
    #define  RCAP2_10ms      65536L - OSC_FREQ/1200L
    #define  TIME0_500us     65536L - OSC_FREQ/8000L
    #define  TIME0_10ms      65536L - OSC_FREQ/200
    #define CALL_isr_UART()         TI = 1
    #define CALL_isw_UART()          RI = 1
    #define TRUE 1
    #define FALSE 0
    void initSystem();
    void delay(unsigned char i);
    void feeb();
    #endif
    
    源文件
    
    #include 
    #include "uart.h"
    #include 
    #include "system.h"
    char code DefaultKey[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //卡片密码
    unsigned char g_ucTempbuf1[4];  //返回的卡号
    static unsigned char g_ucTempbuf2[17]; //读出数据存放
    sfr   RCAP2LH =   0xCA;
    sfr   T2LH    =   0xCC;
    sbit f = P2^5;
    sbit led = P2^0;
    unsigned char addr;
    unsigned char len;
    unsigned char dataLen=17;//获取数据的长度
    ///////////////////////////////////////////
    //初始化¯
    //////////////////////////////////////////
    void initSystem()
    {
    	initUart();					
    	PcdReset();					
            PcdAntennaOff(); 
            PcdAntennaOn();
    	//M500PcdConfigISOType('A');
    	addr = 0;
    }
    ///////////////////////////////////////////////////////////////////////
    // Delay 10ms
    ///////////////////////////////////////////////////////////////////////
    void delay(unsigned int _10ms)
    {
        #ifndef NO_TIMER2
        RCAP2LH = RCAP2_10ms;
        T2LH    = RCAP2_10ms;
    
    TR2 = TRUE;
    while (_10ms--)
    {
        while (!TF2);
        TF2 = FALSE;
    }
    TR2 = FALSE;
    #else
    while (_10ms--)
    {
        delay_50us(19);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid )
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(20);
        if (CmdValid)
            return;
        delay_50us(19);
        if (CmdValid)
            return;
    }
    #endif
    

    }
    ///////////////////////////////////////////////
    //蜂鸣器响应
    ///////////////////////////////////////////////
    void feeb()
    {
    f=1;
    delay(1);
    f=0;
    delay(1);

    }

    void LED()
    {
    led=0;
    delay(1);
    led=1;
    delay(1);

    }
    ///////////////////////////////////////////////////
    //串口中单程序
    //////////////////////////////////////////////////
    void isr_UART() interrupt 4 using 1
    {
    unsigned char i;
    if(TI){
    TI=0;
    for(i=0;i<dataLen;i++){
    SBUF=g_ucTempbuf2[i];
    while(!TI);
    TI=0;
    }
    REN=1;
    }
    }
    ///////////////////////////////////////////////
    //读卡程序
    /////////////////////////////////////////////
    void readCart()
    {
    char status;
    while(1)
    {
    unsigned char status;

    status = PcdRequest(PICC_REQALL, g_ucTempbuf1);//寻卡
    	if (status == MI_OK)
    	{
    		status = PcdAnticoll(g_ucTempbuf1); 
    	}
    	
    	if (status == MI_OK)
    	{
    		status = PcdSelect(g_ucTempbuf1);    //选卡
    	}
      
    	if (status == MI_OK) 
    	{
    		status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf1);//打开天线
    		feeb();
    	}
    	if (status == MI_OK)   
    	{
    		status = PcdRead(1, g_ucTempbuf2);//读卡
    	}
    	if(status == MI_OK)
    	{
    		g_ucTempbuf2[16]=0x11;
    		CALL_isr_UART();
    		LED();
    	}
    

    }
    }

    }

      主函数

    #include "system.h"
    void main()
    {
    	initSystem();
    	readCart();
    }
    

      以上代码可以完成我们读写卡的基本需求,我的上一篇博文其实就是为这个项目服务而写的一个简单的终端程序。

  • 相关阅读:
    【转】5亿个数找中位数
    C++二维数组名的再探索
    转载 图像卷积
    PowerDesigner的使用一
    Spring注解详解
    JSP页面以及简单的指令
    Javascript学习总结
    html第一天
    Chrome开发,debug的使用方法。
    SVN使用
  • 原文地址:https://www.cnblogs.com/kadcyh/p/14465755.html
Copyright © 2011-2022 走看看