找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10332|回复: 7
打印 上一主题 下一主题
收起左侧

51单片机读写RC522卡(LCD12864)RFID开发程序与原理图

  [复制链接]
跳转到指定楼层
楼主
RFID RC522程序及原理

单片机源程序如下:
  1. #include "reg52.h"
  2. #include "main.h"
  3. #include "mfrc522.h"       
  4. #include "LCD12864.h"
  5. #include <string.h>
  6. #include <stdio.h>

  7. sbit BEEP=P0^1        ;
  8. #define SET_BEEP  BEEP = 0
  9. #define CLR_BEEP         BEEP = 1

  10. //M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
  11. //4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
  12. unsigned char code data2[4]  = {0x12,0,0,0};
  13. unsigned char code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
  14. //unsigned char g_ucTempbuf[20];   
  15. unsigned char idata MLastSelectedSnr[4];
  16. unsigned char idata RevBuffer[30];  
  17. //unsigned char data SerBuffer[20];
  18. bit CmdValid;                           

  19. unsigned char code ASCII_NUM[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  20. unsigned char idata LastKeyA[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//NO.2卡
  21. unsigned char idata NewKeyA[6]={0x19,0x84,0x07,0x15,0x76,0x14};//NO.2卡
  22. unsigned char idata NewKey[16]={0x19,0x84,0x07,0x15,0x76,0x14,
  23.                                 0xff,0x07,0x80,0x69,
  24.                                 0x19,0x84,0x07,0x15,0x76,0x14};

  25. unsigned char idata Read_Data[16]={0x00};

  26. //unsigned char idata RevBuffer[30];
  27. //unsigned char idata MLastSelectedSnr[4];
  28. unsigned char data OperationCard;

  29. uchar data bWarn,bPass;


  30. #define        REGCARD                        0xa1
  31. #define        CONSUME                        0xa2
  32. #define READCARD                0xa3
  33. #define ADDMONEY                0xa4

  34. void KeyScan(void)
  35. {
  36.                 if(REGCARDBTN == 0)//注册
  37.                 {
  38.                                 delay_10ms(1);
  39.                                 if(REGCARDBTN == 0 )
  40.                                                 OperationCard = REGCARD;       
  41.                                 LCD_PutString(0,3,"注册:");
  42.                 }
  43.                 if(CONSUMEBTN == 0)//消费
  44.                 {
  45.                                 delay_10ms(1);
  46.                                 if(CONSUMEBTN == 0 )
  47.                                                 OperationCard = CONSUME;
  48.                                 LCD_PutString(0,3,"消费:      ");       
  49.                 }
  50.                 if(ADDMONEYBTN == 0)//充值
  51.                 {
  52.                                 delay_10ms(1);
  53.                                 if(ADDMONEYBTN == 0 )
  54.                                                 OperationCard = ADDMONEY;       
  55.                                 LCD_PutString(0,3,"充值:      ");
  56.                 }
  57.                 if(READCARDBTN == 0)//读卡信息
  58.                 {
  59.                                 delay_10ms(1);
  60.                                 if(READCARDBTN == 0 )
  61.                                                 OperationCard = READCARD;       
  62.                                 LCD_PutString(0,3,"查询:      ");
  63.                 }
  64. }

  65. /*
  66. void delay(void)
  67. {
  68.         uint i ;
  69.         for(i=0;i++;i<100)
  70.         ;
  71. }

  72. void ShortBeep(void)
  73. {
  74.         uint i;
  75.         for(i=0;i<3;i++)
  76.         {
  77.                 SET_BEEP;            
  78.                 delay_10ms(3);
  79.                 CLR_BEEP;
  80.                 delay();
  81.         }
  82. }

  83. void LongBeep(void)
  84. {
  85.         uint i;
  86.         for(i=0;i<20;i++)
  87.         {
  88.                 SET_BEEP;            
  89.                 delay_10ms(5);
  90.                 CLR_BEEP;
  91.                 delay();
  92.         }
  93. }
  94. */
  95. void Warn(void)
  96. {         
  97.   uchar data ii;
  98.   for(ii=0;ii<3;ii++)
  99.   {
  100.     SET_BEEP;//ShortBeep();如果是有源蜂鸣器就一句SET_BEEP就ok了
  101.     delay_10ms(5);
  102.     CLR_BEEP;
  103.     delay_10ms(5);
  104.   }         
  105. }

  106. void Pass(void)
  107. {       
  108.   SET_BEEP;//LongBeep();如果是有源蜂鸣器就一句SET_BEEP就ok了
  109.   delay_10ms(30);
  110.   CLR_BEEP;
  111. }
  112. void CtrlProcess(void)
  113. {
  114.         //        unsigned char idata Write_First_Data[16];
  115.           char string[]="           ";
  116.                 unsigned char idata Write_Consume_Data[16];
  117.           
  118.                 signed long money_value;
  119.           float f_money_value;
  120.           unsigned char ii;
  121.           char status;

  122.           status=PcdRequest(PICC_REQIDL,&RevBuffer[0]);//寻天线区内未进入休眠状态的卡,返回卡片类型 2字节

  123.           if(status!=MI_OK)
  124.                           return;
  125.                
  126.                 for(ii=0;ii<2;ii++)
  127.                 {
  128.                                 string[2*ii]   = ASCII_NUM[(RevBuffer[ii]>>4)&0x0f];
  129.                                 string[2*ii+1] = ASCII_NUM[RevBuffer[ii]&0x0f];
  130.                 }
  131.                 string[4] = '\0';
  132.                 LCD_PutString(3,1,string);//LCD显示卡类型

  133.                 status=PcdAnticoll(&RevBuffer[2]);//防冲撞,返回卡的序列号 4字节
  134.                 
  135.                 if(status!=MI_OK)
  136.               return;

  137.           memcpy(MLastSelectedSnr,&RevBuffer[2],4);//4字节序列号 放到MLastSelectedSnr
  138.                 for(ii=0;ii<4;ii++)
  139.                 {
  140.                                 string[2*ii]   = ASCII_NUM[(MLastSelectedSnr[ii]>>4)&0x0f];
  141.                                 string[2*ii+1] = ASCII_NUM[MLastSelectedSnr[ii]&0x0f];
  142.                 }
  143.                 string[9] = '\0';
  144.                 LCD_PutString(3,2,string);// LCD显示序列号
  145.                
  146.           status=PcdSelect(MLastSelectedSnr);//选卡

  147.           if(status!=MI_OK)
  148.                     return;
  149.                
  150.                 if(OperationCard==REGCARD)//注册
  151.           {
  152.                     status=PcdAuthState(PICC_AUTHENT1A,7,LastKeyA,MLastSelectedSnr);//
  153.                     //DelayNS(1);
  154.                     if(status!=MI_OK)
  155.                     {
  156.                               bWarn=1;
  157.                               return;
  158.                     }
  159.                     status=PcdWrite(7,&NewKey[0]);
  160.                    
  161.                                 if(status!=MI_OK)
  162.                     {
  163.                               bWarn=1;
  164.                               return;
  165.                     }

  166.                     for(ii=0;ii<16;ii++)
  167.                     {
  168.                               Write_Consume_Data[ii]=0xaa;//Write_First_Data
  169.                     }
  170.                                 memset( Write_Consume_Data, 0, sizeof(Write_Consume_Data) );//Write_First_Data         Write_First_Data
  171.                                 money_value = 5000;
  172.                                 memcpy( Write_Consume_Data, ( uchar * )&money_value, 4 );        //Write_First_Data
  173.                    
  174.                                 status=PcdWrite(4,&Write_Consume_Data[0]);//Write_First_Data

  175.                     if(status!=MI_OK)
  176.                     {
  177.                               bWarn=1;
  178.                               return;
  179.                     }
  180.                                 LCD_PutString(0,3,"注册: 成功");
  181.                     bPass=1;                                               
  182.                     PcdHalt();               
  183.                 }
  184.           else if(OperationCard==READCARD)//读卡
  185.           {
  186.                     status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
  187.    
  188.                                 if(status!=MI_OK)
  189.                               return;
  190.                    
  191.                                 status=PcdRead(4,Read_Data);
  192.                    
  193.                                 if(status!=MI_OK)
  194.                     {
  195.                                                 bWarn=1;
  196.                               return;
  197.                     }

  198.                                 memcpy( (uchar *)&money_value, Read_Data, 4 );
  199.                                
  200.                                 LCD_PutString(0,3,"查询:      ");

  201.                                 f_money_value = money_value * 1.0/100;                       
  202.                                 sprintf(string,"%5.2f",f_money_value);       
  203.                                 LCD_PutString(3,4,string);

  204.                                 //ShowFloat816( 4, 5, ( f_money_value >= 0 ) ? ( ( f_money_value+0.5 )/100 ) : ( ( f_money_value-0.5 )/100 ) );
  205.                     if(f_money_value<0)
  206.                               bWarn=1;
  207.                     bPass=1;
  208.                     PcdHalt();       
  209.                 }
  210.           else if(OperationCard==CONSUME)//消费
  211.           {
  212.                     status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//
  213.                    
  214.                                 if(status!=MI_OK)
  215.                               return;
  216.                    
  217.                                 status=PcdRead(4,Read_Data);

  218.                     if(status!=MI_OK)
  219.                     {
  220.                               bWarn=1;
  221.                               return;
  222.                     }

  223.                     memcpy( (uchar *)&money_value, Read_Data, 4 );

  224.                     if(money_value<-10000)
  225.                               money_value=-10000;
  226.                     if(money_value<0)
  227.                               money_value+=10000;

  228.                     money_value=money_value-258;

  229.                                 memcpy( Write_Consume_Data, (uchar *)&money_value, 4 );

  230.                     status=PcdWrite(4,&Write_Consume_Data[0]);
  231.                
  232.                     if(status!=MI_OK)
  233.                     {
  234.                               bWarn=1;
  235.                               return;
  236.                     }               
  237.                                 //ShowFloat816(2,5,2.58);
  238.                                 LCD_PutString(0,3,"消费: 2.58   ");

  239.                                 f_money_value = money_value * 1.0/100;                       
  240.                                 sprintf(string,"%5.2f",f_money_value);       
  241.                                 LCD_PutString(3,4,string);
  242.                                 //ShowFloat816(4,5,( f_money_value >= 0 ) ? ( ( f_money_value+0.5 )/100 ) : ( ( f_money_value-0.5 )/100 ));
  243.                     if(money_value<0)
  244.                       bWarn=1;
  245.                     else
  246.                       bPass=1;
  247.                     PcdHalt();       
  248.                 }
  249.           else if(OperationCard==ADDMONEY)//充值
  250.           {               
  251.                     status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
  252.                    
  253.                                 if(status!=MI_OK)
  254.                               return;

  255.                     status=PcdRead(4,Read_Data);

  256.                     if(status!=MI_OK)
  257.                     {
  258.                               bWarn=1;
  259.                               return;
  260.                     }

  261.                                 memcpy( (uchar *)&money_value, Read_Data, 4 );
  262.                     if(money_value<-10000)
  263.                               money_value=-10000;
  264.                     if(money_value<0)
  265.                               money_value+=10000;
  266.                     money_value=money_value+5000;

  267.                                 memcpy( Write_Consume_Data, (uchar *)&money_value, 4 );

  268.                     status=PcdWrite(4,&Write_Consume_Data[0]);
  269.                            
  270.                                 if(status!=MI_OK)
  271.                     {
  272.                               bWarn=1;
  273.                               return;
  274.                     }       
  275.                                
  276.                                 //ShowFloat816(2,5,50.00);
  277.                                 LCD_PutString(0,3,"充值: 50.00  ");
  278.                                 f_money_value = money_value * 1.0/100;                       
  279.                                 sprintf(string,"%5.2f",f_money_value);       
  280.                                 LCD_PutString(3,4,string);
  281.                                 //ShowFloat816(4,5,( f_money_value >= 0 ) ? ( ( f_money_value+0.5 )/100 ) : ( ( f_money_value-0.5 )/100 ));
  282.                     bPass=1;
  283.                     PcdHalt();       
  284.                 }
  285.                 OperationCard = 0;                                         
  286. }

  287. void iccardcode()
  288. {             
  289.           unsigned char cmd;
  290.         unsigned char status;
  291.        
  292.         cmd = RevBuffer[0];
  293.         switch(cmd)
  294.         {
  295.                 case 1:     // Halt the card     //终止卡的操作
  296.                         status= PcdHalt();;                       
  297.                         RevBuffer[0]=1;
  298.                         RevBuffer[1]=status;
  299.                         break;                       
  300.                 case 2:     // Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)
  301.                                 // 寻卡,防冲突,选择卡    返回卡类型(2 bytes)+ 卡系列号(4 bytes)
  302.                         status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
  303.                         if(status!=0)
  304.                         {
  305.                                 status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
  306.                                 if(status!=0)                               
  307.                                 {
  308.                                         RevBuffer[0]=1;       
  309.                                         RevBuffer[1]=status;
  310.                                         break;
  311.                                 }
  312.                         }  
  313.                         RevBuffer[0]=3;       
  314.                         RevBuffer[1]=status;
  315.                         break;
  316.                        
  317.                 case 3:                         // 防冲突 读卡的系列号 MLastSelectedSnr
  318.                         status = PcdAnticoll(&RevBuffer[2]);
  319.                         if(status!=0)
  320.                         {
  321.                                 RevBuffer[0]=1;       
  322.                                 RevBuffer[1]=status;
  323.                                 break;
  324.                         }
  325.                         memcpy(MLastSelectedSnr,&RevBuffer[2],4);
  326.                         RevBuffer[0]=5;
  327.                         RevBuffer[1]=status;
  328.                         break;       
  329.                 case 4:                                    // 选择卡 Select Card
  330.                         status=PcdSelect(MLastSelectedSnr);
  331.                         if(status!=MI_OK)
  332.                         {
  333.                                 RevBuffer[0]=1;       
  334.                                 RevBuffer[1]=status;
  335.                                 break;
  336.                         }
  337.                         RevBuffer[0]=3;
  338.                         RevBuffer[1]=status;                       
  339.                         break;
  340.                 case 5:            // Key loading into the MF RC500's EEPROM
  341.             status = PcdAuthState(RevBuffer[1], RevBuffer[3], DefaultKey, MLastSelectedSnr);// 校验卡密码
  342.                         RevBuffer[0]=1;
  343.                         RevBuffer[1]=status;                       
  344.                         break;                                                       
  345.                 case 6:
  346.                         RevBuffer[0]=1;
  347.                         RevBuffer[1]=status;                       
  348.                         break;                               
  349.                 case 7:     
  350.                     RevBuffer[0]=1;
  351.                         RevBuffer[1]=status;                       
  352.                         break;
  353.                 case 8:     // Read the mifare card
  354.                             // 读卡
  355.                         status=PcdRead(RevBuffer[1],&RevBuffer[2]);
  356.                         if(status==0)
  357.                         {RevBuffer[0]=17;}
  358.                         else
  359.                         {RevBuffer[0]=1;}
  360.                         RevBuffer[1]=status;                       
  361.                         break;
  362.                 case 9:     // Write the mifare card
  363.                             // 写卡  下载密码
  364.                         status=PcdWrite(RevBuffer[1],&RevBuffer[2]);
  365.                         RevBuffer[0]=1;
  366.                         RevBuffer[1]=status;                       
  367.                         break;
  368.                 case 10:
  369.             PcdValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);
  370.                         RevBuffer[0]=1;       
  371.                         RevBuffer[1]=status;
  372.                         break;
  373.                 case 12:    // 参数设置
  374.                     PcdBakValue(RevBuffer[1], RevBuffer[2]);
  375.                         RevBuffer[0]=1;        //contact
  376.                         RevBuffer[1]=0;
  377.                         break;               
  378.         }






  379.         }
  380. /////////////////////////////////////////////////////////////////////
  381. //系统初始化
  382. /////////////////////////////////////////////////////////////////////
  383. void InitializeSystem()
  384. {
  385.     P0 = 0xFF; P1 = 0xFF; P3 = 0xFF;

  386.         ET2 = 0;        
  387.         T2CON = 0x04;                  //TR2=1 LYF
  388.     PCON = 0x00;//0x80;               
  389.     SCON = 0x70;//SMO SM1= 0 1 方式1,对于方式1,SM2=1,接收到有效的停止位时,将RI置1,REN置1时允许接收数据         
  390.     TMOD = 0x21;//TMOD = 0x22; TIMER1:C/T=0,定时器,M1M0=10,T1为工作模式2,即8位自动重装载模式
  391.                                                          //TIMER0: C/T=0,定时器,M1M0=01,16位计数器
  392.         TH1   = BAUD_2400;
  393.         TL1   = TH1;
  394.         TR1   = 1;             // T1 作为波特率发生器

  395.         TH0 = 0x60;
  396.     TL0 = 0x60;
  397.     TR0 = 0;
  398.    
  399.     ET0=0;
  400.         ET1=0;
  401.         EA=1;
  402.         //EX0=1;
  403.         //IT0 = 1;       
  404.         TR2=0;
  405.         ES = 1;   
  406.         CmdValid=0;

  407.      LED_GREEN = 1;
  408.      PcdReset();
  409.      PcdAntennaOff();
  410.      PcdAntennaOn();  
  411.          M500PcdConfigISOType( 'A' );
  412.      LED_GREEN = 0;
  413.          delay_10ms(10);       
  414.      LED_GREEN = 1;
  415.          delay_10ms(10);
  416.      LED_GREEN = 0;
  417. }

  418. /////////////////////////////////////////////////////////////////////
  419. //用T2做延时子程序
  420. /////////////////////////////////////////////////////////////////////


  421. ///////////////////////////////////////////////////////////////////////
  422. // 接收和发送中断
  423. ///////////////////////////////////////////////////////////////////////
  424. void isr_UART(void) interrupt 4 using 1
  425. {
  426.     unsigned char len, i;
  427.           unsigned int j=0;
  428.          
  429.           if(RI)
  430.         {               
  431.                 len=SBUF;
  432.                 RI=0;       
  433.                 for(i=0;i<len;i++)
  434.                 {
  435.                         while(!RI)
  436.                         {
  437.                                 j++;
  438.                                 if(j>1000)
  439.                                 {
  440.                                     break;
  441.                                 }
  442.                         }
  443.                         if(j<1000)
  444.                         {
  445.                                 RevBuffer[i]=SBUF;
  446.                                 RI=0;
  447.                                 j=0;
  448.                         }
  449.                         else
  450.                         {
  451.                             break;
  452.                         }
  453.                 }
  454.                 if(i==len)
  455.                 {
  456.                         REN=0;
  457.                         CmdValid=1;
  458.                 }
  459.         }
  460.         else if(!RI && TI)
  461.         {
  462.                 TI=0;
  463.                 len=RevBuffer[0];
  464.                 for(i=0;i<len+1;i++)
  465.                 {
  466.                         SBUF=RevBuffer[i];
  467.                         while(!TI);
  468.                         TI=0;                       
  469.                 }
  470.                 REN=1;
  471.         }
  472. }

  473. void UartProcess(void)
  474. {
  475.     unsigned char baud;

  476.                 if(RevBuffer[0]==11)            //为了加快相应速度 测试风鸣器
  477.                 {
  478.                                 RevBuffer[2]=RevBuffer[1];
  479.                           RevBuffer[0]=1;         //contact
  480.                                 RevBuffer[1]=0;
  481.                                 CALL_isr_UART();               
  482.         LED_GREEN = 1;
  483.                                 delay_10ms(RevBuffer[2]);
  484.         LED_GREEN = 0;
  485.                 }
  486.                 else if(RevBuffer[0]==13)   //设置通讯波特率
  487.           {
  488.                                 switch(RevBuffer[1])
  489.                                 {
  490.                                                 case 0:
  491.                                                                 baud=BAUD_9600;
  492.                                                                 break;
  493.                                                 case 1:
  494.                                                                 baud=BAUD_14400;
  495.                                                                 break;
  496.                                                 case 2:
  497.                                                                 baud=BAUD_19200;
  498.                                                                 break;
  499.                                                 case 3:
  500.                                                                 baud=BAUD_28800;
  501.                                                                 break;
  502.                                                 case 4:
  503.                                                                 baud=BAUD_38400;
  504.                                                                 break;
  505.                                                 case 5:
  506.                                                                 baud=BAUD_57600;
  507.                                                                 break;
  508.                                                 case 6:
  509.                                                                 baud=BAUD_115200;
  510.                                                                 break;
  511.                                                 default:
  512.                                                                 baud=BAUD_9600;
  513.                                                                 break;
  514.                                 }       
  515. ……………………

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

所有资料51hei提供下载:
6-51读写卡程序(LCD12864).rar (98.49 KB, 下载次数: 359)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:539433 发表于 2019-5-22 16:26 | 只看该作者
对于1602来说,这个程序适用吗?
回复

使用道具 举报

板凳
ID:551761 发表于 2019-6-18 12:13 | 只看该作者
原理图用什么软件画的
回复

使用道具 举报

地板
ID:679122 发表于 2020-1-1 20:38 | 只看该作者
小白H 发表于 2019-6-18 12:13
原理图用什么软件画的

AD软件。。。。。。。。
回复

使用道具 举报

5#
ID:704509 发表于 2020-3-8 13:02 | 只看该作者
感谢分享
回复

使用道具 举报

6#
ID:470242 发表于 2020-4-14 20:03 | 只看该作者
楼主,怎么没有显示呢?
回复

使用道具 举报

7#
ID:759554 发表于 2020-5-24 01:01 | 只看该作者
能问一下楼主UartProccess跟iccardcode两个函数的作用吗?什么情况下会调用呢?
回复

使用道具 举报

8#
ID:17396 发表于 2021-4-22 11:33 | 只看该作者
谢谢楼主分享。非常感谢,学习中
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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