找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12361|回复: 18
收起左侧

单片机读写RC522射频卡上位机调试软件及参考例程源码下载

  [复制链接]
ID:276417 发表于 2018-1-16 00:26 | 显示全部楼层 |阅读模式
通过stc89c52读写rc522模块资料包:
0.jpg

下位机(单片机)电路原理图:
0.jpg

上位机delphi源码与说明资料:
0.jpg

IC读写器使用说明
一、读写器连接
1.1 把通讯线“DB9”端插到PC 机的串口1/2
1.2 把通讯线2510端插到读写器的插座,使读写器和PC 机的串口良好连接
1.2 把电源线的“圆柱”端插到读写器的电源座子上
1.3读写器上电以后可以听到一声风鸣器的响声,如果没有听到风鸣器声,表明读写器没有正常上电.
二、启动Demo 软件
2.1 双击启动测试软件
2.2 如果串口良好连接的话可以听到一声风鸣器的响声,如果启动测试软件以后并没有听到风鸣器声表明串口通讯没有连接好,请检查串口连接线是否连接正确
三、M1卡片读写测试
3.1 把一张Mifare One 卡片放在天线区域范围内
3.2 进入功能选项“低级操作”里面点击“寻卡”,如果出现“寻卡成功!”表明寻卡正常,如果出现“执行失败!”表明出现异常,请检查卡片是否在寻卡范围内,如果确认卡片没有问题,那读写器有异常
3.3 点击“防冲突”,如果出现“执行成功”表明防冲突正常,如果出现“执行失败”表明读写器出现异常或者卡片没有在天线区域范围内
3.4 点击“选择”,如果出现“执行成功”表明选择正常,如果出现“执行失败”表明读写器出现异常或者卡片没有在天线区域范
围内
3.5 进入功能选项“密码下载”里面下载卡片密码,比如需要测试卡片扇区1 数据的读写,那么就在扇区1后面填上密码A/B(注:卡片的初始密码A/B 均为全‘F’),然后选择“A 组密码”或者“B 组密码”,最后点击“下载”,如果出现“密码下载成
功”表明密码下载成功,如果出现异常请按照错误提示更改后再下载一次,直至“下载成功”为止
3.6 进入功能选项“数据读写”里面,“请选择扇区号”下面的可拉选项里面选择第5步下载密码的扇区号(比如扇区1),然后点击“读出”,如果提示“第*扇区数据读出成功”表明读数据正确。如果出现“第*扇区数据读出失败”表明密码校验出错或者出现其他异常,请返回第5 步重新下载密码
3.7 如果读数据正确,在块0、块1、块2 后面修改数据,比如改成
“块012345678901234567890123456789012
“块123456789012345678901234567890123
“块234567890123456789012345678901234
然后点击“写入”,如果出现“第*扇区数据写入成功”表明写入数据正确。如果出现“第*扇区写入失败”表明密码校验出错或者出现其他异常,请返回第5 步重新下载密码
3.8 再次点击“读出”键,然后点击“读出”,如果提示“第*扇区数据读出成功”表明读数据正确,再对比块0、块1、块2 是否和第7 步写入的数据一样,如果数据一样,证明写入成功了。如果出现“第*扇区数据读出失败”表明密码校验出错或者出现其他异常,请返回第5 步重新下载密码。
四、Mifare One 卡片块值测试
4.1 进入功能选项“块值操作”里面,在“扇区号”下面的可拉选项里面选择第3.5 步下载密码的扇区号(比如扇区1),在“块号”下面的可拉选项里面选择你想测试的块号(比如第1 块)
4.2 在“操作值”后面填上你所希望的初始值(比如“11111111”),然后点击“初始化”,如果出现“数据初始化成功”表明操作成功。如果出现“数据初始化失败”表明操作失败,请检查密码是否正确,返回第3.1 步重新操作一次。
4.3 点击“读出”,如果在“当前值”后面出现是你原来写进去的初始值,证明操作正确,如果“数据读出失败”表明块值操作有异常,请重新初始化。
4.4 在“操作值:”后面填上你所希望的操作值(比如“22222222”),然后点击“加值”,如果出现“数值加操作成功”,表明操作成功。如果出现其他提示表明操作失败
4.4 点击“读出”,如果在“当前值:”后面出现是你初始值加上加值(111111112222222233333333)表明操作正确,如果是其他的值表明失败
4.5 在“操作值:”后面填上你所希望的操作值(比如“11111111”),然后点击“减值”,如果出现“数值减操作成功”,表明操作成功。如果出现其他提示表明操作失败
4.6 点击“读出”,如果在“当前值:”后面出现是你当前值减去操作值(333333331111111122222222),表明操作正确,如果是其他值表明失败
五、修改密码和控制位
5.1 进入功能选项“修改密码”里面,在“扇区号”下面的可拉选项里面选择第3.5步下载密码的扇区号(比如扇区1
5.2 在“密码A”和“密码B”后面分别写入你想修改的密码A 和密码B
5.3 卡片控制位修改之前请详细阅读卡片资料,因为控制位修改不正确,就会导致卡片
不能再使用,请务必小心使用
5.4 在控制位后面填上该扇区的控制位
5.3 点击“修改密码”,如果出现“修改密码成功”,表示操作正确,如果出现出错提示,
请按照出错提示做相应的处理。(注:密码修改后请务必记住,密码遗忘卡片就不
能再次是使用了)
六、参数设置
6.1 进入功能选项“参数设置”里面,可以设置串口通讯参数:串口号、波特率、校验位、数据位、停止位等等,设置玩了以后点击“修改串口”,如果出现“串口参数设置成功”,表明串口设置成功,如果出现异常,请按照提示做出改动。
6.2 设置完毕以后可以点击“测试读卡器”,如果出现“读卡器连接成功”,并且听到读卡器的风鸣器响声,证明串口设置正确,如果出现“读卡器连接失败”,表明串口设置有问题,请重新设置。
6.3 读写器默认参数:Com19600bpsN81
七、调试信息
7.1 进入功能选项“调试信息”里面,在“串口信息发送与接受”处可以看到PC 机和读卡器之间通讯的详细过程,对调试非常有帮助


单片机(下位机)源程序如下:
  1. #include <intrins.h>
  2. #include "reg52.h"
  3. #include "main.h"
  4. #include "mfrc522.h"
  5. #include <string.h>
  6. #define MAXRLEN 18                        
  7. /////////////////////////////////////////////////////////////////////
  8. //功    能:寻卡
  9. //参数说明: req_code[IN]:寻卡方式
  10. //                0x52 = 寻感应区内所有符合14443A标准的卡
  11. //                0x26 = 寻未进入休眠状态的卡
  12. //          pTagType[OUT]:卡片类型代码
  13. //                0x4400 = Mifare_UltraLight
  14. //                0x0400 = Mifare_One(S50)
  15. //                0x0200 = Mifare_One(S70)
  16. //                0x0800 = Mifare_Pro(X)
  17. //                0x4403 = Mifare_DESFire
  18. //返    回: 成功返回MI_OK
  19. /////////////////////////////////////////////////////////////////////
  20. char PcdRequest(unsigned char req_code,unsigned char *pTagType)
  21. {
  22.    char status;  
  23.    unsigned int  unLen;
  24.    unsigned char ucComMF522Buf[MAXRLEN];
  25. //  unsigned char xTest ;
  26.    ClearBitMask(Status2Reg,0x08);
  27.    WriteRawRC(BitFramingReg,0x07);

  28. //  xTest = ReadRawRC(BitFramingReg);
  29. //  if(xTest == 0x07 )
  30. //   { LED_GREEN  =0 ;}
  31. // else {LED_GREEN =1 ;while(1){}}
  32.    SetBitMask(TxControlReg,0x03);

  33.    ucComMF522Buf[0] = req_code;

  34.    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);
  35. //     if(status  == MI_OK )
  36. //   { LED_GREEN  =0 ;}
  37. //   else {LED_GREEN =1 ;}
  38.    if ((status == MI_OK) && (unLen == 0x10))
  39.    {   
  40.        *pTagType     = ucComMF522Buf[0];
  41.        *(pTagType+1) = ucComMF522Buf[1];
  42.    }
  43.    else
  44.    {   status = MI_ERR;   }
  45.    
  46.    return status;
  47. }

  48. /////////////////////////////////////////////////////////////////////
  49. //功    能:防冲撞
  50. //参数说明: pSnr[OUT]:卡片序列号,4字节
  51. //返    回: 成功返回MI_OK
  52. /////////////////////////////////////////////////////////////////////  
  53. char PcdAnticoll(unsigned char *pSnr)
  54. {
  55.     char status;
  56.     unsigned char i,snr_check=0;
  57.     unsigned int  unLen;
  58.     unsigned char ucComMF522Buf[MAXRLEN];
  59.    

  60.     ClearBitMask(Status2Reg,0x08);
  61.     WriteRawRC(BitFramingReg,0x00);
  62.     ClearBitMask(CollReg,0x80);

  63.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  64.     ucComMF522Buf[1] = 0x20;

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

  66.     if (status == MI_OK)
  67.     {
  68.              for (i=0; i<4; i++)
  69.          {   
  70.              *(pSnr+i)  = ucComMF522Buf[i];
  71.              snr_check ^= ucComMF522Buf[i];
  72.          }
  73.          if (snr_check != ucComMF522Buf[i])
  74.          {   status = MI_ERR;    }
  75.     }
  76.    
  77.     SetBitMask(CollReg,0x80);
  78.     return status;
  79. }

  80. /////////////////////////////////////////////////////////////////////
  81. //功    能:选定卡片
  82. //参数说明: pSnr[IN]:卡片序列号,4字节
  83. //返    回: 成功返回MI_OK
  84. /////////////////////////////////////////////////////////////////////
  85. char PcdSelect(unsigned char *pSnr)
  86. {
  87.     char status;
  88.     unsigned char i;
  89.     unsigned int  unLen;
  90.     unsigned char ucComMF522Buf[MAXRLEN];
  91.    
  92.     ucComMF522Buf[0] = PICC_ANTICOLL1;
  93.     ucComMF522Buf[1] = 0x70;
  94.     ucComMF522Buf[6] = 0;
  95.     for (i=0; i<4; i++)
  96.     {
  97.             ucComMF522Buf[i+2] = *(pSnr+i);
  98.             ucComMF522Buf[6]  ^= *(pSnr+i);
  99.     }
  100.     CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
  101.   
  102.     ClearBitMask(Status2Reg,0x08);

  103.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
  104.    
  105.     if ((status == MI_OK) && (unLen == 0x18))
  106.     {   status = MI_OK;  }
  107.     else
  108.     {   status = MI_ERR;    }

  109.     return status;
  110. }

  111. /////////////////////////////////////////////////////////////////////
  112. //功    能:验证卡片密码
  113. //参数说明: auth_mode[IN]: 密码验证模式
  114. //                 0x60 = 验证A密钥
  115. //                 0x61 = 验证B密钥
  116. //          addr[IN]:块地址
  117. //          pKey[IN]:密码
  118. //          pSnr[IN]:卡片序列号,4字节
  119. //返    回: 成功返回MI_OK
  120. /////////////////////////////////////////////////////////////////////               
  121. char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr)
  122. {
  123.     char status;
  124.     unsigned int  unLen;
  125.     unsigned char i,ucComMF522Buf[MAXRLEN];

  126.     ucComMF522Buf[0] = auth_mode;
  127.     ucComMF522Buf[1] = addr;
  128.     for (i=0; i<6; i++)
  129.     {    ucComMF522Buf[i+2] = *(pKey+i);   }
  130.     for (i=0; i<6; i++)
  131.     {    ucComMF522Buf[i+8] = *(pSnr+i);   }
  132. //   memcpy(&ucComMF522Buf[2], pKey, 6);
  133. //   memcpy(&ucComMF522Buf[8], pSnr, 4);
  134.    
  135.     status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
  136.     if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
  137.     {   status = MI_ERR;   }
  138.    
  139.     return status;
  140. }

  141. /////////////////////////////////////////////////////////////////////
  142. //功    能:读取M1卡一块数据
  143. //参数说明: addr[IN]:块地址
  144. //          pData[OUT]:读出的数据,16字节
  145. //返    回: 成功返回MI_OK
  146. /////////////////////////////////////////////////////////////////////
  147. char PcdRead(unsigned char addr,unsigned char *pData)
  148. {
  149.     char status;
  150.     unsigned int  unLen;
  151.     unsigned char i,ucComMF522Buf[MAXRLEN];

  152.     ucComMF522Buf[0] = PICC_READ;
  153.     ucComMF522Buf[1] = addr;
  154.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
  155.    
  156.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
  157.     if ((status == MI_OK) && (unLen == 0x90))
  158. //   {   memcpy(pData, ucComMF522Buf, 16);   }
  159.     {
  160.         for (i=0; i<16; i++)
  161.         {    *(pData+i) = ucComMF522Buf[i];   }
  162.     }
  163.     else
  164.     {   status = MI_ERR;   }
  165.    
  166.     return status;
  167. }

  168. /////////////////////////////////////////////////////////////////////
  169. //功    能:写数据到M1卡一块
  170. //参数说明: addr[IN]:块地址
  171. //          pData[IN]:写入的数据,16字节
  172. //返    回: 成功返回MI_OK
  173. /////////////////////////////////////////////////////////////////////                  
  174. char PcdWrite(unsigned char addr,unsigned char *pData)
  175. {
  176.     char status;
  177.     unsigned int  unLen;
  178.     unsigned char i,ucComMF522Buf[MAXRLEN];
  179.    
  180.     ucComMF522Buf[0] = PICC_WRITE;
  181.     ucComMF522Buf[1] = addr;
  182.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

  183.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

  184.     if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
  185.     {   status = MI_ERR;   }
  186.         
  187.     if (status == MI_OK)
  188.     {
  189.         //memcpy(ucComMF522Buf, pData, 16);
  190.         for (i=0; i<16; i++)
  191.         {    ucComMF522Buf[i] = *(pData+i);   }
  192.         CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

  193.         status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);
  194.         if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
  195.         {   status = MI_ERR;   }
  196.     }
  197.    
  198.     return status;
  199. }



  200. /////////////////////////////////////////////////////////////////////
  201. //功    能:命令卡片进入休眠状态
  202. //返    回: 成功返回MI_OK
  203. /////////////////////////////////////////////////////////////////////
  204. char PcdHalt(void)
  205. {
  206.     char status;
  207.     unsigned int  unLen;
  208.     unsigned char ucComMF522Buf[MAXRLEN];

  209.     ucComMF522Buf[0] = PICC_HALT;
  210.     ucComMF522Buf[1] = 0;
  211.     CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

  212.     status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

  213.     return MI_OK;
  214. }

  215. /////////////////////////////////////////////////////////////////////
  216. //用MF522计算CRC16函数
  217. /////////////////////////////////////////////////////////////////////
  218. void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
  219. {
  220.     unsigned char i,n;
  221.     ClearBitMask(DivIrqReg,0x04);
  222.     WriteRawRC(CommandReg,PCD_IDLE);
  223.     SetBitMask(FIFOLevelReg,0x80);
  224.     for (i=0; i<len; i++)
  225.     {   WriteRawRC(FIFODataReg, *(pIndata+i));   }
  226.     WriteRawRC(CommandReg, PCD_CALCCRC);
  227.     i = 0xFF;
  228.     do
  229.     {
  230.         n = ReadRawRC(DivIrqReg);
  231.         i--;
  232.     }
  233.     while ((i!=0) && !(n&0x04));
  234.     pOutData[0] = ReadRawRC(CRCResultRegL);
  235.     pOutData[1] = ReadRawRC(CRCResultRegM);
  236. }

  237. /////////////////////////////////////////////////////////////////////
  238. //功    能:复位RC522
  239. //返    回: 成功返回MI_OK
  240. /////////////////////////////////////////////////////////////////////
  241. char PcdReset(void)
  242. {
  243.     MF522_RST=1;
  244.     _nop_();
  245.     MF522_RST=0;
  246.     _nop_();
  247.     MF522_RST=1;
  248.      _nop_();
  249.     WriteRawRC(CommandReg,PCD_RESETPHASE);
  250.     _nop_();
  251.    
  252.     WriteRawRC(ModeReg,0x3D);            //和Mifare卡通讯,CRC初始值0x6363
  253.     WriteRawRC(TReloadRegL,30);           
  254.     WriteRawRC(TReloadRegH,0);
  255.     WriteRawRC(TModeReg,0x8D);
  256.     WriteRawRC(TPrescalerReg,0x3E);
  257.     WriteRawRC(TxAutoReg,0x40);     
  258.     return MI_OK;
  259. }
  260. //////////////////////////////////////////////////////////////////////
  261. //设置RC632的工作方式
  262. //////////////////////////////////////////////////////////////////////
  263. char M500PcdConfigISOType(unsigned char type)
  264. {
  265.    if (type == 'A')                     //ISO14443_A
  266.    {
  267.        ClearBitMask(Status2Reg,0x08);

  268. /*     WriteRawRC(CommandReg,0x20);    //as default   
  269.        WriteRawRC(ComIEnReg,0x80);     //as default
  270.        WriteRawRC(DivlEnReg,0x0);      //as default
  271.            WriteRawRC(ComIrqReg,0x04);     //as default
  272.            WriteRawRC(DivIrqReg,0x0);      //as default
  273.            WriteRawRC(Status2Reg,0x0);//80    //trun off temperature sensor
  274.            WriteRawRC(WaterLevelReg,0x08); //as default
  275.        WriteRawRC(ControlReg,0x20);    //as default
  276.            WriteRawRC(CollReg,0x80);    //as default
  277. */
  278.        WriteRawRC(ModeReg,0x3D);//3F
  279. /*           WriteRawRC(TxModeReg,0x0);      //as default???
  280.            WriteRawRC(RxModeReg,0x0);      //as default???
  281.            WriteRawRC(TxControlReg,0x80);  //as default???

  282.            WriteRawRC(TxSelReg,0x10);      //as default???
  283.    */
  284.        WriteRawRC(RxSelReg,0x86);//84
  285. //      WriteRawRC(RxThresholdReg,0x84);//as default
  286. //      WriteRawRC(DemodReg,0x4D);      //as default

  287. //      WriteRawRC(ModWidthReg,0x13);//26
  288.        WriteRawRC(RFCfgReg,0x7F);   //4F
  289.         /*   WriteRawRC(GsNReg,0x88);        //as default???
  290.            WriteRawRC(CWGsCfgReg,0x20);    //as default???
  291.        WriteRawRC(ModGsCfgReg,0x20);   //as default???
  292. */
  293.               WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
  294.            WriteRawRC(TReloadRegH,0);
  295.        WriteRawRC(TModeReg,0x8D);
  296.            WriteRawRC(TPrescalerReg,0x3E);
  297.           

  298.   //     PcdSetTmo(106);
  299.                             delay_10ms(1);
  300.        PcdAntennaOn();
  301.    }
  302.    else{ return -1; }
  303.    
  304.    return MI_OK;
  305. }
  306. /////////////////////////////////////////////////////////////////////
  307. //功    能:读RC632寄存器
  308. //参数说明:Address[IN]:寄存器地址
  309. //返    回:读出的值
  310. /////////////////////////////////////////////////////////////////////
  311. unsigned char ReadRawRC(unsigned char Address)
  312. {
  313.      unsigned char i, ucAddr;
  314.      unsigned char ucResult=0;

  315.      MF522_SCK = 0;
  316.      MF522_NSS = 0;
  317.      ucAddr = ((Address<<1)&0x7E)|0x80;

  318.      for(i=8;i>0;i--)
  319.      {
  320.          MF522_SI = ((ucAddr&0x80)==0x80);
  321.          MF522_SCK = 1;
  322.          ucAddr <<= 1;
  323.          MF522_SCK = 0;
  324.      }

  325.      for(i=8;i>0;i--)
  326.      {
  327.          MF522_SCK = 1;
  328.          ucResult <<= 1;
  329.          ucResult|=(bit)MF522_SO;
  330.          MF522_SCK = 0;
  331.      }

  332.      MF522_NSS = 1;
  333.      MF522_SCK = 1;
  334.      return ucResult;
  335. }

  336. /////////////////////////////////////////////////////////////////////
  337. //功    能:写RC632寄存器
  338. //参数说明:Address[IN]:寄存器地址
  339. //          value[IN]:写入的值
  340. /////////////////////////////////////////////////////////////////////
  341. void WriteRawRC(unsigned char Address, unsigned char value)
  342. {  
  343.     unsigned char i, ucAddr;

  344.     MF522_SCK = 0;
  345.     MF522_NSS = 0;
  346.     ucAddr = ((Address<<1)&0x7E);

  347.     for(i=8;i>0;i--)
  348.     {
  349.         MF522_SI = ((ucAddr&0x80)==0x80);
  350.         MF522_SCK = 1;
  351.         ucAddr <<= 1;
  352.         MF522_SCK = 0;
  353.     }

  354.     for(i=8;i>0;i--)
  355.     {
  356.         MF522_SI = ((value&0x80)==0x80);
  357.         MF522_SCK = 1;
  358.         value <<= 1;
  359.         MF522_SCK = 0;
  360.     }
  361.     MF522_NSS = 1;
  362.     MF522_SCK = 1;
  363. }

  364. /////////////////////////////////////////////////////////////////////
  365. //功    能:置RC522寄存器位
  366. //参数说明:reg[IN]:寄存器地址
  367. //          mask[IN]:置位值
  368. /////////////////////////////////////////////////////////////////////
  369. void SetBitMask(unsigned char reg,unsigned char mask)  
  370. {
  371.     char tmp = 0x0;
  372.     tmp = ReadRawRC(reg);
  373.     WriteRawRC(reg,tmp | mask);  // set bit mask
  374. }

  375. /////////////////////////////////////////////////////////////////////
  376. //功    能:清RC522寄存器位
  377. //参数说明:reg[IN]:寄存器地址
  378. //          mask[IN]:清位值
  379. /////////////////////////////////////////////////////////////////////
  380. void ClearBitMask(unsigned char reg,unsigned char mask)  
  381. {
  382.     char tmp = 0x0;
  383.     tmp = ReadRawRC(reg);
  384.     WriteRawRC(reg, tmp & ~mask);  // clear bit mask
  385. }

  386. /////////////////////////////////////////////////////////////////////
  387. //功    能:通过RC522和ISO14443卡通讯
  388. //参数说明:Command[IN]:RC522命令字
  389. //          pInData[IN]:通过RC522发送到卡片的数据
  390. //          InLenByte[IN]:发送数据的字节长度
  391. //          pOutData[OUT]:接收到的卡片返回数据
  392. //          *pOutLenBit[OUT]:返回数据的位长度
  393. /////////////////////////////////////////////////////////////////////
  394. char PcdComMF522(unsigned char Command,
  395.                  unsigned char *pInData,
  396.                  unsigned char InLenByte,
  397.                  unsigned char *pOutData,
  398.                  unsigned int  *pOutLenBit)
  399. {
  400.     char status = MI_ERR;
  401.     unsigned char irqEn   = 0x00;
  402.     unsigned char waitFor = 0x00;
  403.     unsigned char lastBits;
  404.     unsigned char n;
  405.     unsigned int i;
  406.     switch (Command)
  407.     {
  408.        case PCD_AUTHENT:
  409.           irqEn   = 0x12;
  410.           waitFor = 0x10;
  411.           break;
  412.        case PCD_TRANSCEIVE:
  413.           irqEn   = 0x77;
  414.           waitFor = 0x30;
  415.           break;
  416.        default:
  417.          break;
  418.     }
  419.    
  420.     WriteRawRC(ComIEnReg,irqEn|0x80);
  421.     ClearBitMask(ComIrqReg,0x80);
  422.     WriteRawRC(CommandReg,PCD_IDLE);
  423.     SetBitMask(FIFOLevelReg,0x80);
  424.    
  425.     for (i=0; i<InLenByte; i++)
  426.     {   WriteRawRC(FIFODataReg, pInData[i]);    }
  427.     WriteRawRC(CommandReg, Command);
  428.    
  429.    
  430.     if (Command == PCD_TRANSCEIVE)
  431.     {    SetBitMask(BitFramingReg,0x80);  }
  432.    
  433. //    i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
  434. i = 2000;
  435.     do
  436.     {
  437.          n = ReadRawRC(ComIrqReg);
  438.          i--;
  439.     }
  440.     while ((i!=0) && !(n&0x01) && !(n&waitFor));
  441.     ClearBitMask(BitFramingReg,0x80);
  442.              
  443.     if (i!=0)
  444.     {   
  445.          if(!(ReadRawRC(ErrorReg)&0x1B))
  446.          {
  447.              status = MI_OK;
  448.              if (n & irqEn & 0x01)
  449.              {   status = MI_NOTAGERR;   }
  450.              if (Command == PCD_TRANSCEIVE)
  451.              {
  452.                        n = ReadRawRC(FIFOLevelReg);
  453.                       lastBits = ReadRawRC(ControlReg) & 0x07;
  454.                 if (lastBits)
  455.                 {   *pOutLenBit = (n-1)*8 + lastBits;   }
  456.                 else
  457.                 {   *pOutLenBit = n*8;   }
  458.                 if (n == 0)
  459.                 {   n = 1;    }
  460.                 if (n > MAXRLEN)
  461.                 {   n = MAXRLEN;   }
  462.                 for (i=0; i<n; i++)
  463.                 {   pOutData[i] = ReadRawRC(FIFODataReg);    }
  464.             }
  465.          }
  466.          else
  467.          {   status = MI_ERR;   }
  468.         
  469.    }
  470.    

  471.    SetBitMask(ControlReg,0x80);           // stop timer now
  472.    WriteRawRC(CommandReg,PCD_IDLE);
  473.    return status;
  474. }


  475. /////////////////////////////////////////////////////////////////////
  476. //开启天线  
  477. //每次启动或关闭天险发射之间应至少有1ms的间隔
  478. /////////////////////////////////////////////////////////////////////
  479. void PcdAntennaOn()
  480. {
  481.     unsigned char i;
  482.     i = ReadRawRC(TxControlReg);
  483.     if (!(i & 0x03))
  484.     {
  485.         SetBitMask(TxControlReg, 0x03);
  486.     }
  487. }


  488. /////////////////////////////////////////////////////////////////////
  489. //关闭天线
  490. /////////////////////////////////////////////////////////////////////
  491. void PcdAntennaOff()
  492. {
  493.     ClearBitMask(TxControlReg, 0x03);
  494. }


  495. /////////////////////////////////////////////////////////////////////
  496. //功    能:扣款和充值
  497. //参数说明: dd_mode[IN]:命令字
  498. //               0xC0 = 扣款
  499. //               0xC1 = 充值
  500. //          addr[IN]:钱包地址

  501. ……………………

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

所有资料51hei提供下载:
51读写卡参考例程及上位机调试软件.zip (866.26 KB, 下载次数: 308)
回复

使用道具 举报

ID:250711 发表于 2018-10-18 16:17 | 显示全部楼层
为什么会下位机不发送信息到上位机
回复

使用道具 举报

ID:396560 发表于 2018-12-1 13:27 | 显示全部楼层
看不懂,没有调试通过。楼主写得不够详细啊
回复

使用道具 举报

ID:471632 发表于 2019-5-7 20:43 | 显示全部楼层
这很牛B呀!
回复

使用道具 举报

ID:447180 发表于 2019-5-9 20:51 | 显示全部楼层
重点是上位机
回复

使用道具 举报

ID:455572 发表于 2019-11-6 08:47 | 显示全部楼层
好东西,支持,可以用读写卡了
回复

使用道具 举报

ID:639778 发表于 2019-12-4 13:28 | 显示全部楼层
很好的文章!!!!亲
回复

使用道具 举报

ID:644528 发表于 2020-3-11 10:42 | 显示全部楼层
这个上位机我用过,最不好的一点是只能选择PC的COM1和COM2口
回复

使用道具 举报

ID:316061 发表于 2020-3-17 09:51 | 显示全部楼层
学习参考,文章不错,!!
回复

使用道具 举报

ID:467922 发表于 2020-3-17 11:08 | 显示全部楼层
太谢谢了,正在进行这方面的测试
回复

使用道具 举报

ID:668457 发表于 2020-3-29 12:18 | 显示全部楼层
里面的测试软件都太老了,win10无法打开,估计要用win7
回复

使用道具 举报

ID:716617 发表于 2020-5-12 10:36 | 显示全部楼层
很不错,正需要
回复

使用道具 举报

ID:716617 发表于 2020-5-12 10:39 | 显示全部楼层
简单/ 发表于 2020-3-11 10:42
这个上位机我用过,最不好的一点是只能选择PC的COM1和COM2口

怎么解决,插上识别都是从com3开始的
回复

使用道具 举报

ID:447180 发表于 2020-5-12 15:48 | 显示全部楼层
读取的是什么卡
回复

使用道具 举报

ID:128463 发表于 2020-5-12 18:14 | 显示全部楼层
学习参考,文章不错,!!
回复

使用道具 举报

ID:762481 发表于 2020-5-27 14:38 | 显示全部楼层
正好需要,哈哈
回复

使用道具 举报

ID:788488 发表于 2020-9-4 16:35 | 显示全部楼层
可以对学校的校园卡进行修改吗
回复

使用道具 举报

ID:839933 发表于 2020-11-13 20:59 | 显示全部楼层
为什么我点开IC卡读写操作程序显示access violation at address in 0045ff48 module‘ICreaderprj.exe’......啊?我按照关于非法访问的解决方法弄了还是这样诶
回复

使用道具 举报

ID:206350 发表于 2021-11-19 11:14 | 显示全部楼层
轻舟逐浪 发表于 2020-5-12 10:39
怎么解决,插上识别都是从com3开始的

可以设备列表那里的属性->高级里面修改
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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