• 基于51,人体红外感应和RC522的门禁系统


    总结一下最近学的东西,这两天学的东西,rfid门卡系统终于弄出来来了,这个程序算现在写过的比较满意的程序,大家可以参考参考

    主函数:

    #include<reg52.h>
    #include"mian.h"
    #include"rc522.h"
    #include"12864.h"
    
    //卡号为0扇区0块内容的前四字节为卡号,且此块内容不能改写
    uchar  status;
    uchar g_ucTempbuf[20];
    unsigned char hextoasc(unsigned char i)
    {
        if(i<0x09)
        {
            i=i+'0';
            return i;
        }
        else
        {
            i=i+0x37;
            return i;
        }
    }
    
    void main()
    {
        uint i;
        uchar flagren,flagzhenque;
        uchar xule[4] = "8171";
    
        //初始化:
         init_12864();
    
        
         lcd_pos(1,2);
         write_string("实验重地");
         lcd_pos(2,2);
         write_string("闲人免进");
         while(1)
         {
              flagren = hwgy();
              if(flagren == 1)
              break;
         }
    
         
         write_cmd(0x01);//清除lcd的显示内容
         lcd_pos(1,3);
         write_string("欢迎");
         lcd_pos(2,2);
         write_string("请刷卡!!");   
         
        PcdReset();//rc522初始化
        PcdAntennaOff(); //关闭和打开天线
        PcdAntennaOn();
        M500PcdConfigISOType('A');//设定工作模式
    
        //防冲突,这里需要一个循环,让读卡器不断去读卡
        while(1)
        {
            status = PcdRequest(PICC_REQALL, g_ucTempbuf);
            //PICC_REQALL他是个宏定义 意思是寻找天线内的所有卡片,
            // g_ucTempbuf 是个数组,在这里函数读取卡内的前两位放在数组中
            if(status != MI_OK)//没有找到卡,继续执行PcdRequest()
            {
                  continue;
            }
            
            status = PcdAnticoll(g_ucTempbuf);//防冲突
            //卡片序列号,4字节,这里的status可以判PcdAnticoll的执行情况
            //如果执行成功,表示g_ucTempbuf上面已经记在唯一的卡号了
            //在这里g_ucTempbuf已经用了2+4个
            if(status != MI_OK)//没有找到卡,继续执行PcdRequest()
            {
                  continue;
            }
    
            
            if(status == MI_OK)
            {
              LED_GREEN =0;
              
              for(i=0;i<4;i++)//在12864上显示卡号
              {
                if( hextoasc((g_ucTempbuf[i]&0xf0)>>4)  == xule[i])
                 {
                    write_cmd(0x01);
                    lcd_pos(1,2);
                    write_string("封韦杰");
                    lcd_pos(2,2);
                    write_string("请进!!");
                    flagzhenque = 1; 
                 }
                 else 
                 {
                    write_cmd(0x01);
                    flagzhenque = 0;
                    lcd_pos(1,3);
                    write_string("错误!");
                    lcd_pos(2,2);
                    write_string("请出示门卡!");
                     break;       //寻卡失败跳出循环
                    }
               }
               if(flagzhenque == 1)
               {
                      for(i=0;i<125;i++)
                         {
                            step();
                          }
                 }
              LED_GREEN = 1;
               }
        
           }
    
    }
    
    void DelayMs(unsigned int _MS)
    {
        TH1 = (unsigned char)(RCAP2_1ms>>8);
        TL1 = (unsigned char)(RCAP2_1ms);
    
        ET1     = 0;                                        // Disable timer2 interrupt
        TR1     = 1;
        while (_MS--)
        {  
            while (!TF1);
            TF1 = 0;
            TH1 = (unsigned char)(RCAP2_1ms>>8);
            TL1 = (unsigned char)(RCAP2_1ms);
        }
        TR1 = 0;
    }
    View Code

    rc522.c

    #include <intrins.h>
    #include <REG52.H>
    
    #include "mian.h"
    #include "rc522.h"
    #define MAXRLEN 18
                                  
    /////////////////////////////////////////////////////////////////////
    //功    能:寻卡
    //参数说明: req_code[IN]:寻卡方式
    //                0x52 = 寻感应区内所有符合14443A标准的卡
    //                0x26 = 寻未进入休眠状态的卡
    //          pTagType[OUT]:卡片类型代码
    //                0x4400 = Mifare_UltraLight
    //                0x0400 = Mifare_One(S50)
    //                0x0200 = Mifare_One(S70)
    //                0x0800 = Mifare_Pro(X)
    //                0x4403 = Mifare_DESFire
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////
    
    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;
    }
    /////////////////////////////////////////////////////////////////////
    //功    能:防冲撞
    //参数说明: pSnr[OUT]:卡片序列号,4字节
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////  
    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;
    }
    
    /////////////////////////////////////////////////////////////////////
    //功    能:选定卡片
    //参数说明: pSnr[IN]:卡片序列号,4字节
    //返    回: 成功返回MI_OK
    
    /////////////////////////////////////////////////////////////////////
    /*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;
    }
     */
    /////////////////////////////////////////////////////////////////////
    //功    能:验证卡片密码
    //参数说明: auth_mode[IN]: 密码验证模式
    //                 0x60 = 验证A密钥
    //                 0x61 = 验证B密钥 
    //          addr[IN]:块地址
    //          pKey[IN]:密码
    //          pSnr[IN]:卡片序列号,4字节
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////               
    /*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);   }
     //   memcpy(&ucComMF522Buf[2], pKey, 6); 
     //   memcpy(&ucComMF522Buf[8], pSnr, 4); 
        
        status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
        if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
        {   status = MI_ERR;   }
        
        return status;
    }
      */
    /////////////////////////////////////////////////////////////////////
    //功    能:读取M1卡一块数据
    //参数说明: addr[IN]:块地址
    //          pData[OUT]:读出的数据,16字节
    //返    回: 成功返回MI_OK
    ///////////////////////////////////////////////////////////////////// 
    /*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))
     //   {   memcpy(pData, ucComMF522Buf, 16);   }
        {
            for (i=0; i<16; i++)
            {    *(pData+i) = ucComMF522Buf[i];   }
        }
        else
        {   status = MI_ERR;   }
        
        return status;
    }
     */
    /////////////////////////////////////////////////////////////////////
    //功    能:写数据到M1卡一块
    //参数说明: addr[IN]:块地址
    //          pData[IN]:写入的数据,16字节
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////                  
    /*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)
        {
            //memcpy(ucComMF522Buf, pData, 16);
            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;
    }
     */
    /////////////////////////////////////////////////////////////////////
    //功    能:扣款和充值
    //参数说明: dd_mode[IN]:命令字
    //               0xC0 = 扣款
    //               0xC1 = 充值
    //          addr[IN]:钱包地址
    //          pValue[IN]:4字节增(减)值,低位在前
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////                 
    // char PcdValue(unsigned char dd_mode,unsigned char addr,unsigned char *pValue)
    // {
    //     char status;
    //     unsigned int  unLen;
    //     unsigned char i,ucComMF522Buf[MAXRLEN]; 
    //     
    //     ucComMF522Buf[0] = dd_mode;
    //     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)
    //     {
    //          // memcpy(ucComMF522Buf, pValue, 4);
    //             for (i=0; i<16; i++)
    //             {    ucComMF522Buf[i] = *(pValue+i);   }
    //             CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);
    //             unLen = 0;
    //             status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);
    //             if (status != MI_ERR)
    //             {    status = MI_OK;    }
    //     }
    //     
    //     if (status == MI_OK)
    //     {
    //             ucComMF522Buf[0] = PICC_TRANSFER;
    //             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;   }
    //     }
    //     return status;
    // }
    
    /////////////////////////////////////////////////////////////////////
    //功    能:备份钱包
    //参数说明: sourceaddr[IN]:源地址
    //          goaladdr[IN]:目标地址
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////
    // char PcdBakValue(unsigned char sourceaddr, unsigned char goaladdr)
    // {
    //     char status;
    //     unsigned int  unLen;
    //     unsigned char ucComMF522Buf[MAXRLEN]; 
    
    //     ucComMF522Buf[0] = PICC_RESTORE;
    //     ucComMF522Buf[1] = sourceaddr;
    //     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)
    //     {
    //         ucComMF522Buf[0] = 0;
    //         ucComMF522Buf[1] = 0;
    //         ucComMF522Buf[2] = 0;
    //         ucComMF522Buf[3] = 0;
    //         CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);
    //  
    //         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);
    //         if (status != MI_ERR)
    //         {    status = MI_OK;    }
    //     }
    //     
    //     if (status != MI_OK)
    //     {    return MI_ERR;   }
    //     
    //     ucComMF522Buf[0] = PICC_TRANSFER;
    //     ucComMF522Buf[1] = goaladdr;
    
    //     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;   }
    
    //     return status;
    // }
    
    
    /////////////////////////////////////////////////////////////////////
    //功    能:命令卡片进入休眠状态
    //返    回: 成功返回MI_OK
    /////////////////////////////////////////////////////////////////////
    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;
    }
    
    /////////////////////////////////////////////////////////////////////
    //用MF522计算CRC16函数
    /////////////////////////////////////////////////////////////////////
    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));
        pOutData[0] = ReadRawRC(CRCResultRegL);
        pOutData[1] = ReadRawRC(CRCResultRegM);
    }
     
    /////////////////////////////////////////////////////////////////////
    //功    能:复位RC522
    //返    回: 成功返回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);            //和Mifare卡通讯,CRC初始值0x6363
        WriteRawRC(TReloadRegL,30);           
        WriteRawRC(TReloadRegH,0);
        WriteRawRC(TModeReg,0x8D);
        WriteRawRC(TPrescalerReg,0x3E);
        WriteRawRC(TxAutoReg,0x40);     
        return MI_OK;
    }
    //////////////////////////////////////////////////////////////////////
    //设置RC632的工作方式 
    //////////////////////////////////////////////////////////////////////
    char M500PcdConfigISOType(unsigned char type)
    {
       if (type == 'A')                     //ISO14443_A
       { 
           ClearBitMask(Status2Reg,0x08);
    
     /*     WriteRawRC(CommandReg,0x20);    //as default   
           WriteRawRC(ComIEnReg,0x80);     //as default
           WriteRawRC(DivlEnReg,0x0);      //as default
           WriteRawRC(ComIrqReg,0x04);     //as default
           WriteRawRC(DivIrqReg,0x0);      //as default
           WriteRawRC(Status2Reg,0x0);//80    //trun off temperature sensor
           WriteRawRC(WaterLevelReg,0x08); //as default
           WriteRawRC(ControlReg,0x20);    //as default
           WriteRawRC(CollReg,0x80);    //as default
    */
           WriteRawRC(ModeReg,0x3D);//3F
    /*       WriteRawRC(TxModeReg,0x0);      //as default???
           WriteRawRC(RxModeReg,0x0);      //as default???
           WriteRawRC(TxControlReg,0x80);  //as default???
    
           WriteRawRC(TxSelReg,0x10);      //as default???
       */
           WriteRawRC(RxSelReg,0x86);//84
     //      WriteRawRC(RxThresholdReg,0x84);//as default
     //      WriteRawRC(DemodReg,0x4D);      //as default
    
     //      WriteRawRC(ModWidthReg,0x13);//26
           WriteRawRC(RFCfgReg,0x7F);   //4F
        /*   WriteRawRC(GsNReg,0x88);        //as default???
           WriteRawRC(CWGsCfgReg,0x20);    //as default???
           WriteRawRC(ModGsCfgReg,0x20);   //as default???
    */
              WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) 
           WriteRawRC(TReloadRegH,0);
           WriteRawRC(TModeReg,0x8D);
           WriteRawRC(TPrescalerReg,0x3E);
           
    
      //     PcdSetTmo(106);
           DelayMs(1);
           PcdAntennaOn();
       }
       else{ return -1; }
       
       return MI_OK;
    }
    /////////////////////////////////////////////////////////////////////
    //功    能:读RC632寄存器
    //参数说明:Address[IN]:寄存器地址
    //返    回:读出的值
    /////////////////////////////////////////////////////////////////////
    unsigned char ReadRawRC(unsigned char Address)
    {
         unsigned char i, ucAddr;
         unsigned char ucResult=0;
    
         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;
             ucResult <<= 1;
             ucResult|=(bit)MF522_SO;
             MF522_SCK = 0;
         }
    
         MF522_NSS = 1;
         MF522_SCK = 1;
         return ucResult;
    }
    
    /////////////////////////////////////////////////////////////////////
    //功    能:写RC632寄存器
    //参数说明:Address[IN]:寄存器地址
    //          value[IN]:写入的值
    /////////////////////////////////////////////////////////////////////
    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寄存器位
    //参数说明:reg[IN]:寄存器地址
    //          mask[IN]:置位值
    /////////////////////////////////////////////////////////////////////
    void SetBitMask(unsigned char reg,unsigned char mask)  
    {
        char tmp = 0x0;
        tmp = ReadRawRC(reg);
        WriteRawRC(reg,tmp | mask);  // set bit mask
    }
    
    /////////////////////////////////////////////////////////////////////
    //功    能:清RC522寄存器位
    //参数说明:reg[IN]:寄存器地址
    //          mask[IN]:清位值
    /////////////////////////////////////////////////////////////////////
    void ClearBitMask(unsigned char reg,unsigned char mask)  
    {
        char tmp = 0x0;
        tmp = ReadRawRC(reg);
        WriteRawRC(reg, tmp & ~mask);  // clear bit mask
    } 
    
    /////////////////////////////////////////////////////////////////////
    //功    能:通过RC522和ISO14443卡通讯
    //参数说明:Command[IN]:RC522命令字
    //          pInData[IN]:通过RC522发送到卡片的数据
    //          InLenByte[IN]:发送数据的字节长度
    //          pOutData[OUT]:接收到的卡片返回数据
    //          *pOutLenBit[OUT]:返回数据的位长度
    /////////////////////////////////////////////////////////////////////
    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);  }
        
    //    i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
     i = 2000;
        do 
        {
             n = ReadRawRC(ComIrqReg);
             i--;
        }
        while ((i!=0) && !(n&0x01) && !(n&waitFor));
        ClearBitMask(BitFramingReg,0x80);
              
        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;
    }
    
    
    /////////////////////////////////////////////////////////////////////
    //开启天线  
    //每次启动或关闭天险发射之间应至少有1ms的间隔
    /////////////////////////////////////////////////////////////////////
    void PcdAntennaOn()
    {
        unsigned char i;
        i = ReadRawRC(TxControlReg);
        if (!(i & 0x03))
        {
            SetBitMask(TxControlReg, 0x03);
        }
    }
    
    
    /////////////////////////////////////////////////////////////////////
    //关闭天线
    /////////////////////////////////////////////////////////////////////
    void PcdAntennaOff()
    {
        ClearBitMask(TxControlReg, 0x03);
    }
    View Code

    step.c

    #include<reg52.h>
    #define Step 500
    void step()
    {
        unsigned int i;
        P3 = 0x01;//0000 0001
        for(i = 0;i<Step;i++);
        P3 = 0x02;//0000 0010
        for(i = 0;i<Step;i++);
        P3 = 0x04;//0000 0100
        for(i = 0;i<Step;i++);
        P3 = 0x08;//0000 1000
        for(i = 0;i<Step;i++);
         
    }
    View Code

    12864.c

    #include"12864.h"
    #include<reg52.h>
    
    sbit lcdrs = P2^4;//数据还是指令选择端口
    sbit lcdwr = P2^5;//读写选择端口
    sbit lcden = P2^6;//使能端口
    sbit PSB = P2^1;//串并口选择端口
    
    /*uchar code table1[]={"Welcome!!"};
    uchar code table2[]={"Psw:"};
    uchar code table3[] ={"Open"};
    uchar code table4[] ={"Error try again!"};
    uchar code table5[] ={"Error 3 times!!"};*/
    
    void delay1ms(uint x)//延时函数
    {
        uint i,j;
        for(i= x;i>0;i--)
            for(j=110;j>0;j--);
    }
    
    void write_cmd(uchar cmd)//写指令函数
    {
        lcdrs = 0;
        lcdwr = 0;
        P0 = cmd;
        lcden = 1;
        delay1ms(5);//
        lcden = 0;
    }
    
    void write_date(uchar date)//写数据函数
    {
        lcdrs = 1;
        lcdwr = 0;
        P0 = date;
        lcden = 1;
        delay1ms(5);//
        lcden = 0;
    }
    
    void write_string(uchar *str)//写入字符串函数
    {
        
        
        for(;*str!='';str++)
        {
                write_date(*str);
                delay1ms(2);
        }
        
    }
    
    void init_12864()
    {
        PSB = 1;//并口方式传送数据
        write_cmd(0x30);//基本指令操作
        write_cmd(0x0c);//开显示,关光标
        write_cmd(0x01);//清除lcd的显示内容
    }
    
    void lcd_putpic(unsigned char code *img)//画图函数
    {
        uint i,j;
        //画图上半部分
        for(i = 0;i<32;i++)
        {
            write_cmd(0x80+i);//
            write_cmd(0x80);//
            for(j=0;j<16;j++)
            {
                write_date(*img);
                img++;
            }
        }
        //画下部分的屏幕   
        for(i = 0;i<32;i++)
        {
            write_cmd(0x80+i);//设定列
            write_cmd(0x88);//从第三行开始画图
            for(j=0;j<16;j++)
            {
                write_date(*img);
                img++;
            }
        }
    }
    
    void setpic()//设定画图功能的函数
    {
        write_cmd(0x36);//设定画图其画图功能
        delay1ms(5);
    }
    
    void lcd_pos(uchar x,uchar y)//设定显示位置的函数
    {
        uchar pos;
        if(x==0)
            x=0x80;
        else 
            if(x==1)
                x=0x90;
            else 
                if(x==2)
                    x=0x88;
                else 
                    if(x==3)
                        x=0x98;
                    pos=x+y;
                    write_cmd(pos);
    }
    View Code

    hongwai.c

    #include<reg52.h>
    #include"12864.h"
    sbit led = P3^5;
    sbit hongwai = P3^6;
    
    uchar flag;
    
    uchar hwgy()
    {
        hongwai = 1;
       
        while(1)
         {            
             if(hongwai ==1)//检测到高电平的话,延时一下
             {
                 delay1ms(20);
                 if(hongwai == 1)//再次检测一下
                 {
                     led = 0;
                     flag = 1;
                     return flag;
                     break;
                 }
            }
            else
            {
            led = 1;
            flag = 0;
            return flag;
            }
            
       }
    
    }
    View Code

    头文件:

    12864.h

    #ifndef __12864_H__
    #define _12864_H__
    
    #include<reg52.h>
    typedef unsigned int uint;
    typedef unsigned char uchar;
    
    /*extern uchar code table1[] ;
    extern uchar code table2[] ;
    extern uchar code table3[] ;
    extern uchar code table4[] ;
    extern uchar code table5[] ;*/
    
    
    extern unsigned char code pic1[];
    void delay1ms(uint x);//延时函数
    void write_cmd(uchar cmd);//写指令函数
    void write_date(uchar date);//写数据函数
    
    void init_12864();
    void lcd_putpic(unsigned char code *img);//画图函数
    void setpic();//设定画图功能的函数
    void lcd_pos(uchar x,uchar y);//设定显示位置的函数
    void write_string(uchar *str);
    
    //红外感应模块
    uchar hwgy();
    #endif
    View Code

    main.h

    #ifndef __MIAN_H_
    #define __MIAN_H_
    
    //////////////////////////////////
    //端口定义
    /////////////////////////////////////////////////////////////////////
    //MFRC500
    sbit     MF522_RST  =    P1^1;                   //RC500??
    sbit     MF522_NSS  =    P1^7;
    sbit     MF522_SCK  =    P1^6;
    sbit     MF522_SI   =    P1^5;
    sbit     MF522_SO   =    P1^2;
    //???
    sbit     LED_GREEN  =    P1^0;  
    /////////////////////////////////////////////////////////////////////
    //函数原型
    /////////////////////////////////////////////////////////////////////
    void InitializeSystem(); 
    void step();                                  
                                        
    
    #define  OSC_FREQ        7372800L
    #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
    void DelayMs(unsigned int _MS);
    
    #endif
    View Code

    rc522.h

    /////////////////////////////////////////////////////////////////////
    //函数原型
    /////////////////////////////////////////////////////////////////////
    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);
    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 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               //CRC计算
    
    /////////////////////////////////////////////////////////////////////
    //Mifare_One卡片命令字
    /////////////////////////////////////////////////////////////////////
    #define PICC_REQIDL           0x26               //寻天线区内未进入休眠状态
    #define PICC_REQALL           0x52               //寻天线区内全部卡
    #define PICC_ANTICOLL1        0x93               //防冲撞
    #define PICC_ANTICOLL2        0x95               //防冲撞
    #define PICC_AUTHENT1A        0x60               //验证A密钥
    #define PICC_AUTHENT1B        0x61               //验证B密钥
    #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)
    View Code

    完整版本的程序:请见:http://download.csdn.net/detail/generoius/6700269

    版权所有:转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3469995.html

  • 相关阅读:
    面向对象程序设计寒假作业3
    面向对象程序设计编程题完善1.0
    jq分片上传,可拖动上传
    给富文本框的头添加title
    vue的富文本编辑器使用,并且添加显示当前输入字数
    超出省略号
    关于缓存 windwo.localStorage和sessionStorage
    复制框里的内容
    同一标签添加多个背景图
    函数里添加超链接
  • 原文地址:https://www.cnblogs.com/fengdashen/p/3469995.html
Copyright © 2020-2023  润新知