找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2071|回复: 0
收起左侧

基于校园卡的rc522电子锁单片机源码

[复制链接]
ID:354640 发表于 2018-6-19 20:31 | 显示全部楼层 |阅读模式
这是我写的基于校园卡的电子锁
附件里面有源代码


单片机源程序如下:

  1. #include "rc522.h"
  2. #include <reg52.h>
  3. #define uchar unsigned char
  4. #define uint  unsigned int

  5. sbit CS = P2 ^ 0;            //片选信号 //lcd屏的引脚
  6. sbit SID = P2 ^ 1;                //数据信号
  7. sbit SCLK = P2 ^ 2;                //时钟信号
  8. sbit CH = P2 ^ 3;                //并行、串行选择信号
  9. sbit LED=P1^7;//蜂鸣器

  10. sbit  SDA = P0^0        ; //PF0         SDA  rc522的引脚定义
  11. sbit  SCK = P0^1        ; //PF1
  12. sbit  MOSI =P0^2 ; //PF2
  13. sbit  MISO =P0^3        ; //PF3
  14. sbit  RST  =P0^4        ; //PF4



  15. /**串口数据使用**/
  16. #define         RX1_Lenth                32                        //串口接收缓冲长度
  17. uchar t=0;
  18. uchar status;
  19. uchar a=0x13, b=0x8C, c=0xBE, d=0x27 ;
  20. uchar e,f,g,h;

  21. uchar        idata RX1_Buffer[32];        //接收缓冲
  22. uchar        TX1_Cnt;        //发送计数
  23. uchar        RX1_Cnt;        //接收计数
  24. bit                B_TX1_Busy;        //发送忙标志




  25. uchar buff[4] = { 0 };
  26. uchar send[4]=0;
  27. int i=0;

  28. unsigned char g_ucTempbuf[6];

  29. void delayms(uint t) //1毫秒延时
  30. {
  31.         uint i, j;
  32.         for (i = 0; i<t; i++)
  33.                 for (j = 0; j<112; j++);
  34. }



  35. void delay(uint t) //0.1毫秒延时
  36. {
  37.         uint i, j;
  38.         for (i = 0; i<t; i++)
  39.                 for (j = 0; j<10; j++);
  40. }





  41. /////////////////////////////////////////////////////////////////////
  42. //功    能:寻卡
  43. //参数说明: req_code[IN]:寻卡方式
  44. //                0x52 = 寻感应区内所有符合14443A标准的卡
  45. //                0x26 = 寻未进入休眠状态的卡
  46. //          pTagType[OUT]:卡片类型代码
  47. //                0x4400 = Mifare_UltraLight
  48. //                0x0400 = Mifare_One(S50)
  49. //                0x0200 = Mifare_One(S70)
  50. //                0x0800 = Mifare_Pro(X)
  51. //                0x4403 = Mifare_DESFire
  52. //返    回: 成功返回MI_OK
  53. /////////////////////////////////////////////////////////////////////
  54. char PcdRequest(unsigned char req_code,unsigned char *pTagType)
  55. {
  56.    char status;  
  57.    unsigned int  unLen;
  58.    unsigned char ucComMF522Buf[MAXRLEN];

  59.    ClearBitMask(Status2Reg,0x08);
  60.    WriteRawRC(BitFramingReg,0x07);
  61.    SetBitMask(TxControlReg,0x03);

  62.    ucComMF522Buf[0] = req_code; //寻卡方式

  63.    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
  64.                       //rc522命令字,发给卡片的数据,发送数据的字节长,接收的数据,数据长
  65.    
  66.    if ((status == MI_OK) && (unLen == 0x10))
  67.    {   
  68.        *pTagType     = ucComMF522Buf[0];
  69.        *(pTagType+1) = ucComMF522Buf[1];
  70.    }
  71.    else
  72.    {   status = MI_ERR;  
  73.         }
  74.    
  75.    return status;
  76. }

  77. /////////////////////////////////////////////////////////////////////
  78. //功    能:防冲撞
  79. //参数说明: pSnr[OUT]:卡片序列号,4字节
  80. //返    回: 成功返回MI_OK
  81. /////////////////////////////////////////////////////////////////////  
  82.     char PcdAnticoll(unsigned char *pSnr)
  83. {
  84.     char status;
  85.     unsigned char i;
  86.     unsigned int  unLen;
  87.     unsigned char ucComMF522Buf[MAXRLEN];
  88.    

  89.     ClearBitMask(Status2Reg,0x08);
  90.     WriteRawRC(BitFramingReg,0x00);
  91.     ClearBitMask(CollReg,0x80);

  92.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  93.     ucComMF522Buf[1] = 0x20;

  94.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

  95.     if (status == MI_OK)
  96.     {
  97.              for (i=0; i<16; i++)
  98.          {   
  99.              *(pSnr+i)  = ucComMF522Buf[i];
  100.               

  101.          }
  102.         status=1;
  103.     }
  104.    
  105.     SetBitMask(CollReg,0x80);
  106.     return status;
  107. }



  108. char PcdReset(void) //初始化
  109. {
  110.        
  111.      RST=1;
  112.                 delay(1);                  
  113.      RST=0;
  114.                 delay(1);                  
  115.      RST=1;
  116.                 delay(1);                        
  117.     WriteRawRC(CommandReg,PCD_RESETPHASE);
  118.                 delay(1);                  
  119.    
  120.     WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
  121.     WriteRawRC(TReloadRegL,30);           
  122.     WriteRawRC(TReloadRegH,0);
  123.     WriteRawRC(TModeReg,0x8D);
  124.     WriteRawRC(TPrescalerReg,0x3E);
  125.     WriteRawRC(TxAutoReg,0x40);
  126.     return MI_OK;
  127. }

  128. /////////////////////////////////////////////////////////////////////
  129. //功    能:读RC522寄存器
  130. //参数说明:Address[IN]:寄存器地址
  131. //返    回:读出的值
  132. /////////////////////////////////////////////////////////////////////
  133. unsigned char ReadRawRC(unsigned char Address)
  134. {
  135.      unsigned char i, ucAddr;
  136.      unsigned char ucResult=0;

  137.       SCK = 0;
  138.       SDA = 0;
  139.      ucAddr = ((Address<<1)&0x7E)|0x80;

  140.      for(i=8;i>0;i--)
  141.      {
  142.          MOSI = ((ucAddr&0x80)==0x80);
  143.           SCK = 1;
  144.          ucAddr <<= 1;
  145.           SCK = 0;
  146.                  
  147.      }

  148.      for(i=8;i>0;i--)
  149.      {
  150.           SCK = 1;
  151.          ucResult <<= 1;
  152.          ucResult|=MISO;
  153.           SCK = 0;
  154.                  
  155.      }

  156.       SDA = 1;
  157.       SCK = 1;
  158.      return ucResult;
  159. }

  160. /////////////////////////////////////////////////////////////////////
  161. //功    能:写RC522寄存器
  162. //参数说明:Address[IN]:寄存器地址
  163. //          value[IN]:写入的值
  164. /////////////////////////////////////////////////////////////////////
  165. void WriteRawRC(unsigned char Address, unsigned char value)
  166. {  
  167.     unsigned char i, ucAddr;

  168.      SCK = 0;
  169.      SDA = 0;
  170.     ucAddr = ((Address<<1)&0x7E);

  171.     for(i=8;i>0;i--)
  172.     {
  173.         MOSI = ((ucAddr&0x80)==0x80);
  174.          SCK = 1;
  175.         ucAddr <<= 1;
  176.          SCK = 0;
  177.        
  178.     }

  179.     for(i=8;i>0;i--)
  180.     {
  181.         MOSI = ((value&0x80)==0x80);
  182.         SCK = 1;
  183.         value <<= 1;
  184.         SCK = 0;
  185.                
  186.     }
  187.      SDA = 1;
  188.      SCK = 1;
  189. }

  190. /////////////////////////////////////////////////////////////////////
  191. //功    能:置RC522寄存器位
  192. //参数说明:reg[IN]:寄存器地址
  193. //          mask[IN]:置位值
  194. /////////////////////////////////////////////////////////////////////
  195. void SetBitMask(unsigned char reg,unsigned char mask)  
  196. {
  197.     char tmp = 0x0;
  198.     tmp = ReadRawRC(reg);
  199.     WriteRawRC(reg,tmp | mask);  // set bit mask
  200. }

  201. /////////////////////////////////////////////////////////////////////
  202. //功    能:清RC522寄存器位
  203. //参数说明:reg[IN]:寄存器地址
  204. //          mask[IN]:清位值
  205. /////////////////////////////////////////////////////////////////////
  206. void ClearBitMask(unsigned char reg,unsigned char mask)  
  207. {
  208.     char tmp = 0x0;
  209.     tmp = ReadRawRC(reg);
  210.     WriteRawRC(reg, tmp & ~mask);  // clear bit mask
  211. }

  212. /////////////////////////////////////////////////////////////////////
  213. //功    能:通过RC522和ISO14443卡通讯
  214. //参数说明:Command[IN]:RC522命令字
  215. //          pInData[IN]:通过RC522发送到卡片的数据
  216. //          InLenByte[IN]:发送数据的字节长度
  217. //          pOutData[OUT]:接收到的卡片返回数据
  218. //          *pOutLenBit[OUT]:返回数据的位长度
  219. /////////////////////////////////////////////////////////////////////
  220. char PcdComMF522(unsigned char Command,  //命令
  221.                  unsigned char *pInData, //rc522到卡片的数据
  222.                  unsigned char InLenByte,//发送数据的字节长度
  223.                  unsigned char *pOutData, //收到的数据
  224.                  unsigned int  *pOutLenBit)//接受数据的字节长度长度
  225. {
  226.     char status = MI_ERR;
  227.     unsigned char irqEn   = 0x00;
  228.     unsigned char waitFor = 0x00;
  229.     unsigned char lastBits;
  230.     unsigned char n;
  231.     unsigned int i;
  232.     switch (Command)
  233.     {
  234.        case PCD_AUTHENT: //验证密钥
  235.           irqEn   = 0x12;
  236.           waitFor = 0x10;
  237.           break;
  238.        case PCD_TRANSCEIVE://发送并接受数据
  239.           irqEn   = 0x77;
  240.           waitFor = 0x30;
  241.           break;
  242.        default:
  243.          break;
  244.     }
  245.    
  246.     WriteRawRC(ComIEnReg,irqEn|0x80);
  247.     ClearBitMask(ComIrqReg,0x80);
  248.     WriteRawRC(CommandReg,PCD_IDLE);
  249.     SetBitMask(FIFOLevelReg,0x80);
  250.    
  251.     for (i=0; i<InLenByte; i++)
  252.     {   WriteRawRC(FIFODataReg, pInData[i]);    }
  253.     WriteRawRC(CommandReg, Command);
  254.    
  255.    
  256.     if (Command == PCD_TRANSCEIVE)
  257.     {    SetBitMask(BitFramingReg,0x80);  }
  258.    
  259.     i = 1000;//根据时钟频率调整,操作M1卡最大等待时间25ms
  260.     do
  261.     {
  262.          n = ReadRawRC(ComIrqReg);
  263.          i--;
  264.     }
  265.     while ((i!=0) && !(n&0x01) && !(n&waitFor));
  266.     ClearBitMask(BitFramingReg,0x80);
  267.              
  268.     if (i!=0)
  269.     {   
  270.          if(!(ReadRawRC(ErrorReg)&0x1B))
  271.          {
  272.              status = MI_OK;
  273.              if (n & irqEn & 0x01)
  274.              {   status = MI_NOTAGERR;   }
  275.              if (Command == PCD_TRANSCEIVE)
  276.              {
  277.                        n = ReadRawRC(FIFOLevelReg);
  278.                       lastBits = ReadRawRC(ControlReg) & 0x07;
  279.                 if (lastBits)
  280.                 {   *pOutLenBit = (n-1)*8 + lastBits;   }
  281.                 else
  282.                 {   *pOutLenBit = n*8;   }
  283.                 if (n == 0)
  284.                 {   n = 1;    }
  285.                 if (n > MAXRLEN)
  286.                 {   n = MAXRLEN;   }
  287.                 for (i=0; i<n; i++)
  288.                 {   pOutData[i] = ReadRawRC(FIFODataReg);    }
  289.             }
  290.          }
  291.          else
  292.          {   status = MI_ERR;   }
  293.         
  294.    }
  295.    

  296.    SetBitMask(ControlReg,0x80);           // stop timer now
  297.    WriteRawRC(CommandReg,PCD_IDLE);
  298.    return status;
  299. }


  300. /////////////////////////////////////////////////////////////////////
  301. //开启天线  
  302. //每次启动或关闭天险发射之间应至少有1ms的间隔
  303. /////////////////////////////////////////////////////////////////////
  304. void PcdAntennaOn()
  305. {
  306.     unsigned char i;
  307.     i = ReadRawRC(TxControlReg);
  308.     if (!(i & 0x03))
  309.     {
  310.         SetBitMask(TxControlReg, 0x03);
  311.     }
  312. }


  313. /////////////////////////////////////////////////////////////////////
  314. //关闭天线
  315. /////////////////////////////////////////////////////////////////////
  316. void PcdAntennaOff()
  317. {
  318.     ClearBitMask(TxControlReg, 0x03);
  319. }




  320. /********************************************************************
  321. * 名称 : Uart_Init()
  322. * 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
  323. * 输入 : 无
  324. * 输出 : 无
  325. ***********************************************************************/
  326. void Uart_Init(void)
  327. {
  328.      TMOD = 0x20;   //定时器工作在定时器1的方式2
  329.      PCON = 0x00;   //不倍频
  330.      SCON = 0x50;        //串口工作在方式1,并且启动串行接收       
  331.      TH1 = 0xFD;    //设置波特率 9600
  332.      TL1 = 0xFD;
  333.      TR1 = 1;                //启动定时器1
  334.          ES = 1;                //开串口中断
  335.          EA = 1;                //开总中断
  336.          RX1_Cnt=0;                //接受计数清零
  337.          TX1_Cnt = 0;        //发送计数清零
  338.          B_TX1_Busy = 0;//初始化判忙标志位               
  339. }


  340. void main()
  341. {
  342.        
  343.         PcdReset();  //复位
  344.         PcdAntennaOff();  //关天线
  345.         delay(100);      //延时10ms
  346.         PcdAntennaOn();    //开天线
  347.         delay(100);

  348.         Uart_Init();   //串口通信初始化
  349.          
  350.                               //连接云服务器
  351. //uchar idata buff1[47]="AT+CIPSTART=\"TCP\",\"60.205.224.195\",8234\r\n";
  352. //uchar idata buff2[16]="AT+CGACT=1,1\r\n";
  353. //uchar idata buff3[17]="AT+CIPTMODE=1\r\n";
  354. //         for(t=0;t<14;t++)
  355. //        {
  356. //                SBUF=buff4[t];delay(10);
  357. //        }
  358. //        delayms(1000);
  359. //        delayms(1000);

  360. //       
  361. //         for(t=0;t<16;t++)
  362. //        {
  363. //                SBUF=buff2[t];delay(10);
  364. //        }
  365. //        delayms(1000);
  366. //        delayms(1000);
  367. //  flag=0;
  368. //
  369. //        for(t=0;t<47;t++)
  370. //        {
  371. //                SBUF=buff1[t];delay(10);
  372. //        }
  373. //        delayms(1000);
  374. //        delayms(1000);
  375. //        delayms(1000);
  376. //        delayms(1000);
  377. //       
  378. //        flag=1;
  379. //       
  380. //        for(t=0;t<17;t++)
  381. //        {
  382. //                SBUF=buff3[t];delay(10);
  383. //        }
  384. //        delayms(1000);
  385. //        flag=0;
  386. //        write_com(0x80);delay(10);
  387. //                hzkdis("开始签到");
  388. ……………………

  389. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
rfid电子锁.zip (80.39 KB, 下载次数: 27)


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表