搜索
bottom↓
回复: 19

RFID 读写器中使用SST89E58

[复制链接]

出0入0汤圆

发表于 2012-5-8 15:16:26 | 显示全部楼层 |阅读模式
用SST89E58单片机+SL RC632读卡芯片,用于测试ISO14443A协议指令。按照例程修改程序,开始的时候发送寻卡指令“26”,“52”,完全没有反应,也就是没有返回,后来修改一些寄存器值后,有返回,应该是返回卡片类型的,却返回的是“14 14”,这样就说明寻不到卡片,程序还是没有调试正确,程序问题是出现在哪部分呢?是寻卡函数PcdRequest();还是PCD与卡片通信函数PcdComTransceive();或是一开始的配置14443A协议函数PcdConfigISOType();寄存器就没有设置正确?请大虾们指教啊,急急急!

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2012-5-8 21:03:57 | 显示全部楼层
RC632 先 M500PcdConfig(); →  M500PcdConfigISOType(TYPEA); → M500PiccRequest(PICC_REQSTD, &TagType); 看看有没有返回 0400,如果有就说明读到卡
我比较想知道,你RC632与89E58之间用的是什么接口?SPI还是并口?中断还是查询方式

你可以先把RC632当做RC500来用,看看能否正确寻卡,防冲突,另外在做寻卡之前最好先SOR/LOAD KEY

另外给你一份文档


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-5-8 23:58:31 | 显示全部楼层
黑暗深处 发表于 2012-5-8 21:03
RC632 先 M500PcdConfig(); →  M500PcdConfigISOType(TYPEA); → M500PiccRequest(PICC_REQSTD, &TagType) ...

谢谢解答。632与单片机之间通过SPI方式连接,中断方式。我这里只有RC632例程代码,没有RC500的,网上看到有一些,但是不完整。为什么要在做寻卡之前最好先SOR/LOAD KEY呢?另外SOR KEY是什么命令啊?不好意思,我新手,很多东西不懂,第一次做RFID测试,请多多指教!

出0入0汤圆

 楼主| 发表于 2012-5-9 15:05:18 | 显示全部楼层
用示波器测试了一下,632的TX1和TX2端有方波信号。

出0入0汤圆

 楼主| 发表于 2012-5-9 22:30:46 | 显示全部楼层
黑暗深处 发表于 2012-5-8 21:03
RC632 先 M500PcdConfig(); →  M500PcdConfigISOType(TYPEA); → M500PiccRequest(PICC_REQSTD, &TagType) ...

不好意思,我说错了,我的单片机和632之间是通过并口连接的,不是SPI方式。我的QQ是493010142,希望能与你进一步沟通,多多指教!

出0入0汤圆

发表于 2012-5-10 19:18:21 | 显示全部楼层
给我先看一下你的原理图,就是RC632与单片机的连接

出0入0汤圆

 楼主| 发表于 2012-5-10 21:44:05 | 显示全部楼层
本帖最后由 smilelb 于 2012-5-10 21:46 编辑
黑暗深处 发表于 2012-5-10 19:18
给我先看一下你的原理图,就是RC632与单片机的连接


这个电路不是我设计的,我暂时不能上传到网上,我暂时只能发图的一部分,不好意思!你加我Q吧。。。与上位机通信是用的max232 USB转串口的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-5-11 12:51:30 | 显示全部楼层
smilelb 发表于 2012-5-10 21:44
这个电路不是我设计的,我暂时不能上传到网上,我暂时只能发图的一部分,不好意思!你加我Q吧。。。与上 ...

你RC632的A0 A1 A2配置成什么?

出0入0汤圆

 楼主| 发表于 2012-5-11 14:04:24 | 显示全部楼层
黑暗深处 发表于 2012-5-11 12:51
你RC632的A0 A1 A2配置成什么?


/////////////////////////////////////////////////////////////////////
//系统初始化
/////////////////////////////////////////////////////////////////////
void InitializeSystem()
{
    TMOD &= 0x0F;
    TMOD |= 0x21;
    PCON |= 0x80;
    SCON  = 0x50;
    TH1 = TL1 = BOUND19200;
    TR1=1;
    P0 = P1 = P2 = P3 = 0xFF;
    IE |= 0x90;

        RC632_A0 = 1;
        RC632_A1 = 1;
        RC632_A2 = 0;

        LED_GREEN = 1;   //灯灭
        BEEP = 0;
}

/////////////////////////////////////////////////////////////////////
//初始化RC632
/////////////////////////////////////////////////////////////////////
void Rc632Ready()
{
    char status;
                LED_GREEN = 1;
    DelayMs(100);
    status = PcdReset();
    if(status != MI_OK)
    {
        DelayMs(10);
        status = PcdReset();
    }
    if(status != MI_OK)
    {
        DelayMs(10);
        status = PcdReset();
    }
    if(status == MI_OK)
    {
        g_bRc632Ok = 1;
                LED_GREEN = 0;
                //绿色指示灯亮,表示RC632复位成功
    }      
}
       

出0入0汤圆

发表于 2012-5-11 17:10:51 | 显示全部楼层
char M500PcdConfigISOType(unsigned char type)
{
   if(type==TYPEA)
   {
     WriteIO(RegTxControl,0x5b);         // Force100ASK, TX1 & TX2 enable
     WriteIO(RegCoderControl,0x19);     // Miller coding, 106kbps
     WriteIO(RegRxControl1,0x73);
     WriteIO(RegDecoderControl,0x08);   // Manchester Coding
     WriteIO(RegCRCPresetLSB,0x63);     // set CRC preset to 0x6363
     WriteIO(RegCRCPresetMSB,0x63);
     WriteIO(RegRxThreshold,0xff);          // set max MinLevel & ColLevel.
     TYPE = TYPEA;       
   }
   else
   {

     WriteIO(RegTxControl,0x4b);              // disable Force100ASk
     WriteIO(RegCoderControl,0x20);     // NRZ-L, TypeB baud 106kbps
     WriteIO(RegRxControl1,0x73);       //
     WriteIO(RegDecoderControl,0x19);   // BPSK coding
     WriteIO(RegCRCPresetLSB,0xff);     // set CRC preset to 0xffff
     WriteIO(RegCRCPresetMSB,0xff);
     WriteIO(RegTypeBFraming,0x23);     // EGT=0
     WriteIO(RegBPSKDemControl,0x3e);   // ignore EOF, on amp. detect         
     WriteIO(RegModConductance,0x06);        // set modulation index at 12%
     
     WriteIO(RegRxThreshold,0x44);  // Reduce MinLevel & ColLevel.
                                    // Increase higher nibble if carrier
                                    // present but not detect
     TYPE = TYPEB;
   }
   return MI_OK;
}

先执行上面的函数,设置为typeA

再执行

///////////////////////////////////////////////////////////////////////
//          M I F A R E    R E Q U E S T
///////////////////////////////////////////////////////////////////////
char M500PiccRequest(unsigned char req_code, // request code ALL = 0x52
                                             // or IDLE = 0x26
                   unsigned char *atq)     // answer to request
{
   return M500PiccCommonRequest(req_code,atq);
}

///////////////////////////////////////////////////////////////////////
//          M I F A R E   C O M M O N   R E Q U E S T
///////////////////////////////////////////////////////////////////////
char M500PiccCommonRequest(unsigned char req_code,
                         unsigned char *atq)
{
   char xdata status = MI_OK;

    //************* initialize ******************************
   WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
   ClearBitMask(RegControl,0x08);    // disable crypto 1 unit   
   WriteIO(RegBitFraming,0x07);        // set TxLastBits to 7
   SetBitMask(RegTxControl,0x03);    // Tx2RF-En, Tx1RF-En enable
  
   PcdSetTmo(106);

   ResetInfo(MInfo);   
   MSndBuffer[0] = req_code;
   MInfo.nBytesToSend   = 1;   
   status = PcdSingleResponseCmd(PCD_TRANSCEIVE,
                      MSndBuffer,
                      MRcvBuffer,
                      &MInfo);
  
   if (status)      // error occured
   {
      *atq = 0;
   }
   else
   {
      if (MInfo.nBitsReceived != 16) // 2 bytes expected
      {
         *atq = 0;
         status = MI_BITCOUNTERR;
      }
      else
      {
         status = MI_OK;
         memcpy(atq,MRcvBuffer,2);
      }
   }
   return status;
}

出0入0汤圆

 楼主| 发表于 2012-5-11 17:48:12 | 显示全部楼层
本帖最后由 smilelb 于 2012-5-11 17:54 编辑
黑暗深处 发表于 2012-5-11 17:10
char M500PcdConfigISOType(unsigned char type)
{
   if(type==TYPEA)


疑问一: WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable

REQA和WUPA应该是短帧,应该既没有CRC,也没有parity吧?

疑问二:char M500PcdConfigISOType(unsigned char type);函数中,TypeB的配置情况必须要写进去么,也就是else后面的语句。

三:PCD与PICC通讯函数PcdComTransceive();呢?

出0入0汤圆

发表于 2012-5-11 20:53:21 | 显示全部楼层
第一个问题,请自己看RC632或者RC500的datasheet 第9.2.1章
http://www.cn.nxp.com/documents/data_sheet/MFRC500.pdf

第二个问题,如果仅仅配置读typeA的卡,只需要写入typeA参数

设置完成rc632为typeA模式后,调用M500PiccRequest函数,如果有卡就会返回0400,

你要的PCD与PICC通讯函数请自己去NXP的官方网站下载RC632的库

出0入0汤圆

 楼主| 发表于 2012-5-14 10:33:27 | 显示全部楼层
本帖最后由 smilelb 于 2012-5-14 10:39 编辑

命令的帧,是14443A协议中规定的,包括帧格式,REQA/WUPA是短帧,只有7bit,没有CRC和ParityOdd校验;ANTICOLLISION是面向位的帧,没有CRC,但有ParityOdd;SELECT和HLTA是标准帧,有CRC和ParityOdd。


出0入0汤圆

 楼主| 发表于 2012-5-14 10:38:31 | 显示全部楼层
黑暗深处 发表于 2012-5-11 20:53
第一个问题,请自己看RC632或者RC500的datasheet 第9.2.1章
http://www.cn.nxp.com/documents/data_sheet/M ...

命令的帧,是14443A协议中规定的,包括帧格式,REQA/WUPA是短帧,只有7bit,没有CRC和ParityOdd校验;ANTICOLLISION是面向位的帧,没有CRC,但有ParityOdd;SELECT和HLTA是标准帧,有CRC和ParityOdd。
然后,这是我的配置协议函数,Pcdrequest函数,PcdComTransceive函数,请帮我看看,那个地方设置有问题。

char PcdConfigISOType(unsigned char type)
{
   
   if (type == 'A')                    //ISO14443_A,'A'在ACSII中0x41.
   {
       ClearBitMask(RegControl,0x08);  //disable crypto 1 unit 加密单元关闭
       WriteRawRC(RegClockQControl,0x00);
       WriteRawRC(RegClockQControl,0x40);
       Delay_50us(2);                   // wait approximately 100 us - calibration in progress
       ClearBitMask(RegClockQControl,0x40);
      
       WriteRawRC(RegTxControl,0x5B);
       WriteRawRC(RegCwConductance,0x0F);   //配置输出驱动的电导系数     /////////////////                     
       WriteRawRC(RegModConductance,0x3F);   //配置输出信号的时间调制系数,100%ASK此位无效   
       WriteRawRC(RegCoderControl,0x19);    //配置时钟速率和编码模式,初始值和14443A值均是0x19.
       WriteRawRC(RegModWidth,0x13);       //设定调制脉冲的宽度       脉冲调制宽度Tmod=2(ModWidth+1)/fc=3.0us   
       WriteRawRC(RegModWidthSOF,0x3F);   //SOF调制宽度9.44us                                                     00     
       WriteRawRC(RegTypeBFraming,0x00);
      
       WriteRawRC(RegRxControl1,0x73);    //控制接收行为 ,接收信号电压增益因子为35dB
       WriteRawRC(RegDecoderControl,0x08);  // 控制解调,28(2C),68,08    P45    ////                              
       WriteRawRC(RegBitPhase,0xAD);        //设定发送与接收时钟间的相位关系                        
       WriteRawRC(RegRxThreshold,0xFF);   //设定位解码阈值,88   FF    初值AA     /////////  ////                                       
       WriteRawRC(RegBPSKDemControl,00);   //控制BPSK解调
       WriteRawRC(RegRxControl2,0x41);     //控制解调,并定义接收机decoder的输入   

       WriteRawRC(RegRxWait,0x06);      //
       WriteRawRC(RegChannelRedundancy,0x0F);  //  
       WriteRawRC(RegCRCPresetLSB,0x63);      //14443A的CRC初始值为0x6363
       WriteRawRC(RegCRCPresetMSB,0x63);     //14443A的CRC初始值为0x6363
       WriteRawRC(RegTimeSlotPeriod,0x00);   //for I.CODE1 protocol
       WriteRawRC(RegMfOutSelect,0x04);     // select internal signal applied to pin MFOUT  04 or 05          00  
       WriteRawRC(RFU27,0x00);                

       WriteRawRC(RegFIFOLevel,0x3F);     //0x3F=63D,FIFO共64字节
       WriteRawRC(RegTimerClock,0x07);      
       WriteRawRC(RegTimerControl,0x06);   
           WriteRawRC(RegTimerReload,0x0A);   
       WriteRawRC(RegIRqPinConfig,0x02);        
       WriteRawRC(RFU2E,0x00);
       WriteRawRC(RFU2F,0x00);       

       PcdSetTmo(106);
       DelayMs(1);
       PcdAntennaOn();

   }

   else{ return -1; }
   return MI_OK;
}

/////////////////////////////////////////////////////////////////////
//功    能:寻卡
//参数说明: req_code[IN]:寻卡方式
//                0x52 = 寻感应区内所有符合14443A标准的卡
//                0x26 = 寻未进入休眠状态的卡
//         pTagType[OUT]:卡片类型代码
//                0x4400 = Mifare_UltraLight
//                0x0400 = Mifare_One(S50)
//                0x0200 = Mifare_One(S70)
//                0x0800 = Mifare_Pro
//                0x0403 = Mifare_ProX
//                0x4403 = Mifare_DESFire
//返    回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdRequest(unsigned char req_code,unsigned char *pTagType)
{
   char  idata status;   
   struct TranSciveBuffer MfComData;
   struct TranSciveBuffer *pi;
   pi = &MfComData;

   WriteRawRC(RegChannelRedundancy,0x02);   //无CRC_16,无奇校验。                                   03
   ClearBitMask(RegControl,0x08);        //disable crypto 1 unit 加密单元关闭
   WriteRawRC(RegBitFraming,0x07);    //(接收的数据在FIFO中从bit0开始存放,发送的最后一个字节有7bits。07)
   SetBitMask(RegTxControl,0x03);     //pin TX1,TX2发送调制的13.56MHz的载波。                  
   PcdSetTmo(4);
   MfComData.MfCommand = PCD_TRANSCEIVE;
   MfComData.MfLength  = 1;
   MfComData.MfData[0] = req_code;

   status = PcdComTransceive(pi);

  if((status == MI_OK) && (MfComData.MfLength == 0x10))
    {
      *pTagType     = MfComData.MfData[0];
      *(pTagType+1) = MfComData.MfData[1];
    }
  else
    { status = MI_BITCOUNTERR; }
   
  return status;
}

/////////////////////////////////////////////////////////////////////
//通过RC632和ISO14443卡通讯
//input: pi->MfCommand = RC632命令字
//       pi->MfLength  = 发送的数据长度
//       pi->MfData[]  = 发送数据
//output:status        = 错误字
//       pi->MfLength  = 接收的数据BIT长度
//       pi->MfData[]  = 接收数据
/////////////////////////////////////////////////////////////////////
char PcdComTransceive(struct TranSciveBuffer *pi)
{
   bit recebyte = 0;
   char status;
   unsigned char irqEn   = 0x00;
   unsigned char waitFor = 0x00;
   unsigned char lastBits;
   unsigned char n;
   unsigned int i;
   switch (pi->MfCommand)
   {
      case PCD_IDLE:
         irqEn   = 0x00;
         waitFor = 0x00;
         break;
      case PCD_WRITEE2:
         irqEn   = 0x11;
         waitFor = 0x10;
         break;
      case PCD_READE2:
         irqEn   = 0x07;
         waitFor = 0x04;
         recebyte=1;
         break;
      case PCD_LOADCONFIG:
      case PCD_LOADKEYE2:
      case PCD_AUTHENT1:
         irqEn   = 0x05;
         waitFor = 0x04;
         break;
      case PCD_CALCCRC:
         irqEn   = 0x11;
         waitFor = 0x10;
         break;
      case PCD_AUTHENT2:
         irqEn   = 0x04;
         waitFor = 0x04;
         break;
      case PCD_RECEIVE:
         irqEn   = 0x06;
         waitFor = 0x04;
         recebyte=1;
         break;
      case PCD_LOADKEY:
         irqEn   = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSMIT:
         irqEn   = 0x05;
         waitFor = 0x04;
         break;
      case PCD_TRANSCEIVE:
         irqEn   = 0x3D;
         waitFor = 0x04;
         recebyte=1;
         break;
      default:
         pi->MfCommand = MI_UNKNOWN_COMMAND;
         break;
   }
   
   if (pi->MfCommand != MI_UNKNOWN_COMMAND)
   {
      WriteRawRC(RegPage,0x00);
      WriteRawRC(RegInterruptEn,0x7F);     //3F  使能所有中断
      WriteRawRC(RegInterruptRq,0x7F);     //3F
      WriteRawRC(RegCommand,PCD_IDLE);       //取消当前命令
      SetBitMask(RegControl,0x01);         // clear the internal FIFO-buffer's read- and write-pointer abd the flag FIFOOvfl (FIFO length become 0)
      WriteRawRC(RegInterruptEn,irqEn|0x80);//使能发送与接收中断请求
      for (i=0; i<pi->MfLength; i++)
      {
         WriteRawRC(RegFIFOData, pi->MfData); //写数据到FIFO
      }
      WriteRawRC(RegCommand, pi->MfCommand);   //执行命令
      i = 0X3500;   
      do
      {
         n = ReadRawRC(RegInterruptRq);
         i--;
      }
      while ((i!=0) && !(n&irqEn&0x20) && !(n&waitFor));    ////等待数据发送完    n&waitFor表示命令自动结束
      status = MI_COM_ERR;
      if ((i!=0) && !(n&irqEn&0x20))  //FIFO数据超限或i=0  
      {
         if (!(ReadRawRC(RegErrorFlag)&0x17)) //don't write to FIFO buffer if FIFO is full ,SOF is ok,the parity check is ok,a bit-collision is not detected.
         {
            status = MI_OK;
            if (recebyte)
            {
                      n = ReadRawRC(RegFIFOLength);  //读返回数据的长度
                      lastBits = ReadRawRC(RegSecondaryStatus) & 0x07;   //得出接受字节中的有效位,如果为0,全部位都有效
                if (lastBits)
                {
                   pi->MfLength = (n-1)*8 + lastBits;
                }
                else
                {
                   pi->MfLength = n*8;
                }
                if (n == 0)
                {
                   n = 1;
                }
                for (i=0; i<n; i++)
                {
                    pi->MfData = ReadRawRC(RegFIFOData);
                }
            }
         }
                 else if (ReadRawRC(RegErrorFlag)&0x01)     //a bit-collision is detected.
         {
                    status = MI_COLLERR;
            if (recebyte)
            {
                      n = ReadRawRC(RegFIFOLength);
                      lastBits = ReadRawRC(RegSecondaryStatus) & 0x07;
                if (lastBits)
                {
                   pi->MfLength = (n-1)*8 + lastBits;
                }
                else
                {
                   pi->MfLength = n*8;
                }
                if (n == 0)
                {
                   n = 1;
                }
                for (i=0; i<n; i++)
                {
                    pi->MfData[i+1] = ReadRawRC(RegFIFOData);
                }
            }
                        pi->MfData[0]=ReadRawRC(0x0B);    //0B is CollPos Register                  
         }  

      }
      else if (n & irqEn & 0x20)    //FIFO数据未超限      
      {   status = MI_NOTAGERR;   }
      else if (!(ReadRawRC(RegErrorFlag)&0x17))
      {   status = MI_ACCESSTIMEOUT;   }
      else
      {   status = MI_COM_ERR;    }
      
      WriteRawRC(RegInterruptEn,0x7F);
     // DelayMs(10);
      WriteRawRC(RegInterruptRq,0x7F);
      SetBitMask(RegControl,0x04);           // stop timer now
      WriteRawRC(RegCommand,PCD_IDLE);
   }
   return status;
}

出0入0汤圆

 楼主| 发表于 2012-5-14 22:34:07 | 显示全部楼层
黑暗深处 发表于 2012-5-11 12:51
你RC632的A0 A1 A2配置成什么?

你好,请问,如果我上电复位后,是不是寄存器值就和RC632datasheet上面的一样了?

出0入0汤圆

发表于 2013-4-2 14:43:58 | 显示全部楼层
mark---------------------------------------

出0入0汤圆

发表于 2013-4-2 15:05:13 | 显示全部楼层
mark 有时间慢慢看

出0入0汤圆

发表于 2013-5-15 11:44:26 | 显示全部楼层
黑暗深处 发表于 2012-5-11 20:53
第一个问题,请自己看RC632或者RC500的datasheet 第9.2.1章
http://www.cn.nxp.com/documents/data_sheet/M ...

你好,我想请问一下,我用RC632读身份证UID,每次读出的UID号都不一样,个别次能读对,我用的PIC16F1934单片机,和RC632是并口通信,采用查询方式
希望能得到你的解答,不胜感激.
用STC12C5A32S2单片机都可以读对

出0入0汤圆

发表于 2013-5-17 22:14:01 | 显示全部楼层

出0入0汤圆

发表于 2022-3-23 22:23:22 | 显示全部楼层
感谢分享
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 09:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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