找回密码
 立即注册

QQ登录

只需一步,快速开始

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

FM1702SL 51单片机测试程序

[复制链接]
跳转到指定楼层
楼主
ID:442251 发表于 2018-12-8 16:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
FM1702SL源码:
  1. /****************************************************************************
  2. * File :  main.c                                                            *
  3. * COPYRIGHT BY HUOYAN LTD.COMPANY                                           *
  4. * Version:      V1.3                                                                      *
  5. * Author:       NIL                                                         *
  6. *                                                                           *
  7. * Compiler:     KEIL C51 V7.10                                              *
  8. *                                                                           *
  9. * Description:  AT89S52-Firmware for FM1702 Demo Serial Reader             *
  10. *                                                                           *
  11. ****************************************************************************/
  12. #include <reg52.h>
  13. #define __SRC
  14. #include "main.h"
  15. #undef  __SRC
  16. #include <intrins.h>
  17. //#include <string.h>
  18. //#include <stdio.h>
  19. //#include <absacc.h>



  20. #include "FM1702.h"


  21. #define uchar        unsigned char
  22. #define uint        unsigned int
  23. //pin define  mcu控制管脚定义          

  24. sbit RF_MISO        =        P1^0;
  25. sbit RF_MOSI        =        P1^1;
  26. sbit RF_SCK                =        P1^2;
  27. sbit RF_NSS                =        P1^3;
  28. sbit RF_RST          =   P1^4;        //由高变低时启动内部复位程序       

  29. sbit CARD_LED        =        P2^0;
  30. sbit SPEAKER    =   P2^0;
  31.                                

  32.                                                                                        



  33. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
  34. //名称: spi_byte_transceive                                                    //
  35. //功能: 该函数实现SPI通讯的数据收发                                            //
  36. //                                                                               //
  37. //输入:                                                                        //
  38. //      发送数据                                                               //
  39. //                                                                             //
  40. //输出:                                                                        //
  41. //      接收数据                                                               //
  42. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
  43. char spi_byte_transceive(char sendbyte)
  44. {
  45.   char i,temp;
  46.   for(i=0;i<8;i++)
  47.    {  
  48.     RF_SCK=0;
  49.     if(sendbyte & 0x80)                      //位运算,判断最高位是否为1
  50.      {
  51.       RF_MOSI=1;
  52.      }
  53.     else
  54.      {
  55.       RF_MOSI=0;
  56.      }
  57.     sendbyte <<= 1;
  58.     RF_SCK=1;
  59.     temp <<= 1;
  60.     if(RF_MISO)
  61.     temp |= 0x01;
  62.    }
  63.     RF_SCK=0;
  64.      _nop_();
  65.          _nop_();
  66.     RF_MOSI=0;
  67.     return (temp);
  68. }

  69. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
  70. //名称: rc531_register_write                                                   //
  71. //功能: 该函数实现通过SPI接口对RC531中一个寄存器写入值                         //
  72. //                                                                             //
  73. //输入:                                                                        //
  74. //     RC531目标寄存器地址和写入值                                             //
  75. //                                                                             //
  76. //输出:                                                                        //
  77. //     N/A                                                                     //
  78. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
  79. void SPIWrite(char reg_ad,char reg_data)
  80. {   
  81.     RF_SCK=0;
  82.     reg_ad <<= 1;
  83.     RF_NSS=0;
  84.     reg_ad &= 0x7F;
  85.     spi_byte_transceive(reg_ad);
  86.     spi_byte_transceive(reg_data);
  87.     RF_NSS=1;
  88.     return;
  89. }

  90. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
  91. //名称: rc531_register_read                                                    //
  92. //功能: 该函数实现通过SPI接口读取RC531中一个寄存器的值                         //
  93. //                                                                             //
  94. //输入:                                                                        //
  95. //     RC531目标寄存器地址                                                     //
  96. //                                                                             //
  97. //输出:                                                                        //
  98. //     目标寄存器的值                                                          //
  99. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
  100. unsigned char SPIRead(char reg_ad)
  101. {   char temp;
  102.     RF_SCK=0;
  103.      _nop_();
  104.      _nop_();
  105.     RF_NSS=0;
  106.     reg_ad <<= 1;
  107.     reg_ad |= 0x80;
  108.     spi_byte_transceive(reg_ad);
  109.     temp=spi_byte_transceive(0x00);
  110.     RF_NSS=1;
  111.     return (temp);
  112. }

  113.                                        






  114. ///////////////////////////////////////////////////////////////////////
  115. // 主函数
  116. ///////////////////////////////////////////////////////////////////////
  117. void main(void)
  118. {         //设置变量
  119.     uchar baud;
  120.        

  121.     InitSystem();     //初始化系统
  122.     while (1)
  123.     {

  124.                 //检查命令标志       
  125.             if (CmdValid)                //if LEVEL 1
  126.             {
  127.                     CmdValid = FALSE;
  128.                     if(RevBuffer[0]==11)         //if LEVEL 2   
  129.                     {
  130.                             RevBuffer[2]=RevBuffer[1];
  131.                               RevBuffer[0]=1;         
  132.                             RevBuffer[1]=0;
  133.                             CALL_isr_UART();                //equal to 'SETB TI', defined in main.h
  134.                             SPEAKER=0;              //开蜂鸣器和指示灯
  135.                                 delay_10ms(RevBuffer[2]);
  136.                             SPEAKER=1;
  137.                     }
  138.                      else if(RevBuffer[0]==13)   //设置通讯波特率 //if LEVEL 2
  139.                     {
  140.                             switch(RevBuffer[1])
  141.                             {
  142.                                     case 0:
  143.                                             baud=BAUD_9600;
  144.                                             break;
  145.                                     case 1:
  146.                                             baud=BAUD_14400;
  147.                                             break;
  148.                                     case 2:
  149.                                             baud=BAUD_19200;
  150.                                             break;
  151.                                     case 3:
  152.                                             baud=BAUD_28800;
  153.                                             break;
  154.                                     case 4:
  155.                                             baud=BAUD_38400;
  156.                                             break;
  157.                                     case 5:
  158.                                             baud=BAUD_57600;
  159.                                             break;
  160.                                     case 6:
  161.                                             baud=BAUD_115200;
  162.                                             break;
  163.                                     default:
  164.                                             baud=BAUD_19200;
  165.                                             break;
  166.                             }        //switch body                       
  167.                             RevBuffer[0]=1;                //contact
  168.                             RevBuffer[1]=0;
  169.                             CALL_isr_UART();
  170.                             delay_10ms(5);                       
  171.                             TR1   = 0;
  172.                             TH1   = baud;
  173.                             TL1   = TH1;
  174.                             delay_10ms(2);
  175.                             TR1   = TRUE;
  176.                     }//if LEVEL 2
  177.                        else
  178.                     {
  179.                             cmd_process();        // 进入IC卡处理程序
  180.                             CALL_isr_UART();
  181.                     }
  182.             }
  183.     }//while循环体
  184. }//main函数
  185. ///////////////////////////////////////////////////////////////////////
  186. // 系统初始化
  187. ///////////////////////////////////////////////////////////////////////
  188. void InitSystem(void)
  189. {
  190.     RF_NSS=1;               
  191.         RF_RST=0;       
  192.         ET2 = 0;         //Timer 2 disabled
  193.         T2CON = 0x04;        //start Timer 2(internal timer, auto reload)
  194.     PCON = 0x80;    //baud rate double   
  195.     SCON = 0x70;    //UART mode 1, enable receive, if No valid stop bit, RI not activated.

  196.         //TMOD = 0x22;
  197.     TMOD = 0x21;    //Timer 1 8bit auto reload TR1 control
  198.                                         //Timer 0 16bit TR0 control

  199.         TH1   = BAUD_19200;  //默认波特率
  200.         TL1   = TH1;
  201.         TR1   = TRUE;        // 波特率发生器
  202.        
  203.         TH0 = 0x60;
  204.     TL0 = 0x60;
  205.     TR0 = 0;        //Timer 0 doesn't run
  206.    
  207.     ET0=0;
  208.         ET1=0;
  209.         EA=1;
  210.         EX0=1;
  211.         IT0 = 1;       
  212.         TR2=0;
  213.         ES = TRUE;    //enable UART interrupt
  214.         CmdValid=0;         //flag initiation
  215.                                                 //喇叭和指示灯测试



  216.         SPEAKER=0;
  217.         delay_10ms(10);
  218.         delay_10ms(10);
  219.         SPEAKER=1;                  
  220.         Init_FM1702(0);                 

  221. }
  222. ///////////////////////////////////////////////////////////////////////
  223. // 串口接收和发送中断
  224. ///////////////////////////////////////////////////////////////////////
  225. void isr_UART(void) interrupt 4 using 1
  226. {
  227.     uchar len, i;
  228.           unsigned int j=0;
  229.          
  230.           if(RI)
  231.         {               
  232.                 len=SBUF;
  233.                 RI=0;       
  234.                 for(i=0;i<len;i++)
  235.                 {
  236.                         while(!RI)
  237.                         {
  238.                                 j++;
  239.                                 if(j>1000)
  240.                                 {
  241.                                     break;
  242.                                 }
  243.                         }
  244.                         if(j<1000)
  245.                         {
  246.                                 RevBuffer[i]=SBUF;
  247.                                 RI=0;
  248.                                 j=0;
  249.                         }
  250.                         else
  251.                         {
  252.                             break;
  253.                         }
  254.                 }
  255.                 if(i==len)
  256.                 {
  257.                         REN=0;
  258.                         CmdValid=1;
  259.                 }
  260.         }
  261.         else if(!RI && TI)
  262.         {
  263.                 TI=0;
  264.                 len=RevBuffer[0];
  265.                 for(i=0;i<len+1;i++)
  266.                 {
  267.                         SBUF=RevBuffer[i];
  268.                         while(!TI);
  269.                         TI=0;                       
  270.                 }
  271.                 REN=1;
  272.         }
  273. }
  274. ///////////////////////////////////////////////////////////////////////
  275. // IC卡处理函数
  276. ///////////////////////////////////////////////////////////////////////
  277. void cmd_process(void)
  278. {
  279.     uchar cmd;
  280.     uchar status;
  281.        
  282.         cmd = RevBuffer[0];
  283.         switch(cmd)
  284.         {
  285.                 case 1:     // Halt the card     //终止卡的操作
  286.                         status=MIF_Halt();                       
  287.                         RevBuffer[0]=1;
  288.                         RevBuffer[1]=status;
  289.                         break;                       
  290.                 case 2:     
  291.                 status = Request(RF_CMD_REQUEST_ALL);        //RF_CMD_REQUEST_STD=0x26, request Idle
  292.                 if(status != FM1702_OK)
  293.                 {
  294.                     status = Request(RF_CMD_REQUEST_ALL);               
  295.                     if(status != FM1702_OK)
  296.                     {
  297.                         RevBuffer[0] = 1;
  298.                         RevBuffer[1] = FM1702_REQERR;

  299.                         break;
  300.                     }
  301.                 }
  302.                         if(tagtype[0]==2)
  303.                                 cardtype=mifarepro;     // Mifare Pro 卡
  304.                         else if(tagtype[0]==4)
  305.                                 cardtype=mifare1;       // Mifare One 卡
  306.                         else if(tagtype[0]==16)
  307.                                 cardtype=mifarelight;   // Mifare Light 卡
  308.                         else
  309.                                 cardtype=unknowncard;
  310.                         RevBuffer[0]=3;       
  311.                         RevBuffer[1]=status;
  312.                         RevBuffer[2]=tagtype[0];
  313.                         RevBuffer[3]=tagtype[1];
  314.                         break;
  315.             case 3:                         // 防冲突 读卡的系列号 MLastSelectedSnr
  316.                         status = AntiColl();;
  317.                         if(status!=FM1702_OK)
  318.                         {
  319.                                 RevBuffer[0]=1;       
  320.                                 RevBuffer[1]=FM1702_ANTICOLLERR;
  321.                                 break;
  322.                         }
  323.                         //memcpy(MLastSelectedSnr,&RevBuffer[2],4);
  324.                         RevBuffer[0]=5;
  325.                         RevBuffer[1]=status;
  326.                         RevBuffer[2]=UID[0];
  327.                         RevBuffer[3]=UID[1];
  328.                         RevBuffer[4]=UID[2];
  329.                         RevBuffer[5]=UID[3];
  330.                         break;       
  331.                 case 4:                                    // 选择卡 Select Card
  332.                         status=Select_Card();
  333.                         if(status!=FM1702_OK)
  334.                         {
  335.                                 RevBuffer[0]=1;       
  336.                                 RevBuffer[1]=FM1702_SELERR;
  337.                                 break;
  338.                         }
  339.                         RevBuffer[0]=1;
  340.                         RevBuffer[1]=status;                       
  341.                         break;

  342.         case 5:                        //下载密钥
  343.                         status = Load_keyE2(RevBuffer[2],RevBuffer[1]);   //%40
  344.                         status = Authentication(UID, RevBuffer[2], RevBuffer[1]);       
  345.                 if(status != FM1702_OK)
  346.                 {
  347.                         RevBuffer[0]=1;
  348.                             RevBuffer[1]=status;
  349.                             break;
  350.                 }
  351.                         RevBuffer[0]=1;
  352.                         RevBuffer[1]=status;                       
  353.                         break;       


  354.                 case 6:            // Key loading into the MF RC500's EEPROM
  355.                             // 校验卡密码(E2)                   Load_keyE2_CPY(uchar Secnr, uchar Mode)

  356.                         status = Load_keyE2_CPY(RevBuffer[2],RevBuffer[1]);   //%40
  357.                 if(status != FM1702_OK)
  358.                 {
  359.                         RevBuffer[0]=1;
  360.                             RevBuffer[1]=status;
  361.                             break;
  362.                 }
  363.                         RevBuffer[0]=1;
  364.                         RevBuffer[1]=status;                       
  365.                         break;       


  366.                 case 8:                       //读卡
  367.                         status=MIF_READ(&RevBuffer[2],RevBuffer[1]);
  368.                         if(status != FM1702_OK)
  369.                         {
  370.                             RevBuffer[0]=1;
  371.                             RevBuffer[1]=status;
  372.                             break;
  373.                         }
  374.                         else
  375.                         {
  376.                                 if(cardtype==mifare1||cardtype==mifarepro)
  377.                                         RevBuffer[0]=17;
  378.                                 else if(cardtype==1)
  379.                                         RevBuffer[0]=9;
  380.                                 else
  381.                                         RevBuffer[0]=16;
  382.                         }
  383.                         RevBuffer[1]=status;                       
  384.                         break;       
  385.                 case 9:                  //写卡
  386.                         status=MIF_Write(&RevBuffer[2],RevBuffer[1]);
  387.                         RevBuffer[0]=1;
  388.                         RevBuffer[1]=status;                       
  389.                         break;       
  390.                 case 10:                //加值减值
  391.                         if(RevBuffer[1] == RF_CMD_INC)
  392.                         {
  393.                             status = MIF_Increment(&RevBuffer[3],RevBuffer[2]);
  394.                             MIF_Transfer(RevBuffer[2]);
  395.                         }
  396.                         else if(RevBuffer[1] == RF_CMD_DEC)
  397.                         {
  398.                             status = MIF_Decrement(&RevBuffer[3],RevBuffer[2]);   
  399.                             MIF_Transfer(RevBuffer[2]);
  400.                         }
  401.                         else
  402.                         {
  403.                             status = 1;
  404.                         }
  405.                         RevBuffer[0]=1;       
  406.                         RevBuffer[1]=status;
  407.                         break;
  408.                 case 12:   
  409.                         RevBuffer[0]=1;
  410.                         RevBuffer[1]=0;
  411.                         break;
  412.                 default:
  413.                     RevBuffer[0] = 1;
  414.                     RevBuffer[1] = 1;
  415.                     break;       
  416.         }
  417. }



  418. /****************************************************************/
  419. /*名称: Clear_FIFO */
  420. /*功能: 该函数实现清空FM1702中FIFO的数据*/
  421. /*输入: N/A */
  422. /*输出: TRUE, FIFO被清空*/
  423. /* FALSE, FIFO未被清空*/
  424. /****************************************************************/
  425. uchar Clear_FIFO(void)
  426. {
  427.         uchar        temp;
  428.         uint        i;
  429.         temp = SPIRead(Control);                        /* 清空FIFO */
  430.         temp = (temp | 0x01);
  431.         SPIWrite(Control,temp);
  432.         for(i = 0; i < RF_TimeOut; i++) /* 检查FIFO是否被清空 */
  433.         {
  434.                 temp = SPIRead(FIFO_Length);
  435.                 if(temp == 0)
  436.                 {
  437.                         return TRUE;
  438.                 }
  439.         }

  440.         return FALSE;
  441. }

  442. /****************************************************************/
  443. /*名称: Write_FIFO */
  444. /*功能: 该函数实现向FM1702的FIFO中写入x bytes数据*/
  445. /*输入: count, 待写入字节的长度*/
  446. /* buff, 指向待写入数据的指针*/
  447. /*输出: N/A */
  448. /****************************************************************/
  449. void Write_FIFO(uchar count, uchar idata *buff)
  450. {
  451.         uchar        i;
  452.        
  453.         for(i = 0; i < count; i++)
  454.         {
  455.                 SPIWrite(FIFO,*(buff + i));
  456.         }
  457. }

  458. /****************************************************************/
  459. /*名称: Read_FIFO */
  460. /*功能: 该函数实现从FM1702的FIFO中读出x bytes数据*/
  461. /*输入: buff, 指向读出数据的指针*/
  462. /*输出: N/A */
  463. /****************************************************************/
  464. uchar Read_FIFO(uchar idata *buff)
  465. {
  466.         uchar        temp;
  467.         uchar        i;
  468.        
  469.         temp = SPIRead(FIFO_Length);
  470.         if(temp == 0)
  471.         {
  472.                 return 0;
  473.         }

  474.         if(temp >= 24)               
  475.         {
  476.        
  477.                 temp = 24;       
  478.         }

  479.         for(i = 0; i < temp; i++)
  480.         {
  481.                 *(buff + i) = SPIRead(FIFO);
  482.         }

  483.         return temp;
  484. }

  485. /****************************************************************/
  486. /*名称: Judge_Req */
  487. /*功能: 该函数实现对卡片复位应答信号的判断*/
  488. /*输入: *buff, 指向应答数据的指针*/
  489. /*输出: TRUE, 卡片应答信号正确*/
  490. /* FALSE, 卡片应答信号错误*/
  491. /****************************************************************/
  492. uchar Judge_Req(uchar idata *buff)
  493. {
  494.        
  495.         uchar        temp1, temp2;
  496.        
  497.         temp1 = *buff;
  498.         temp2 = *(buff + 1);
  499.         if((temp1 == 0x02) || (temp1 == 0x04) || (temp1 == 0x05) || (temp1 == 0x53) || (temp1 == 0x03))
  500.         {
  501.                 if (temp2 == 0x00)
  502.                 {
  503.                         return TRUE;
  504.                 }
  505.         }
  506.         return FALSE;
  507. }

  508. /****************************************************************/
  509. /*名称: Check_UID */
  510. /*功能: 该函数实现对收到的卡片的序列号的判断*/
  511. /*输入: N/A */
  512. /*输出: TRUE: 序列号正确*/
  513. /* FALSE: 序列号错误*/
  514. /****************************************************************/
  515. uchar Check_UID(void)
  516. {
  517.        
  518.         uchar        temp;
  519.         uchar        i;
  520.        
  521.         temp = 0x00;
  522.         for(i = 0; i < 5; i++)
  523.         {
  524.                 temp = temp ^ UID[i];
  525.         }

  526.         if(temp == 0)
  527.         {
  528.                 return TRUE;
  529.         }

  530.         return FALSE;
  531. }

  532. /****************************************************************/
  533. /*名称: Save_UID */
  534. /*功能: 该函数实现保存卡片收到的序列号*/
  535. /*输入: row: 产生冲突的行*/
  536. /* col: 产生冲突的列*/
  537. /* length: 接収到的UID数据长度*/
  538. /*输出: N/A */
  539. /****************************************************************/
  540. void Save_UID(uchar row, uchar col, uchar length)
  541. {
  542.         uchar        i;
  543.         uchar        temp;
  544.         uchar        temp1;
  545.        
  546.         if((row == 0x00) && (col == 0x00))
  547.         {
  548.                 for(i = 0; i < length; i++)
  549.                 {
  550.                         UID[i] = RevBuffer[i];
  551.                 }
  552.         }
  553.         else
  554.         {
  555.                 temp = RevBuffer[0];
  556.                 temp1 = UID[row - 1];
  557.                 switch(col)
  558.                 {
  559.                 case 0:                temp1 = 0x00; row = row + 1; break;
  560.                 case 1:                temp = temp & 0xFE; temp1 = temp1 & 0x01; break;
  561.                 case 2:                temp = temp & 0xFC; temp1 = temp1 & 0x03; break;
  562.                 case 3:                temp = temp & 0xF8; temp1 = temp1 & 0x07; break;
  563.                 case 4:                temp = temp & 0xF0; temp1 = temp1 & 0x0F; break;
  564.                 case 5:                temp = temp & 0xE0; temp1 = temp1 & 0x1F; break;
  565.                 case 6:                temp = temp & 0xC0; temp1 = temp1 & 0x3F; break;
  566.                 case 7:                temp = temp & 0x80; temp1 = temp1 & 0x7F; break;
  567.                 default:        break;
  568.                 }

  569.                 RevBuffer[0] = temp;
  570.                 UID[row - 1] = temp1 | temp;
  571.                 for(i = 1; i < length; i++)
  572.                 {
  573.                         UID[row - 1 + i] = RevBuffer[i];
  574.                 }
  575.         }
  576. }

  577. /****************************************************************/
  578. /*名称: Set_BitFraming */
  579. /*功能: 该函数设置待发送数据的字节数*/
  580. /*输入: row: 产生冲突的行*/
  581. /* col: 产生冲突的列*/
  582. /*输出: N/A */
  583. /****************************************************************/
  584. void Set_BitFraming(uchar row, uchar col)
  585. {
  586.         switch(row)
  587.         {
  588.         case 0:                RevBuffer[1] = 0x20; break;
  589.         case 1:                RevBuffer[1] = 0x30; break;
  590.         case 2:                RevBuffer[1] = 0x40; break;
  591.         case 3:                RevBuffer[1] = 0x50; break;
  592.         case 4:                RevBuffer[1] = 0x60; break;
  593.         default:        break;
  594.         }

  595.         switch(col)
  596.         {
  597.         case 0:                SPIWrite(Bit_Frame,0x00); break;
  598.         case 1:                SPIWrite(Bit_Frame,0x11); RevBuffer[1] = (RevBuffer[1] | 0x01); break;
  599.         case 2:                SPIWrite(Bit_Frame,0x22); RevBuffer[1] = (RevBuffer[1] | 0x02); break;
  600.         case 3:                SPIWrite(Bit_Frame,0x33); RevBuffer[1] = (RevBuffer[1] | 0x03); break;
  601.         case 4:                SPIWrite(Bit_Frame,0x44); RevBuffer[1] = (RevBuffer[1] | 0x04); break;
  602.         case 5:                SPIWrite(Bit_Frame,0x55); RevBuffer[1] = (RevBuffer[1] | 0x05); break;
  603.         case 6:                SPIWrite(Bit_Frame,0x66); RevBuffer[1] = (RevBuffer[1] | 0x06); break;
  604.         case 7:                SPIWrite(Bit_Frame,0x77); RevBuffer[1] = (RevBuffer[1] | 0x07); break;
  605.         default:        break;
  606.         }
  607. }

  608. /****************************************************************/
  609. /*名称: Init_FM1702 */
  610. /*功能: 该函数实现对FM1702初始化操作*/
  611. /*输入: mode:工作模式, 0:TYPEA模式*/
  612. /* 1:TYPEB模式*/
  613. /* 2:上海模式*/
  614. /*输出: N/A */
  615. /****************************************************************/
  616. void Init_FM1702(uchar mode)
  617. {
  618.        
  619.         uchar temp;
  620.         uint        i;
  621.        
  622. //    unsigned int idata timecnt=0;
  623.         RF_SCK = 1;
  624.         RF_MISO = 1;
  625.         RF_MOSI = 1;
  626.         RF_RST = 1;                                    /* FM1702复位 */
  627.         for(i = 0; i < 0x1fff; i++)
  628.         {
  629.                 _nop_();                     /*等待约140ms, 11.0592*/
  630.         }

  631.         RF_RST = 0;
  632.         for(i = 0; i < 0x1fff; i++)      
  633.         {
  634.                 _nop_();
  635.         }


  636. ////////////////////////////////////////////////////////////////////////////
  637.        
  638.         while(temp = SPIRead(Command) != 0)                        /* 等待Command = 0,FM1702复位成功 */
  639.         {
  640.                 _nop_();
  641.         }
  642. ////////////////////////////////////////////////////////////////////////////
  643. //        delay_10ms(1);
  644.     SPIWrite(Page_Sel,0x80);       


  645.         for(i = 0; i < 0x1fff; i++) /* 延时 */
  646.         {
  647.                 if(temp=SPIRead(Command) == 0x00)       
  648.                 {
  649.                         SPIWrite(Page_Sel,0x00);
  650.                 }
  651.         }


  652. //           P2 = SPIRead(TimerClock);           //for debug


  653.         SPIWrite(TimerClock,0x0b);                   //address 2AH    /* 定时器周期设置寄存器 */   

  654.         SPIWrite(TimerControl,0x02);           //address 2BH        /* 定时器控制寄存器 */   
  655.         SPIWrite(TimerReload,0x42);               //address 2CH    /* 定时器初值寄存器 */          
  656.    
  657.         SPIWrite(InterruptEn,0x7f);                   //address 06H    /* 中断使能/禁止寄存器 */     

  658. //        temp = SPIRead(InterruptEn);
  659.         SPIWrite(Int_Req,0x7f);            //address 07H    /* 中断请求标识寄存器 */
  660.         SPIWrite(MFOUTSelect,0x02);                   //address 26H    /* mf OUT 选择配置寄存器 */     

  661. //设置调制器的输入源为内部编码器, 并且设置TX1和TX2
  662.         SPIWrite(TxControl,0x5b);                   //address 11H    /* 发送控制寄存器 */
  663.         SPIWrite(RxControl2,0x01);
  664. //        SPIWrite(RxControl1,0x73);
  665.         SPIWrite(RxWait,0x07);
  666.         if(mode ==2)
  667.         {
  668.                 SPIWrite(TypeSH,0x01);
  669.         }
  670.         else
  671.         {
  672.                 SPIWrite(TypeSH,0x00);
  673.         }

  674. }

  675. /****************************************************************/
  676. /*名称: Command_Send */
  677. /*功能: 该函数实现向FM1702发送命令集的功能*/
  678. /*输入: count, 待发送命令集的长度*/
  679. /* buff, 指向待发送数据的指针*/
  680. /* Comm_Set, 命令码*/
  681. /*输出: TRUE, 命令被正确执行*/
  682. /* FALSE, 命令执行错误*/
  683. /****************************************************************/
  684. uchar Command_Send(uchar count, uchar idata *buff, uchar Comm_Set)
  685. {

  686.         uint                j;
  687.         uchar idata        temp, temp1;
  688.        
  689.         SPIWrite(Command,0x00);
  690.         Clear_FIFO();
  691.         Write_FIFO(count, buff);

  692.        
  693.         SPIWrite(Command,Comm_Set);                /* 命令执行 */
  694.         for(j = 0; j < RF_TimeOut; j++) /* 检查命令执行否 */
  695.         {
  696.                 temp = SPIRead(Command);
  697.                 temp1 = SPIRead(Int_Req) & 0x80;
  698.                 if(temp == 0x00)
  699.                 {
  700.                         return TRUE;
  701.                 }
  702.         }

  703.         return FALSE;
  704. }

  705. /****************************************************************/
  706. /*名称: Read_E2 */
  707. /*功能: 该函数实现从FM1702的EE中读出数据*/
  708. /*输入: lsb, EE地址(低字节) */
  709. /* msb, EE地址(高字节) */
  710. /* count, 待读出数据EE的字节个数*/
  711. /* buff, 指向待读出数据的指针*/
  712. /*输出: TRUE, EE数据正确读出*/
  713. /* FALSE, EE数据读出有误*/
  714. /****************************************************************/
  715. uchar Read_E2(uchar lsb, uchar msb, uchar count, uchar idata *buff)
  716. {
  717.        
  718.         uchar        temp;
  719.        
  720.         *buff = lsb;
  721.         *(buff + 1) = msb;
  722.         *(buff + 2) = count;
  723.         temp = Command_Send(3, buff, ReadE2);
  724.         Read_FIFO(buff);
  725.         if(temp == FALSE) return(TRUE);
  726.         return(FALSE);
  727. }

  728. /****************************************************************/
  729. /*名称: Write_E2 */
  730. /*功能: 该函数实现向FM1702的EE中写入数据*/
  731. /*输入: lsb, EE地址(低字节) */
  732. /* msb, EE地址(高字节) */
  733. /* count, 待写入数据EE的字节个数*/
  734. /* buff, 指向待写入数据的指针*/
  735. /*输出: TRUE, EE数据正确写入*/
  736. /* FALSE, EE数据写入有误*/
  737. /****************************************************************/
  738. uchar Write_E2(uchar lsb, uchar msb, uchar count, uchar idata *buff)
  739. {

  740.         uchar idata        temp, i;

  741.         for(i = 0; i < count; i++)
  742.         {
  743.                 *(buff + count - i + 2) = *(buff - i + count);
  744.         }

  745.         *buff = lsb;
  746.         *(buff + 1) = msb;
  747.         temp = Command_Send(count + 2, buff, WriteE2);
  748.         temp = SPIRead(SecondaryStatus);
  749.         temp = temp & 0x40;
  750.         if(temp == 0x40)
  751.         {
  752.                 SPIWrite(Command,0x00);                        //added 2006/03/15
  753.                 return TRUE;
  754.         }

  755.         return FALSE;
  756. }

  757. /****************************************************************/
  758. /*名称: MIF_Halt */
  759. /*功能: 该函数实现暂停MIFARE卡*/
  760. /*输入: N/A */
  761. /*输出: FM1702_OK: 应答正确*/
  762. /* FM1702_PARITYERR: 奇偶校验错*/
  763. /* FM1702_CRCERR: CRC校验错*/
  764. /* FM1702_NOTAGERR: 无卡*/
  765. /****************************************************************/
  766. uchar MIF_Halt(void)
  767. {

  768.         uchar        temp;
  769.         uint        i;
  770.        
  771.         SPIWrite(CRCPresetLSB,0x63);
  772.         SPIWrite(CWConductance,0x3f);
  773.         SPIWrite(ChannelRedundancy,0x03);
  774.         *RevBuffer = RF_CMD_HALT;
  775.         *(RevBuffer + 1) = 0x00;
  776.         temp = Command_Send(2, RevBuffer, Transmit);
  777.         if(temp == TRUE)
  778.         {
  779.                 for(i = 0; i < 0x50; i++)
  780.                 {
  781.                         _nop_();
  782.                 }

  783.                 return FM1702_OK;
  784.         }
  785.         else
  786.         {
  787.                 temp = SPIRead(ErrorFlag);
  788.                 if((temp & 0x02) == 0x02)
  789.                 {
  790.                         return(FM1702_PARITYERR);
  791.                 }

  792.                 if((temp & 0x04) == 0x04)
  793.                 {
  794.                         return(FM1702_FRAMINGERR);
  795.                 }

  796.                 return(FM1702_NOTAGERR);
  797.         }
  798. }

  799. ///////////////////////////////////////////////////////////////////////
  800. // 转换密钥格式
  801. ///////////////////////////////////////////////////////////////////////
  802. char M500HostCodeKey(  uchar *uncoded, uchar *coded)   
  803. {
  804.     char idata status = FM1702_OK;
  805.     uchar idata cnt = 0;
  806.     uchar idata ln  = 0;     
  807.     uchar idata hn  = 0;      
  808.     for (cnt = 0; cnt < 6; cnt++)
  809.     {
  810.         ln = uncoded[cnt] & 0x0F;
  811.         hn = uncoded[cnt] >> 4;
  812.         coded[cnt * 2 + 1] = (~ln << 4) | ln;
  813.         coded[cnt * 2 ] = (~hn << 4) | hn;
  814.     }
  815.     return FM1702_OK;
  816. }






  817. /****************************************************************/
  818. /*名称: Load_keyE2 */
  819. /*功能: 该函数实现把E2中密码存入FM1702的keyRevBuffer中*/
  820. /*输入: Secnr: EE起始地址*/
  821. /*输出: True: 密钥装载成功*/
  822. /* False: 密钥装载失败*/
  823. /****************************************************************/
  824. uchar Load_keyE2_CPY(uchar Secnr, uchar Mode)
  825. {
  826.         char idata status;
  827.         uchar        temp;       
  828.         uchar        msb = 0;
  829.         uchar        lsb = 0;
  830.         uchar coded_keys[12];

  831.         uchar        temp1;
  832.         if(Secnr >= 0x20)
  833.         {
  834.           temp1 = Secnr - 0x20;
  835.           Secnr = 0x20 + temp1 * 4;
  836.         }

  837.         temp = Secnr * 12;

  838.         if(Mode == RF_CMD_AUTH_LA)
  839.         {
  840.                 if(temp >= 0x80)       
  841.                 {
  842.                         lsb = temp - 0x80;
  843.                         msb = 0x01;
  844.                 }
  845.                 else
  846.                 {
  847.                         lsb = temp + 0x80;
  848.                         msb = 0x00;
  849.                 }
  850.         }
  851.         else
  852.         {
  853.                 msb = 0x01;
  854.                 lsb = temp + 0x40;
  855.         }
  856.        
  857.         status = M500HostCodeKey(&RevBuffer[3],coded_keys);////////////////
  858.         status = Write_E2(lsb, msb, 12, coded_keys);             ////////////////
  859.         if(status != FM1702_OK)
  860.         {
  861.                 return FALSE;
  862.         }

  863.         return TRUE;       

  864. }


  865. /****************************************************************/
  866. /*名称: Load_keyE2 */
  867. /*功能: 该函数实现把E2中密码存入FM1702的keyRevBuffer中*/
  868. /*输入: Secnr: EE起始地址*/
  869. /*输出: True: 密钥装载成功*/
  870. /* False: 密钥装载失败*/
  871. /****************************************************************/
  872. uchar Load_keyE2(uchar Secnr, uchar Mode)
  873. {
  874.         uchar        temp;       
  875.         uchar        msb = 0;
  876.         uchar        lsb = 0;

  877.         uchar        temp1;
  878.         if(Secnr >= 0x20)
  879.         {
  880.           temp1 = Secnr - 0x20;
  881.           Secnr = 0x20 + temp1 * 4;
  882.         }

  883.         temp = Secnr * 12;

  884.         if(Mode == RF_CMD_AUTH_LA)
  885.         {
  886.                 if(temp >= 0x80)       
  887.                 {
  888.                         lsb = temp - 0x80;
  889.                         msb = 0x01;
  890.                 }
  891.                 else
  892.                 {
  893.                         lsb = temp + 0x80;
  894.                         msb = 0x00;
  895.                 }
  896.         }
  897.         else
  898.         {
  899.                 msb = 0x01;
  900.                 lsb = temp + 0x40;
  901.         }
  902.        
  903.         RevBuffer[0] = lsb;
  904.         RevBuffer[1] = msb;
  905.        
  906.         temp = Command_Send(2, RevBuffer, LoadKeyE2);
  907.         temp = SPIRead(ErrorFlag) & 0x40;
  908.         if(temp == 0x40)
  909.         {
  910.                 return FALSE;
  911.         }

  912.         return TRUE;
  913. }


  914. /****************************************************************/
  915. /*名称: Request */
  916. /*功能: 该函数实现对放入FM1702操作范围之内的卡片的Request操作*/
  917. /*输入: mode: ALL(监测所以FM1702操作范围之内的卡片) */
  918. /* STD(监测在FM1702操作范围之内处于HALT状态的卡片) */
  919. /*输出: FM1702_NOTAGERR: 无卡*/
  920. /* FM1702_OK: 应答正确*/
  921. /* FM1702_REQERR: 应答错误*/
  922. /****************************************************************/
  923. uchar Request(uchar mode)
  924. {
  925.        
  926.         uchar idata        temp;
  927.        
  928. //        SPIWrite(CRCPresetLSB,0x63);                //CRCPresetLSB address is 0x23
  929. //        SPIWrite(CWConductance,0x3f);
  930.         RevBuffer[0] = mode;       
  931.         SPIWrite(Bit_Frame,0x07);               
  932.         SPIWrite(ChannelRedundancy,0x03);       
  933.         temp = SPIRead(Control);
  934.         temp = temp & (0xf7);
  935.         SPIWrite(Control,temp);                        //Control reset value is 00
  936.         temp = Command_Send(1, RevBuffer, Transceive);   //Transceive=0x1E
  937.         if(temp == FALSE)
  938.         {
  939.                 return FM1702_NOTAGERR;
  940.         }

  941.         Read_FIFO(RevBuffer);       
  942.         temp = Judge_Req(RevBuffer);
  943.         if(temp == TRUE)
  944.         {
  945.                 tagtype[0] = RevBuffer[0];
  946.                 tagtype[1] = RevBuffer[1];
  947.                 return FM1702_OK;
  948.         }                                                       

  949.         return FM1702_REQERR;
  950. }

  951. /****************************************************************/
  952. /*名称: AntiColl */
  953. /*功能: 该函数实现对放入FM1702操作范围之内的卡片的防冲突检测*/
  954. /*输入: N/A */
  955. /*输出: FM1702_NOTAGERR: 无卡*/
  956. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  957. /* FM1702_SERNRERR: 卡片序列号应答错误*/
  958. /* FM1702_OK: 卡片应答正确*/
  959. /****************************************************************/
  960. uchar AntiColl(void)
  961. {
  962.        
  963.         uchar        temp;
  964.         uchar        i;
  965.         uchar        row, col;
  966.         uchar        pre_row;
  967.        
  968.         row = 0;
  969.         col = 0;
  970.         pre_row = 0;
  971.         SPIWrite(CRCPresetLSB,0x63);
  972.         SPIWrite(CWConductance,0x3f);
  973. //        SPIWrite(ModConductance,0x3f);
  974.         RevBuffer[0] = RF_CMD_ANTICOL;
  975.         RevBuffer[1] = 0x20;
  976.         SPIWrite(ChannelRedundancy,0x03);
  977.         temp = Command_Send(2, RevBuffer, Transceive);
  978.         while(1)
  979.         {
  980.                 if(temp == FALSE)
  981.                 {
  982.                         return(FM1702_NOTAGERR);
  983.                 }

  984.                 //temp = ErrorFlag;

  985.                 temp = SPIRead(FIFO_Length);
  986.                 if(temp == 0)
  987.                 {
  988.                         return FM1702_BYTECOUNTERR;
  989.                 }

  990.                 Read_FIFO(RevBuffer);
  991.                 Save_UID(row, col, temp);                        /* 将收到的UID放入UID数组中 */
  992.                
  993.                
  994.                 temp = SPIRead(ErrorFlag);                                    /* 判断接収数据是否出错 */
  995.                 temp = temp & 0x01;
  996.                 if(temp == 0x00)
  997.                 {
  998.                         temp = Check_UID();                        /* 校验收到的UID */
  999.                         if(temp == FALSE)
  1000.                         {
  1001.                                 return(FM1702_SERNRERR);
  1002.                         }

  1003.                         return(FM1702_OK);
  1004.                 }
  1005.                 else
  1006.                 {
  1007.                         temp = SPIRead(CollPos);                                /* 读取冲突检测寄存器 */
  1008.                         row = temp / 8;
  1009.                         col = temp % 8;
  1010.                         RevBuffer[0] = RF_CMD_ANTICOL;
  1011.                         Set_BitFraming(row + pre_row, col);        /* 设置待发送数据的字节数 */
  1012.                         pre_row = pre_row + row;
  1013.                         for(i = 0; i < pre_row + 1; i++)
  1014.                         {
  1015.                                 RevBuffer[i + 2] = UID[i];
  1016.                         }

  1017.                         if(col != 0x00)
  1018.                         {
  1019.                                 row = pre_row + 1;
  1020.                         }
  1021.                         else
  1022.                         {
  1023.                                 row = pre_row;
  1024.                         }

  1025.                         temp = Command_Send(row + 2, RevBuffer, Transceive);
  1026.                 }
  1027.         }
  1028. }

  1029. /****************************************************************/
  1030. /*名称: Select_Card */
  1031. /*功能: 该函数实现对放入FM1702操作范围之内的某张卡片进行选择*/
  1032. /*输入: N/A */
  1033. /*输出: FM1702_NOTAGERR: 无卡*/
  1034. /* FM1702_PARITYERR: 奇偶校验错*/
  1035. /* FM1702_CRCERR: CRC校验错*/
  1036. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1037. /* FM1702_OK: 应答正确*/
  1038. /* FM1702_SELERR: 选卡出错*/
  1039. /****************************************************************/
  1040. uchar Select_Card(void)
  1041. {
  1042.        
  1043.         uchar        temp, i;
  1044.        
  1045.         SPIWrite(CRCPresetLSB,0x63);
  1046.         SPIWrite(CWConductance,0x3f);
  1047.         RevBuffer[0] = RF_CMD_SELECT;
  1048.         RevBuffer[1] = 0x70;
  1049.         for(i = 0; i < 5; i++)
  1050.         {
  1051.                 RevBuffer[i + 2] = UID[i];
  1052.         }

  1053.         SPIWrite(ChannelRedundancy,0x0f);       
  1054.         temp = Command_Send(7, RevBuffer, Transceive);
  1055.         if(temp == FALSE)
  1056.         {
  1057.                 return(FM1702_NOTAGERR);
  1058.         }
  1059.         else
  1060.         {
  1061.                 temp = SPIRead(ErrorFlag);
  1062.                 if((temp & 0x02) == 0x02) return(FM1702_PARITYERR);
  1063.                 if((temp & 0x04) == 0x04) return(FM1702_FRAMINGERR);
  1064.                 if((temp & 0x08) == 0x08) return(FM1702_CRCERR);
  1065.                 temp = SPIRead(FIFO_Length);
  1066.                 if(temp != 1) return(FM1702_BYTECOUNTERR);
  1067.                 Read_FIFO(RevBuffer);        /* 从FIFO中读取应答信息 */
  1068.                 temp = *RevBuffer;

  1069.                 if((temp == 0x18) || (temp == 0x08) || (temp == 0x88) || (temp == 0x53))        /* 判断应答信号是否正确 */
  1070.                         return(FM1702_OK);
  1071.                 else
  1072.                         return(FM1702_SELERR);
  1073.         }
  1074. }

  1075. /****************************************************************/
  1076. /*名称: Authentication */
  1077. /*功能: 该函数实现密码认证的过程*/
  1078. /*输入: UID: 卡片序列号地址*/
  1079. /* SecNR: 扇区号*/
  1080. /* mode: 模式*/
  1081. /*输出: FM1702_NOTAGERR: 无卡*/
  1082. /* FM1702_PARITYERR: 奇偶校验错*/
  1083. /* FM1702_CRCERR: CRC校验错*/
  1084. /* FM1702_OK: 应答正确*/
  1085. /* FM1702_AUTHERR: 权威认证有错*/
  1086. /****************************************************************/
  1087. uchar Authentication(uchar idata *UID, uchar SecNR, uchar mode)
  1088. {
  1089.        
  1090.         uchar idata        i;
  1091.         uchar idata        temp, temp1;

  1092.         uchar temp0;
  1093.         if(SecNR >= 0x20)
  1094.         {
  1095.                 temp0 = SecNR -0x20;
  1096.                 SecNR = 0x20 + temp0 * 4;
  1097.         }
  1098.        
  1099.         SPIWrite(CRCPresetLSB,0x63);
  1100.         SPIWrite(CWConductance,0x3f);
  1101. //        SPIWrite(ModConductance,0X3f);
  1102. //        temp1 = SPIRead(Control);
  1103. //        temp1 = temp1 & 0xf7;
  1104. //        SPIWrite(Control,temp1);
  1105.         if(mode == RF_CMD_AUTH_LB)                       
  1106.                 RevBuffer[0] = RF_CMD_AUTH_LB;
  1107.         else
  1108.                 RevBuffer[0] = RF_CMD_AUTH_LA;
  1109.         RevBuffer[1] = SecNR * 4 + 3;
  1110.         for(i = 0; i < 4; i++)
  1111.         {
  1112.                 RevBuffer[2 + i] = UID[i];
  1113.         }

  1114.         SPIWrite(ChannelRedundancy,0x0f);       
  1115.         temp = Command_Send(6, RevBuffer, Authent1);
  1116.         if(temp == FALSE)
  1117.         {
  1118.                
  1119.                 return 0x99;
  1120.         }

  1121.         temp = SPIRead(ErrorFlag);             //ErrorFlag address is 0x0A.
  1122.         if((temp & 0x02) == 0x02) return FM1702_PARITYERR;
  1123.         if((temp & 0x04) == 0x04) return FM1702_FRAMINGERR;
  1124.         if((temp & 0x08) == 0x08) return FM1702_CRCERR;
  1125.         temp = Command_Send(0, RevBuffer, Authent2);       
  1126.         if(temp == FALSE)
  1127.         {
  1128.                
  1129.                 return 0x88;
  1130.         }

  1131.         temp = SPIRead(ErrorFlag);
  1132.         if((temp & 0x02) == 0x02) return FM1702_PARITYERR;
  1133.         if((temp & 0x04) == 0x04) return FM1702_FRAMINGERR;
  1134.         if((temp & 0x08) == 0x08) return FM1702_CRCERR;
  1135.         temp1 = SPIRead(Control);
  1136.         temp1 = temp1 & 0x08;       
  1137.         if(temp1 == 0x08)
  1138.         {
  1139.                 return FM1702_OK;
  1140.         }

  1141.         return FM1702_AUTHERR;
  1142. }

  1143. /****************************************************************/
  1144. /*名称: MIF_Read */
  1145. /*功能: 该函数实现读MIFARE卡块的数值*/
  1146. /*输入: buff: 缓冲区首地址*/
  1147. /* Block_Adr: 块地址*/
  1148. /*输出: FM1702_NOTAGERR: 无卡*/
  1149. /* FM1702_PARITYERR: 奇偶校验错*/
  1150. /* FM1702_CRCERR: CRC校验错*/
  1151. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1152. /* FM1702_OK: 应答正确*/
  1153. /****************************************************************/
  1154. uchar MIF_READ(uchar idata *buff, uchar Block_Adr)
  1155. {
  1156.        
  1157.         uchar idata        temp;
  1158.        
  1159.         SPIWrite(CRCPresetLSB,0x63);
  1160.         SPIWrite(CWConductance,0x3f);
  1161.         SPIWrite(ModConductance,0x3f);
  1162.         SPIWrite(ChannelRedundancy,0x0f);

  1163.         buff[0] = RF_CMD_READ;
  1164.         buff[1] = Block_Adr;
  1165.         temp = Command_Send(2, buff, Transceive);
  1166.         if(temp == 0)
  1167.         {
  1168.                 return FM1702_NOTAGERR;
  1169.         }

  1170.         temp = SPIRead(ErrorFlag);
  1171.         if((temp & 0x02) == 0x02) return FM1702_PARITYERR;
  1172.         if((temp & 0x04) == 0x04) return FM1702_FRAMINGERR;
  1173.         if((temp & 0x08) == 0x08) return FM1702_CRCERR;
  1174.         temp = SPIRead(FIFO_Length);
  1175.         if(temp == 0x10)       
  1176.         {
  1177.                 Read_FIFO(buff);
  1178.                 return FM1702_OK;
  1179.         }
  1180.         else if(temp == 0x04)       
  1181.         {
  1182.                 Read_FIFO(buff);
  1183.                 return FM1702_OK;
  1184.         }
  1185.         else
  1186.         {
  1187.                 return FM1702_BYTECOUNTERR;
  1188.         }
  1189. }

  1190. /****************************************************************/
  1191. /*名称: MIF_Write */
  1192. /*功能: 该函数实现写MIFARE卡块的数值*/
  1193. /*输入: buff: 缓冲区首地址*/
  1194. /* Block_Adr: 块地址*/
  1195. /*输出: FM1702_NOTAGERR: 无卡*/
  1196. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1197. /* FM1702_NOTAUTHERR: 未经权威认证*/
  1198. /* FM1702_EMPTY: 数据溢出错误*/
  1199. /* FM1702_CRCERR: CRC校验错*/
  1200. /* FM1702_PARITYERR: 奇偶校验错*/
  1201. /* FM1702_WRITEERR: 写卡块数据出错*/
  1202. /* FM1702_OK: 应答正确*/
  1203. /****************************************************************/
  1204. uchar MIF_Write(uchar idata *buff, uchar Block_Adr)
  1205. {

  1206.         uchar idata        temp;
  1207.         uchar idata        *F_buff;

  1208.         SPIWrite(CRCPresetLSB,0x63);
  1209.         SPIWrite(CWConductance,0x3f);
  1210.         F_buff = buff + 0x10;
  1211.         SPIWrite(ChannelRedundancy,0x07);    /* Note: this line is for 1702, different from RC500*/
  1212.         *F_buff = RF_CMD_WRITE;
  1213.         *(F_buff + 1) = Block_Adr;
  1214.         temp = Command_Send(2, F_buff, Transceive);
  1215.         if(temp == FALSE)
  1216.         {
  1217.                 return(FM1702_NOTAGERR);
  1218.         }

  1219.         temp = SPIRead(FIFO_Length);
  1220.         if(temp == 0)
  1221.         {
  1222.                 return(FM1702_BYTECOUNTERR);
  1223.         }

  1224.         Read_FIFO(F_buff);
  1225.         temp = *F_buff;
  1226.         switch(temp)
  1227.         {
  1228.         case 0x00:        return(FM1702_NOTAUTHERR);       
  1229.         case 0x04:        return(FM1702_EMPTY);
  1230.         case 0x0a:        break;
  1231.         case 0x01:        return(FM1702_CRCERR);
  1232.         case 0x05:        return(FM1702_PARITYERR);
  1233.         default:        return(FM1702_WRITEERR);
  1234.         }

  1235.         temp = Command_Send(16, buff, Transceive);
  1236.         if(temp == TRUE)
  1237.         {
  1238.                 return(FM1702_OK);
  1239.         }
  1240.         else
  1241.         {
  1242.                 temp = SPIRead(ErrorFlag);
  1243.                 if((temp & 0x02) == 0x02)
  1244.                         return(FM1702_PARITYERR);
  1245.                 else if((temp & 0x04) == 0x04)
  1246.                         return(FM1702_FRAMINGERR);
  1247.                 else if((temp & 0x08) == 0x08)
  1248.                         return(FM1702_CRCERR);
  1249.                 else
  1250.                         return(FM1702_WRITEERR);
  1251.         }
  1252. }

  1253. /****************************************************************/
  1254. /*名称: MIF_Increment */
  1255. /*功能: 该函数实现MIFARE卡自动增值操作*/
  1256. /*输入: buff: 四个字节数值起始地址*/
  1257. /* Block_Adr: 块地址*/
  1258. /*输出: FM1702_NOTAGERR: 无卡*/
  1259. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1260. /* FM1702_NOTAUTHERR: 未经权威认证*/
  1261. /* FM1702_EMPTY: 数据溢出错误*/
  1262. /* FM1702_CRCERR: CRC校验错*/
  1263. /* FM1702_PARITYERR: 奇偶校验错*/
  1264. /* FM1702_INCRERR: 卡片增款操作失败*/
  1265. /* FM1702_OK: 应答正确*/
  1266. /****************************************************************/
  1267. uchar MIF_Increment(uchar idata *buff, uchar Block_Adr)
  1268. {
  1269.        
  1270.         uchar                temp;
  1271.         uchar idata        *F_buff;
  1272.        
  1273.         SPIWrite(CRCPresetLSB,0x63);
  1274.         SPIWrite(CWConductance,0x3f);
  1275.         F_buff = buff + 4;
  1276.         *F_buff = RF_CMD_INC;
  1277.         *(F_buff + 1) = Block_Adr;
  1278.         SPIWrite(ChannelRedundancy,0x07);
  1279.         temp = Command_Send(2, F_buff, Transceive);
  1280.         if(temp == FALSE)
  1281.         {
  1282.                 return FM1702_NOTAGERR;
  1283.         }

  1284.         temp = SPIRead(FIFO_Length);
  1285.         if(temp == 0)
  1286.         {
  1287.                 return FM1702_BYTECOUNTERR;
  1288.         }

  1289.         Read_FIFO(F_buff);
  1290.         temp = *F_buff;
  1291.         switch(temp)
  1292.         {
  1293.         case 0x00:        /* break; */return(FM1702_NOTAUTHERR);
  1294.         case 0x04:        return(FM1702_EMPTY);
  1295.         case 0x0a:        break;
  1296.         case 0x01:        return(FM1702_CRCERR);
  1297.         case 0x05:        return(FM1702_PARITYERR);
  1298.         default:        return(FM1702_INCRERR);
  1299.         }
  1300.         
  1301.         temp = Command_Send(4, buff, Transmit);
  1302.         if(temp == FALSE)
  1303.         {
  1304.                 return FM1702_INCRERR;
  1305.         }

  1306.         return FM1702_OK;
  1307. }

  1308. /****************************************************************/
  1309. /*名称: MIF_Decrement */
  1310. /*功能: 该函数实现MIFARE卡自动减值操作*/
  1311. /*输入: buff: 四个字节数值起始地址*/
  1312. /* Block_Adr: 块地址*/
  1313. /*输出: FM1702_NOTAGERR: 无卡*/
  1314. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1315. /* FM1702_NOTAUTHERR: 未经权威认证*/
  1316. /* FM1702_EMPTY: 数据溢出错误*/
  1317. /* FM1702_CRCERR: CRC校验错*/
  1318. /* FM1702_PARITYERR: 奇偶校验错*/
  1319. /* FM1702_DECRERR: 卡片扣款操作失败*/
  1320. /* FM1702_OK: 应答正确*/
  1321. /****************************************************************/
  1322. uchar MIF_Decrement(uchar idata *buff, uchar Block_Adr)
  1323. {
  1324.        
  1325.         uchar                temp;
  1326.         uchar idata        *F_buff;
  1327.        
  1328.         SPIWrite(CRCPresetLSB,0x63);
  1329.         SPIWrite(CWConductance,0x3f);
  1330.         F_buff = buff + 4;
  1331.         *F_buff = RF_CMD_DEC;
  1332.         *(F_buff + 1) = Block_Adr;
  1333.         SPIWrite(ChannelRedundancy,0x07);
  1334.         temp = Command_Send(2, F_buff, Transceive);
  1335.         if(temp == FALSE)
  1336.         {
  1337.                 return FM1702_NOTAGERR;
  1338.         }

  1339.         temp = SPIRead(FIFO_Length);
  1340.         if(temp == 0)
  1341.         {
  1342.                 return FM1702_BYTECOUNTERR;
  1343.         }

  1344.         Read_FIFO(F_buff);
  1345.         temp = *F_buff;
  1346.         switch(temp)
  1347.         {
  1348.         case 0x00:        /* break; */return(FM1702_NOTAUTHERR);       
  1349.         case 0x04:        return(FM1702_EMPTY);
  1350.         case 0x0a:        break;
  1351.         case 0x01:        return(FM1702_CRCERR);
  1352.         case 0x05:        return(FM1702_PARITYERR);
  1353.         default:        return(FM1702_DECRERR);
  1354.         }

  1355.         temp = Command_Send(4, buff, Transmit);
  1356.         if(temp == FALSE)
  1357.         {
  1358.                 return(FM1702_DECRERR);
  1359.         }

  1360.         return FM1702_OK;
  1361. }

  1362. /****************************************************************/
  1363. /*名称: MIF_Restore */
  1364. /*功能: 该函数实现MIFARE卡自动恢复,备份操作*/
  1365. /*输入: Block_Adr: 块地址*/
  1366. /*输出: FM1702_NOTAGERR: 无卡*/
  1367. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1368. /* FM1702_NOTAUTHERR: 未经权威认证*/
  1369. /* FM1702_EMPTY: 数据溢出错误*/
  1370. /* FM1702_CRCERR: CRC校验错*/
  1371. /* FM1702_PARITYERR: 奇偶校验错*/
  1372. /* FM1702_RESTERR: 卡片恢复,备份操作失败*/
  1373. /* FM1702_OK: 应答正确*/
  1374. /****************************************************************/
  1375. uchar MIF_Restore(uchar Block_Adr)
  1376. {
  1377.        
  1378.         uchar        temp, i;
  1379.        
  1380.         SPIWrite(CRCPresetLSB,0x63);
  1381.         SPIWrite(CWConductance,0x3f);
  1382.         SPIWrite(ChannelRedundancy,0x07);
  1383.         *RevBuffer = RF_CMD_RESTORE;
  1384.         *(RevBuffer + 1) = Block_Adr;
  1385.         temp = Command_Send(2, RevBuffer, Transceive);
  1386.         if(temp == FALSE)
  1387.         {
  1388.                 return FM1702_NOTAGERR;
  1389.         }

  1390.         temp = SPIRead(FIFO_Length);
  1391.         if(temp == 0)
  1392.         {
  1393.                 return FM1702_BYTECOUNTERR;
  1394.         }

  1395.         Read_FIFO(RevBuffer);
  1396.         temp = *RevBuffer;
  1397.         switch(temp)
  1398.         {
  1399.         case 0x00:        /* break; */return(FM1702_NOTAUTHERR);       
  1400.         case 0x04:        return(FM1702_EMPTY);
  1401.         case 0x0a:        break;
  1402.         case 0x01:        return(FM1702_CRCERR);
  1403.         case 0x05:        return(FM1702_PARITYERR);
  1404.         default:        return(FM1702_RESTERR);
  1405.         }

  1406.         for(i = 0; i < 4; i++) RevBuffer[i] = 0x00;
  1407.         temp = Command_Send(4, RevBuffer, Transmit);
  1408.         if(temp == FALSE)
  1409.         {
  1410.                 return FM1702_RESTERR;
  1411.         }

  1412.         return FM1702_OK;
  1413. }

  1414. /****************************************************************/
  1415. /*名称: MIF_Transfer */
  1416. /*功能: 该函数实现MIFARE卡电子钱包保存操作*/
  1417. /*输入: Block_Adr: 块地址*/
  1418. /*输出: FM1702_NOTAGERR: 无卡*/
  1419. /* FM1702_BYTECOUNTERR: 接收字节错误*/
  1420. /* FM1702_NOTAUTHERR: 未经权威认证*/
  1421. /* FM1702_EMPTY: 数据溢出错误*/
  1422. /* FM1702_CRCERR: CRC校验错*/
  1423. /* FM1702_PARITYERR: 奇偶校验错*/
  1424. /* FM1702_TRANSERR: 卡片恢复,备份操作失败*/
  1425. /* FM1702_OK: 应答正确*/
  1426. /****************************************************************/
  1427. uchar MIF_Transfer(uchar Block_Adr)
  1428. {
  1429.        
  1430.         uchar        temp;
  1431.         SPIWrite(CRCPresetLSB,0x63);
  1432.         SPIWrite(CWConductance,0x3f);
  1433.         SPIWrite(ChannelRedundancy,0x07);       
  1434.         RevBuffer[0] = RF_CMD_TRANSFER;
  1435.         RevBuffer[1] = Block_Adr;
  1436.         temp = Command_Send(2, RevBuffer, Transceive);
  1437.         if(temp == FALSE)
  1438.         {
  1439.                 return FM1702_NOTAGERR;
  1440.         }

  1441.         temp = SPIRead(FIFO_Length);
  1442.         if(temp == 0)
  1443.         {
  1444.                 return FM1702_BYTECOUNTERR;
  1445.         }

  1446.         Read_FIFO(RevBuffer);
  1447.         temp = *RevBuffer;
  1448.         switch(temp)
  1449.         {
  1450.         case 0x00:        /* break; */return(FM1702_NOTAUTHERR);       
  1451.         case 0x04:        return(FM1702_EMPTY);
  1452.         case 0x0a:        return(FM1702_OK);
  1453.         case 0x01:        return(FM1702_CRCERR);
  1454.         case 0x05:        return(FM1702_PARITYERR);
  1455.         default:        return(FM1702_TRANSERR);
  1456.         }
  1457. }

  1458. #if 0
  1459. /****************************************************************/
  1460. /*名称: HL_Active */
  1461. /*功能: 该函数实现高级MIFARE卡激活命令*/
  1462. /*输入: Secnr: 扇区号*/
  1463. /* Block_Adr: 块地址*/
  1464. /*输出: 操作状态码*/
  1465. /* 读出数据存于RevBuffer中*/
  1466. /****************************************************************/
  1467. uchar HL_Active(uchar Block_Adr, uchar Mode)
  1468. {
  1469.        
  1470.         uchar        temp;
  1471.        
  1472.         Secnr = Block_Adr / 4;
  1473.         MIF_Halt();        /* Halt */
  1474.         temp = Request(RF_CMD_REQUEST_STD);               
  1475.         if(temp != FM1702_OK)
  1476.         {
  1477.                 return(FM1702_REQERR);
  1478.         }

  1479.         temp = AntiColl();                               
  1480.         if(temp != FM1702_OK)
  1481.         {
  1482.                 return(FM1702_ANTICOLLERR);
  1483.         }

  1484.         temp = Select_Card();                               
  1485.         if(temp != FM1702_OK)
  1486.         {
  1487.                 return(FM1702_SELERR);
  1488.         }

  1489.         Load_keyE2_CPY(Secnr, Mode);        //%40       
  1490. ……………………

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

所有资料51hei提供下载:

1702SL开发板源码.rar (42.75 KB, 下载次数: 36)

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

使用道具 举报

沙发
ID:1 发表于 2018-12-9 00:51 | 只看该作者
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

板凳
ID:461708 发表于 2019-1-4 13:14 | 只看该作者
不错!~~~~~
回复

使用道具 举报

地板
ID:29579 发表于 2022-8-19 14:14 | 只看该作者
谢谢分享
回复

使用道具 举报

5#
ID:1096636 发表于 2023-10-20 09:01 | 只看该作者
可否提供原理图学习呀,谢谢!
回复

使用道具 举报

6#
ID:1100683 发表于 2023-11-21 17:35 | 只看该作者
请问,是什么型号的单片机?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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