找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机的RC522的CPU卡(FM1208)的例程

  [复制链接]
跳转到指定楼层
楼主
ID:179677 发表于 2017-3-22 11:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用51单片机,飞利浦RC522的射频芯片,
读写CPU卡(复旦的FM1208)的例程,
PS: RC522模块(淘宝上有卖7块钱左右一个)





完整例程下载:
RC522_串口操作FM1208.rar (119.84 KB, 下载次数: 860)




主程序预览:
  1. #include   <STDIO.H>
  2. #include <string.h>
  3. #include "reg52.h"
  4. #include "main.h"
  5. #include "rc522.h"
  6. #include "1602.h"




  7. //////////////////CPU卡的指令/////////////////////////////////////////////////////////////////////////////////
  8. unsigned char code Keyfile[7] ={0x3F, 0x00, 0xB0, 0x01, 0xF0, 0xFF, 0xFF};        //建密钥文件
  9. unsigned char code DefaultKey[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};  //原始外部密钥
  10. unsigned char code ExKey[5]   ={0x39, 0xF0, 0xF0, 0xAA, 0x55};             ////外部密钥建立的指令信息
  11. unsigned char code DFfile[13] ={0x38,0x05,0x20,0xF0,0xF0,0x95,0xFF,0xFF,0x44,0x44,0x46,0x30,0x31};//建立的DF文件                                                          
  12. unsigned char code EF_KEY_File[7]={0x3F, 0x01, 0x8F, 0x95, 0xF0, 0xFF, 0xFF};//建立EF密钥文件                                                                                                                  
  13. unsigned char code C_KEY[8]={0x3A, 0xF0, 0xEF, 0x44, 0x55, 0x12, 0x34, 0x56};    //增加口令密钥
  14. unsigned char code EF_File1[7]={0x28, 0x00, 0x1E, 0xF0, 0xF0, 0xFF, 0xFF};//        基本文件EF 建立的二进制文件1                                                  
  15. unsigned char code EF_File2[7]={0x28, 0x00, 0x0F, 0xF4, 0xF0, 0xFF, 0xFF};//        基本文件EF 建立的二进制文件2
  16. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////





  17. //////////////////文件标识的定义/////////////////////////////////////////////////////////////////////////////////

  18. unsigned char code MF_File_Flag[2] = {0x3f,0x00};       //MF文件标识3F00//
  19. unsigned char code KEY_File_Flag[2] = {0x00,0x00};      //密钥文件标识0000//
  20. unsigned char code KEY_Flag = {0x00};                //密钥标识00,即放在MF下密钥文件里面的密钥,用1个字节表示 //

  21. unsigned char code DF_File_Flag[2] = {0x3f,0x01};       //DF文件标识3F01//
  22. unsigned char code KEY_DF_File_Flag[2] = {0x00,0x01};   //DF下的密钥文件标识0001//
  23. unsigned char code Keyword_DF_Flag = {0x01};         //密钥标识01,即放在DF下密钥文件里面的密钥,用1个字节表示 //

  24. unsigned char code EF_File3_Flag[2]        = {0x00,0x03};       //EF文件标识0003//
  25. unsigned char code EF_File4_Flag[2]        = {0x00,0x04};       //EF文件标识0004//
  26. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  27. unsigned char xdata g_ucTempbuf[MAXRLEN];
  28. unsigned char  xdata Rec_Buf[MAXRLEN];        //接收到串口助手的数据缓存器

  29. unsigned char WorkInt;        //成功接收指令的标志
  30. unsigned char Cmd_Len;  //指令长度         
  31. void delay1(unsigned int z)
  32. {
  33.         unsigned int x,y;
  34.         for(x=z;x>0;x--)
  35.         for(y=110;y>0;y--);       
  36. }  

  37. void UART_Init()     
  38. {
  39. PCON|=0x80; //PCON的最高位SMOD=1时波特率加倍
  40. TMOD=0x20;  //时器1为方式2 初值自动装入 产生波特率
  41. TH1=0xfd;   //定时器初始为0XFd,晶振为22.1184MHz,本函数实际产生的波特率为38400bps
  42. TL1=0xfd;         //同上   
  43. SCON=0x50;         //串口设置为方式1,REN=1,允许接收
  44. TR1=1;      //启动定时器1
  45. ES=1;       //使能串口接收中断,
  46. EA=1;       //打开所有中断
  47. }

  48. /**************************************************************************
  49. - 功能描述:51单片机的串口发送字节的函数
  50. - 隶属模块:STC51串口操作
  51. - 函数属性:外部,使用户使用
  52. - 参数说明:mydata:要发送的一个字节
  53. - 返回说明:无
  54. - 注:发送一个字节,是串口发送的基础操作
  55. **************************************************************************/

  56. void UART_Send_Byte(unsigned char mydata)       
  57. {
  58. ES=0;
  59. TI=0;
  60. SBUF=mydata;
  61. while(!TI);
  62. TI=0;
  63. ES=1;
  64. }

  65. /**************************************************************************
  66. - 功能描述:51单片机的串口发送0d 0a ,即回车换行
  67. - 隶属模块:STC51串口操作
  68. - 函数属性:外部,使用户使用
  69. - 参数说明:无
  70. - 返回说明:无
  71. - 注:此函数就是发送0d 0a这两个字节,在“超级终端”上会有回车换行的效果
  72. **************************************************************************/

  73. void UART_Send_Enter()
  74. {
  75. UART_Send_Byte(0x0d);
  76. UART_Send_Byte(0x0a);
  77. }
  78. /**************************************************************************
  79. - 功能描述:51单片机的串口发送字符串
  80. - 隶属模块:STC51串口操作
  81. - 函数属性:外部,使用户使用
  82. - 参数说明:s:指向字符串的指针
  83. - 返回说明:无
  84. - 注:如果在字符串中有'\n',则会发送一个回车换行
  85. **************************************************************************/

  86. void UART_Send_Str(char *s)
  87. {
  88. int len=strlen(s)-1;
  89. int i;
  90. for(i=0;i<len;i++)
  91. UART_Send_Byte(s[i]);
  92. if(s[i]=='\n')
  93. {
  94.   UART_Send_Enter();
  95. }
  96. else
  97. {
  98.   UART_Send_Byte(s[i]);
  99. }
  100. }




  101. /////////////////////////////////////////////////////////////////////
  102. //串行中断,接收串口助手发来的数据
  103. /////////////////////////////////////////////////////////////////////
  104. seri_int () interrupt 4 using 1
  105. {
  106. unsigned char len, i;
  107. unsigned int j=0;
  108.    if (RI)
  109.    {

  110.                 ES=0;
  111.                 len=SBUF;
  112.                 RI=0;       
  113.                 for(i=0;i<len;i++)
  114.                 {
  115.                         while(!RI)
  116.                         {
  117.                                 j++;
  118.                                 if(j>1000)
  119.                                 {
  120.                                    ES=1;
  121.                                     break;
  122.                                 }
  123.                         }
  124.                         if(j<1000)
  125.                         {
  126.                                 Rec_Buf[i]=SBUF;
  127.                                 RI=0;
  128.                                 j=0;
  129.                         }
  130.                         else
  131.                         {
  132.                            ES=1;
  133.                             break;
  134.                         }
  135.                 }
  136.                 if(i==len)
  137.                 {
  138.                         ES=1;
  139.                         Cmd_Len=len;
  140.                         WorkInt  = 1;
  141.                                        
  142.                 }
  143.     }

  144. }











  145.   
  146. void u8tostr(unsigned char dat)
  147. {

  148. switch(dat>>4)         //高位
  149. {
  150.         case 0: UART_Send_Byte(0x30);  break;
  151.         case 1: UART_Send_Byte(0x31);  break;
  152.         case 2: UART_Send_Byte(0x32);  break;
  153.         case 3: UART_Send_Byte(0x33);  break;
  154.         case 4: UART_Send_Byte(0x34);  break;
  155.         case 5: UART_Send_Byte(0x35);  break;
  156.         case 6: UART_Send_Byte(0x36);  break;
  157.         case 7: UART_Send_Byte(0x37);  break;
  158.         case 8: UART_Send_Byte(0x38);  break;
  159.         case 9: UART_Send_Byte(0x39);  break;
  160.         case 0x0A: UART_Send_Byte(0x41);  break;
  161.         case 0x0B: UART_Send_Byte(0x42); break;
  162.         case 0x0C: UART_Send_Byte(0x43); break;
  163.         case 0x0D: UART_Send_Byte(0x44); break;
  164.         case 0x0E: UART_Send_Byte(0x45); break;
  165.         case 0x0F: UART_Send_Byte(0x46); break;

  166. }

  167. switch(dat&0x0f)        //低位
  168. {
  169.         case 0: UART_Send_Byte(0x30);  break;
  170.         case 1: UART_Send_Byte(0x31);  break;
  171.         case 2: UART_Send_Byte(0x32);  break;
  172.         case 3: UART_Send_Byte(0x33);  break;
  173.         case 4: UART_Send_Byte(0x34);  break;
  174.         case 5: UART_Send_Byte(0x35);  break;
  175.         case 6: UART_Send_Byte(0x36);  break;
  176.         case 7: UART_Send_Byte(0x37);  break;
  177.         case 8: UART_Send_Byte(0x38);  break;
  178.         case 9: UART_Send_Byte(0x39);  break;
  179.         case 0x0A: UART_Send_Byte(0x41);  break;
  180.         case 0x0B: UART_Send_Byte(0x42); break;
  181.         case 0x0C: UART_Send_Byte(0x43); break;
  182.         case 0x0D: UART_Send_Byte(0x44); break;
  183.         case 0x0E: UART_Send_Byte(0x45); break;
  184.         case 0x0F: UART_Send_Byte(0x46); break;

  185. }

  186.   
  187. }
  188. void UART_Put_Num(unsigned char * dat,unsigned char len)
  189. {
  190.         unsigned char i;
  191.        
  192.         for(i=0;i<len;i++)
  193.         {
  194.                 u8tostr(dat[i]);
  195.         }
  196.         UART_Send_Enter();
  197. }



  198. //////////////////////////////////////////////////////////////////////////////

  199. void main( )
  200. {   
  201.         unsigned char status;
  202.         unsigned char tt[2];
  203.         unsigned int sst=0;
  204.            InitSystem( );
  205.          lcd1602_init();
  206.      RC522_Init();

  207.      PcdAntennaOff();
  208.      PcdAntennaOn();

  209.          display_welcome();

  210.          delay1(500);
  211.          BEEP=0;
  212.          delay1(100);
  213.          BEEP=1;

  214.           memset(g_ucTempbuf, 0x00, MAXRLEN); //清0

  215.           while(1)
  216.           {

  217.                    if(WorkInt)
  218.                    {
  219.                                 WorkInt=0;
  220.                
  221.                                 if((Cmd_Len==1)&&(Rec_Buf[0]==0xAA))           //寻卡及复位只操作一次  约定指令为:01AA
  222.                                 {
  223.                                         Rec_Buf[0]=0;
  224.                                         Cmd_Len=0;
  225.                                         if(GetCard(PICC_REQALL,tt,g_ucTempbuf)!=ST_OK)  //寻卡函数
  226.                                         {
  227.                                                 UART_Send_Str("无卡!");
  228.                                                 UART_Send_Enter();
  229.                                                 continue;
  230.                                         }          //寻卡失败返回
  231.                                        
  232.                                        
  233.                                         memset(g_ucTempbuf, 0x00, MAXRLEN);        //清0
  234.                                         if (CardReset(g_ucTempbuf,tt)!=ST_OK)                  //CPU卡复位函数
  235.                                         { continue; }
  236.                                         UART_Send_Str("复位成功!");
  237.                                         UART_Send_Str("返回ATS值:");
  238.                                         UART_Put_Num(g_ucTempbuf,tt[0]);         //串口助手显示返回
  239.                                         UART_Send_Enter();
  240.                                         memset(g_ucTempbuf, 0x00, MAXRLEN);        //清0
  241.                                         BEEP=0;
  242.                                         delay1(500);
  243.                                         BEEP=1;                       
  244.                                         continue;
  245.                                 }


  246.                                 status=Pcd_Cmd(Rec_Buf, Cmd_Len, g_ucTempbuf,tt);
  247.                                 if(status)        //1时出错了
  248.                                 {

  249.                                         Cmd_Len=0;
  250.                                         memset(Rec_Buf, 0x00, MAXRLEN);
  251.                                         memset(g_ucTempbuf, 0x00, MAXRLEN);        //清0                               
  252.                                         UART_Send_Str("操作失败!");
  253.                                          
  254.                                         UART_Send_Enter();
  255.                                         continue;                                                //返回       
  256.                                 }
  257.                                
  258.                                 UART_Put_Num(&g_ucTempbuf[2],tt[0]);         //串口助手显示返回状态

  259.                                 BEEP=0;
  260.                                 delay1(100);
  261.                                 BEEP=1;                       
  262.                                 delay1(100);
  263.                                 BEEP=0;
  264.                                 delay1(100);
  265.                                 BEEP=1;
  266.                           
  267.                                 memset(g_ucTempbuf, 0x00, MAXRLEN);        //清0
  268.        
  269.                    }

  270.           }                       


  271. }


  272. /////////////////////////////////////////////////////////////////////
  273. //系统初始化
  274. /////////////////////////////////////////////////////////////////////
  275. void InitSystem()
  276. {

  277.     P0 = P1 = P2 = P3 = 0xFF;
  278.         UART_Init();
  279. }

复制代码


评分

参与人数 3黑币 +70 收起 理由
JACKLI + 15 共享资料的黑币奖励!
efefeq + 5 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

来自 2#
ID:179677 发表于 2017-10-26 19:25 | 只看该作者
开始的时候,我是用的M1卡的,那个很容易被破解的,为了安全考虑,后来采用的CPU卡,这个只是简单的用串口操作的例程,实际应用中,外部密钥我们一般是不会把次数设置成F的,像我的话,我一般设置成5次,这样就不怕破解了,只要密码不对,超过5次,卡被锁死,就成废品。某宝上卖的这个模块,有些电感用的精度不高,CPU卡只能读取个卡号,后面的操作做不了,至于硬件怎么接?好像模块上都有丝印!自己怎么接的单片机,记得把对应的头文件里设置成一样的就行吧

评分

参与人数 2黑币 +85 收起 理由
n841115849 + 5 绝世好帖!
admin + 80 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

来自 3#
ID:179677 发表于 2017-11-15 17:36 | 只看该作者
FM1208的09和10,其实两种卡都能用,一种是纯CPU卡,一种是CPU+M1卡!但是要注意的一点是,用那种含M1卡容量的,由于它的CPU容量要小一些,在建立DF文件,EF文件的时候,分配文件空间的时候就尽量别划分的太大,不然可能会回复错误代码(好象是6D01?我也不太记得了!)只要把对应的文件空间大小改小一些就可以!我两种卡都买过,就算是同一家店买的同一批次的卡片的实际容量也有差别的,所以最好,根据自己的实际需求来,要用到多大的空间,就划多大的

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

地板
ID:210179 发表于 2017-6-11 17:53 | 只看该作者
推一個
回复

使用道具 举报

5#
ID:210179 发表于 2017-6-11 17:56 | 只看该作者
請問一下RC522可以複製卡片嗎?
回复

使用道具 举报

6#
ID:228989 发表于 2017-8-24 14:41 | 只看该作者
感谢大神分享!
回复

使用道具 举报

7#
ID:230285 发表于 2017-8-31 16:54 | 只看该作者

感谢大神分享!
回复

使用道具 举报

8#
ID:230293 发表于 2017-8-31 17:12 | 只看该作者
学习一下
回复

使用道具 举报

9#
ID:230429 发表于 2017-9-1 15:45 | 只看该作者
非常感谢分享!正在研究这个
回复

使用道具 举报

10#
ID:232405 发表于 2017-9-11 15:18 | 只看该作者
CPU卡  可以完全防复制吗?
回复

使用道具 举报

11#
ID:233809 发表于 2017-9-18 11:28 | 只看该作者
给力,mark,等积分够了下载看看,我目前也在搞CPU卡,卡在不知道发什么指令,怎么个过程读CPU卡了
回复

使用道具 举报

12#
ID:234818 发表于 2017-9-22 10:15 | 只看该作者
不是很详细的吧!!!!
回复

使用道具 举报

13#
ID:234516 发表于 2017-9-26 22:40 | 只看该作者
麻烦问下硬件是怎么连接的呢?
回复

使用道具 举报

14#
ID:234516 发表于 2017-9-26 23:08 | 只看该作者
还有,有没有程序现象的说明等等?谢谢了啊
回复

使用道具 举报

15#
ID:151356 发表于 2017-9-28 18:31 | 只看该作者
cpu卡确实有很大的优势。
回复

使用道具 举报

16#
ID:244795 发表于 2017-11-1 00:00 | 只看该作者
学习了!非常感谢分享!
回复

使用道具 举报

17#
ID:81808 发表于 2017-11-6 21:55 | 只看该作者
FM1208有09和10两个版本,不知楼主是哪个版本
回复

使用道具 举报

18#
ID:81808 发表于 2017-11-8 17:22 | 只看该作者
我已经证实了,是09版,也就是纯CPU卡。已经成功地读取到ATS
回复

使用道具 举报

19#
ID:255421 发表于 2017-12-1 11:02 | 只看该作者
非常感谢分享!
回复

使用道具 举报

20#
ID:268839 发表于 2017-12-29 14:32 | 只看该作者
我也能读取ATS,但是APDU操作不成功,怎么回事?
回复

使用道具 举报

21#
ID:229788 发表于 2017-12-29 17:22 | 只看该作者
n841115849 发表于 2017-12-29 14:32
我也能读取ATS,但是APDU操作不成功,怎么回事?

我的没反应咋回事,我的晶振时11.0592的,我再串口调试助手测试了不同波特率,也没反应,我的qq946736858,可以讨论一下么,整这个好几天了恼火啊
回复

使用道具 举报

22#
ID:271862 发表于 2018-1-5 12:00 | 只看该作者
回复

使用道具 举报

23#
ID:261686 发表于 2018-1-11 17:04 | 只看该作者
n841115849 发表于 2017-12-29 14:32
我也能读取ATS,但是APDU操作不成功,怎么回事?

你的APDU指令能调了吗??
回复

使用道具 举报

24#
ID:255063 发表于 2018-1-11 20:28 | 只看该作者
CPU 卡是什么?
回复

使用道具 举报

25#
ID:276348 发表于 2018-1-21 22:52 | 只看该作者
这个东西可以下来一用。
回复

使用道具 举报

26#
ID:261686 发表于 2018-1-22 20:08 | 只看该作者
n841115849 发表于 2017-12-29 14:32
我也能读取ATS,但是APDU操作不成功,怎么回事?

兄弟你APDU指令能调了吗
回复

使用道具 举报

27#
ID:285608 发表于 2018-2-26 12:09 | 只看该作者
不知道RC522还可以操作CPU卡,来看看能否借鉴一下
回复

使用道具 举报

28#
ID:285608 发表于 2018-2-27 15:21 | 只看该作者
黑币不够,只能一天天的来刷了。
回复

使用道具 举报

29#
ID:68603 发表于 2018-3-25 15:49 | 只看该作者
谢谢分享
回复

使用道具 举报

30#
ID:223788 发表于 2018-4-15 16:56 | 只看该作者
这个不错,先收下了
回复

使用道具 举报

31#
ID:310333 发表于 2018-4-17 19:35 | 只看该作者
看一下 谢谢楼主分享
回复

使用道具 举报

32#
ID:308858 发表于 2018-4-18 20:02 | 只看该作者
正好有用,可以参考一下了
回复

使用道具 举报

33#
ID:327558 发表于 2018-5-12 14:39 | 只看该作者
很有帮助,感谢!
回复

使用道具 举报

34#
ID:309881 发表于 2018-5-15 18:48 | 只看该作者
你好,楼主,我的到选卡都没问题,到发送RATS时,无回复,一般这是啥情况
回复

使用道具 举报

35#
ID:325456 发表于 2018-5-26 13:02 | 只看该作者
版主 ,请问 怎么 开始 测试IC卡
回复

使用道具 举报

36#
ID:268820 发表于 2018-6-5 14:44 | 只看该作者
感谢分享
回复

使用道具 举报

37#
ID:369737 发表于 2018-7-13 17:18 | 只看该作者
谢谢分享,这几天都在弄这个东西,也基本没什么头绪,
回复

使用道具 举报

38#
ID:369737 发表于 2018-7-14 15:55 | 只看该作者
东电逸仙 发表于 2018-5-26 13:02
版主 ,请问 怎么 开始 测试IC卡

同求,这个怎么验证,希望能讲解一下,谢谢
回复

使用道具 举报

39#
ID:367839 发表于 2018-8-14 15:08 | 只看该作者
各位大哥还在不在,小弟最近用RC531在调CPU卡的数据交互,RATS已经成功复位,但是进行数据交互不成功,这个问题困惑我好几天了,有没有大哥指点一下。
回复

使用道具 举报

40#
ID:336834 发表于 2018-10-5 16:43 | 只看该作者
真的非常好用啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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