LBQ691477940 发表于 2015-9-23 12:46:52

RC522基站能否写UID卡0扇区0块

请问各位高手RC522做的M1卡读写器能否写UID卡的0扇区0块数据呢?
我自己用RC522做官方的SPI程序做了一个读写器除了0扇区0块不能写之外,其余扇区和块都能正常读写这是为何?难道对0扇区0块有特殊的指令写吗?还是我买到的是假的UID卡只是普通的M1白卡呢?!(卖家却咬定说给我的是UID卡且0扇区0块是能写的,说什么普通的读写器写不了,对这话真心不懂)难道对0扇区0块有特殊指令吗?
有经验的高手请赐教,谢谢!

KongQuan 发表于 2015-9-23 14:59:36

做东西,怎么也得看数据手册吧。
一般的m1卡, 都是不能写0块的。

LBQ691477940 发表于 2015-9-23 15:13:44

我买的不是一般的M1卡呀是UID卡说0扇区0块能写的哟

runapp 发表于 2015-10-21 11:16:14

可以,参见
http://vd5678.pixnet.net/blog/post/54729406-%E5%AF%AB-mifare-one-s50-uid%E5%8D%A1%E7%9A%84%E7%89%B9%E6%AE%8A%E5%91%BD%E4%BB%A4

sml009 发表于 2015-11-14 13:37:00

跟着学习

LBQ691477940 发表于 2015-11-14 14:18:31

本帖最后由 LBQ691477940 于 2015-11-14 14:44 编辑

runapp 发表于 2015-10-21 11:16
可以,参见
http://vd5678.pixnet.net/blog/post/54729406-%E5%AF%AB-mifare-one-s50-uid%E5%8D%A1%E7%9A%8 ...

以下是网上的方法,不过我未试过其可行性{:titter:}
可是不管我怎麼試, UID卡的行為就跟標準卡沒兩樣,甚至一度以為買到假貨。
於是又在網路上繼續搜索,我覺得,一定有特別的命令讓我可以寫 sector:block
終於讓我找到一篇,他的流程是這樣:
Sent bits: 26 (7 bits) //尋卡 0x26 / 0x52 都可以
Received bits: 04 00
Sent bits: 93 20 //防衝撞
Received bits: 01 23 45 67 00
Sent bits: 93 70 01 23 45 67 00 d0 6f //選卡
Received bits: 08 b6 dd (SAK)

(不可以認證密鑰,不然後門打不開)
好,重點來了,
Sent bits: 50 00 57 cd //休眠,50 00 就是 PcdHalt()
Sent bits: 40 (7 bits) (特殊指令)//開後門第一條指令,要設定 BitFramingReg 使傳送 7 個位元,必須要 7 個
eceived bits: a (4 bits)
Sent bits: 43 (特殊指令)//開後門第二條指令
Received bits: 0a
Sent bits: a0 00 5f b1 //正常的寫區塊第一次交握
Received bits: 0a
Sent bits: 00 dc 44 20 b8 08 04 00 46 59 25 58 49 10 23 02 c0 10 //正常的寫 block 0 資料
Received bits: 0a
重點就是要:
1. 不可以進行 3 Pass Authenticaiton
2. 發 PcdHalt()
3. 發 0x40 in 7-bit
4. 發 0x43
到這邊,我把考勤卡的 sector:block 整個區塊複製過來了,
著,我又把其餘的 63 個區塊也都一併複製,然後滿心期待的拿去刷考勤機看看,
結果....
考勤機根本沒回應...

34480016 发表于 2015-11-15 15:28:05

用pn532加libnfc可以写

whimsyB 发表于 2015-11-28 15:52:08

你这种卡本身就是非标的,确实有特殊指令才可以改写!!!

zeng_19870714 发表于 2015-12-2 17:06:28

你好,不知道你使用RC522修改卡号成功没有,我这里也是遇到这个问题,请指教

petermxw 发表于 2015-12-23 19:27:02

好用不 试试

runapp 发表于 2015-12-25 22:33:16

那个帖子里的确实能用,我买了几批uid卡了,都没问题。注意bitframereg一定要写7进去,否则传输0x40的时候会收不到0xa

petermxw 发表于 2015-12-30 19:07:37

已经成功 确实好用 Sent bits: 40 (7 bits) (特殊指令)这个7bit发送 4bit接收 就可以了 别的按上面流程来就ok

zeng_19870714 发表于 2016-1-4 15:38:28

petermxw 发表于 2015-12-30 19:07
已经成功 确实好用 Sent bits: 40 (7 bits) (特殊指令)这个7bit发送 4bit接收 就可以了 别的按上面流程来 ...

为什么我试了半天始终不行,求教

zeng_19870714 发表于 2016-1-4 15:55:10

runapp 发表于 2015-12-25 22:33
那个帖子里的确实能用,我买了几批uid卡了,都没问题。注意bitframereg一定要写7进去,否则传输0x40的时候 ...

你是用的什么刷卡芯片,我用的FM1701为什么不行呢,还是我程序没写对

runapp 发表于 2016-1-4 16:36:16

zeng_19870714 发表于 2016-1-4 15:55
你是用的什么刷卡芯片,我用的FM1701为什么不行呢,还是我程序没写对

你说基站吗?原厂rc522啊

zeng_19870714 发表于 2016-1-4 16:39:15

runapp 发表于 2016-1-4 16:36
你说基站吗?原厂rc522啊

能不能留个联系方式,请教下你

petermxw 发表于 2016-1-5 14:46:34

zeng_19870714 发表于 2016-1-4 15:38
为什么我试了半天始终不行,求教

RC522 淘宝最便宜的模块。 看是否有返回值0a按照顺序一步一步做 根据官方例程 重新改写底部驱动函数 肯定没问题 番墙去国外网站看过 也是这么搞的

zeng_19870714 发表于 2016-1-5 15:58:28

petermxw 发表于 2016-1-5 14:46
RC522 淘宝最便宜的模块。 看是否有返回值0a按照顺序一步一步做 根据官方例程 重新改写底部驱动函数 肯 ...

试了好几天,不知道什么地方有问题,求指教

petermxw 发表于 2016-1-5 16:02:05

zeng_19870714 发表于 2016-1-5 15:58
试了好几天,不知道什么地方有问题,求指教

一步一步试 看返回值0a 每一部都有0a 没有就说明这步错了

zeng_19870714 发表于 2016-1-5 16:37:21

petermxw 发表于 2016-1-5 16:02
一步一步试 看返回值0a 每一部都有0a 没有就说明这步错了

写40,43都有返回值0X0a,为什么写A0,00后就没有0X0A了呢,这个命令和写写别的块的命令不一样么?

petermxw 发表于 2016-1-5 16:43:53

zeng_19870714 发表于 2016-1-5 16:37
写40,43都有返回值0X0a,为什么写A0,00后就没有0X0A了呢,这个命令和写写别的块的命令不一样么?
...

    ucComMF522Buf = 0xa0;
    ucComMF522Buf = 0x00;
    ucComMF522Buf = 0x5f;
    ucComMF522Buf = 0xb1;先发这个 然后再发数据块

zeng_19870714 发表于 2016-1-5 17:01:37

petermxw 发表于 2016-1-5 16:43
ucComMF522Buf = 0xa0;
    ucComMF522Buf = 0x00;
    ucComMF522Buf = 0x5f;


in com522 send:A0 00 5F B1 00
e: MI_NOTAGERR
Receive: 60
返回值不是0A,

petermxw 发表于 2016-1-5 17:39:37

为什么要发 00呢

petermxw 发表于 2016-1-5 17:44:00

zeng_19870714 发表于 2016-1-5 17:01
in com522 send:A0 00 5F B1 00
e: MI_NOTAGERR
Receive: 60


不发00 不检测 直接发送16位数据

zeng_19870714 发表于 2016-1-6 09:33:37

petermxw 发表于 2016-1-5 17:44
不发00 不检测 直接发送16位数据

这个00不是程序发送的,程序写的发送是没有00的,应该是软件监视的时候自带的

petermxw 发表于 2016-1-6 13:04:12

zeng_19870714 发表于 2016-1-6 09:33
这个00不是程序发送的,程序写的发送是没有00的,应该是软件监视的时候自带的 ...

我是随便找个单片机编的程序 按提示发送的数据 主要是 0x43 0x40那里 后面的直接调用的例程函数就ok了

zeng_19870714 发表于 2016-1-6 15:38:45

petermxw 发表于 2016-1-6 13:04
我是随便找个单片机编的程序 按提示发送的数据 主要是 0x43 0x40那里 后面的直接调用的例程函数就ok了
...

不知道是应为芯片不同的原因还是怎么回事,不行,能不能你那边的代码给我看看

petermxw 发表于 2016-1-6 16:15:28

zeng_19870714 发表于 2016-1-6 15:38
不知道是应为芯片不同的原因还是怎么回事,不行,能不能你那边的代码给我看看 ...

我这代码也是按照提示的步骤写的

zeng_19870714 发表于 2016-1-6 16:18:19

petermxw 发表于 2016-1-6 16:15
我这代码也是按照提示的步骤写的

我也是按照步骤弄啊,关键就是通不过,你说气人不气人

petermxw 发表于 2016-1-6 21:46:11

zeng_19870714 发表于 2016-1-6 16:18
我也是按照步骤弄啊,关键就是通不过,你说气人不气人

再仔细看看 还是哪步骤出错了

elet 发表于 2016-1-10 04:23:39

petermxw 发表于 2015-12-30 19:07
已经成功 确实好用 Sent bits: 40 (7 bits) (特殊指令)这个7bit发送 4bit接收 就可以了 别的按上面流程来 ...

请问petermxw兄,上面那个贴子中选卡后面的d0 6f和休眠后面的57 cd是什么东东,不加正常,加了后接收超时错误。
另外发40命令的时候,除了设置 WriteRawIO(RegBitFraming,0x07) 外,还需要做其它设置吗?为什么我这边总是接收超时,我用的是RC500芯片。。

elet 发表于 2016-1-10 21:30:00

zeng_19870714 发表于 2016-1-6 16:18
我也是按照步骤弄啊,关键就是通不过,你说气人不气人

你成功了吗?我测试成功了。
用FM1207SL的标准程序,只需要编写40和43的函数就好了,

用RC500的标标准程序,除了编写40和43的函数外,写块的函数也要改写。标准程序先传入a0 00,要改为传入a0 00 5f b1,另外后面写数据要写18字节,
参考上面贴子里的00 dc 44 20 b8 08 04 00 46 59 25 58 49 10 23 02 c0 10能写成功,但是我把ID号改为其它的就写不成功了,看来还需研究一下。

zeng_19870714 发表于 2016-1-11 10:21:59

elet 发表于 2016-1-10 21:30
你成功了吗?我测试成功了。
用FM1207SL的标准程序,只需要编写40和43的函数就好了,



在不在?我还没有搞定,留个联系方式吧

elet 发表于 2016-1-11 11:23:41

zeng_19870714 发表于 2016-1-11 10:21
在不在?我还没有搞定,留个联系方式吧

RC500源码
char M500PiccW40(void)
{
   char status = MI_OK;
   WriteRawIO(RegBitFraming,0x07);      // set TxLastBits to 7
   WriteRawIO(RegChannelRedundancy,0x03);
   ResetInfo(MInfo);   
   MSndBuffer = 0x40;
   MInfo.nBytesToSend   = 1;   
   status = M500PcdCmd(PCD_TRANSCEIVE,
                      MSndBuffer,
                      MRcvBuffer,
                      &MInfo);

   if (status!=MI_OK)      // error occured
   {
      return status;
   }
   if (MInfo.nBitsReceived != 4||(MRcvBuffer&0x0f)!=0x0a) // 4 bit expected
   {
      status = MI_BITCOUNTERR;
   }
   else
   {
      status = MI_OK;
   }
   return status;
}
char M500PiccW43(void)
{
   char status = MI_OK;
   ResetInfo(MInfo);   
   MSndBuffer = 0x43;
   MInfo.nBytesToSend   = 1;   
   status = M500PcdCmd(PCD_TRANSCEIVE,
                      MSndBuffer,
                      MRcvBuffer,
                      &MInfo);

   if (status!=MI_OK)      // error occured
   {
      return status;
   }
   if (MInfo.nBitsReceived != 4||(MRcvBuffer&0x0f)!=0x0a) // 4 bit expected
   {
      status = MI_BITCOUNTERR;
   }
   else
   {
      status = MI_OK;
   }
   return status;
}
char M500PiccWBlock0(void)
{
//        uint8_t buff[]={0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00, 0x01, 0x72, 0x92, 0x86, 0x61, 0x66, 0xF2, 0x1D};
//        uint8_t buff[]={0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x72, 0x92, 0x86, 0x61, 0x66, 0xF2, 0x1D};
//uint8_t buff[]={0x00, 0x00, 0x00, 0x01, 0x01, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0xc0, 0x10};
    uint8_t buff[]={0x00, 0xdc, 0x44, 0x20, 0xb8, 0x08, 0x04, 0x00, 0x46, 0x59, 0x25, 0x58, 0x49, 0x10, 0x23, 0x02, 0xc0, 0x10};
        return M500PiccWrite(0,buff);
}
char M500PiccWrite( unsigned char addr,
                  unsigned char *_data)
{
   char status = MI_OK;

   // ************* Cmd Sequence **********************************
   ResetInfo(MInfo);   
   MSndBuffer = PICC_WRITE;      // Write command code
   MSndBuffer = addr;
MSndBuffer = 0X5F;
MSndBuffer = 0XB1;
MInfo.nBytesToSend   = 4;
//   MInfo.nBytesToSend   = 2;
   status = M500PcdCmd(PCD_TRANSCEIVE,
                         MSndBuffer,
                         MRcvBuffer,
                         &MInfo);

   if (status != MI_NOTAGERR)   // no timeout error
   {
      if (MInfo.nBitsReceived != 4)   // 4 bits are necessary
      {
         status = MI_BITCOUNTERR;
      }
      else                     // 4 bit received
      {
         MRcvBuffer &= 0x0f; // mask out upper nibble
         if ((MRcvBuffer & 0x0a) == 0)
         {
            status = MI_NOTAUTHERR;                  
         }
         else
         {
            if (MRcvBuffer == 0x0a)
            {
               status = MI_OK;
            }
            else
            {
               status = MI_CODEERR;
            }
         }
      }
   }

   if ( status == MI_OK)
   {

      M500PcdSetTmo(3);   // long timeout
      ResetInfo(MInfo);
memcpy(MSndBuffer,_data,18);
MInfo.nBytesToSend   = 18;                  
//      memcpy(MSndBuffer,_data,16);
//      MInfo.nBytesToSend   = 16;
      status = M500PcdCmd(PCD_TRANSCEIVE,
                            MSndBuffer,
                            MRcvBuffer,
                            &MInfo);
      
      if (status & 0x80)    // timeout occured
      {
         status = MI_NOTAGERR;
      }
      else
      {
         
         if (MInfo.nBitsReceived != 4)// 4 bits are necessary
         {
            status = MI_BITCOUNTERR;
         }
         else                     // 4 bit received
         {
            MRcvBuffer &= 0x0f; // mask out upper nibble
            if ((MRcvBuffer & 0x0a) == 0)
            {
               status = MI_WRITEERR;
            }
            else
            {
               if (MRcvBuffer == 0x0a)
               {
                  status = MI_OK;
               }
               else
               {
                  status = MI_CODEERR;
               }
            }   
         }
      }      
      M500PcdSetTmo(1);    // short timeout
   }
return status;
}

elet 发表于 2016-1-11 11:25:27

zeng_19870714 发表于 2016-1-11 10:21
在不在?我还没有搞定,留个联系方式吧

我搞不懂写0块数据里后面二字节是什么意思,不能写其它序列号,你研究过吗?

elet 发表于 2016-1-11 11:26:55

zeng_19870714 发表于 2016-1-11 10:21
在不在?我还没有搞定,留个联系方式吧

FM1702SL源码
uint8_t M500PiccW40(void)
{
    uint8_t temp;
        RevBuffer = 0x40;                /* Request模式选择 */
        SPIWrite(Bit_Frame,0x07);               
        SPIWrite(ChannelRedundancy,0x03);       
        temp = Command_Send(1, RevBuffer, Transceive);   //Transceive=0x1E        /* 发送接收命令 */
        if(temp == FALSE)
        {
                return FM1702_NOTAGERR;
        }
        Read_FIFO(RevBuffer);                /* 从FIFO中读取应答信息到RevBuffer[]中 */
    if((RevBuffer&0x0f)==0x0a)
        {
                return FM1702_OK;
        }
        return FM1702_REQERR;
}
uint8_t M500PiccW43(void)
{
       
        uint8_t temp;
        RevBuffer = 0x43;                /* Request模式选择 */
        temp = Command_Send(1, RevBuffer, Transceive);   //Transceive=0x1E        /* 发送接收命令 */
        if(temp == FALSE)
        {
                return FM1702_NOTAGERR;
        }

        Read_FIFO(RevBuffer);                /* 从FIFO中读取应答信息到RevBuffer[]中 */
    if((RevBuffer&0x0f)==0x0a)
        {
                return FM1702_OK;
        }
        return FM1702_REQERR;
}
uint8_t MIF_Write(uint8_t *buff, uint8_t Block_Adr);
uint8_t M500PiccWBlock0(void)//这个可以写任意序列号
{
    uint8_t blockbuf[]={0x01, 0x23, 0x45, 0x67, 0x00, 0x08, 0x04, 0x00,
        0x01, 0x72, 0x92, 0x86, 0x61, 0x66, 0xF2, 0x1D};
        uint8_t buff;
        memcpy(buff,blockbuf,16);
        return MIF_Write((uint8_t *)buff, 0);
}

zeng_19870714 发表于 2016-1-11 15:21:29

elet 发表于 2016-1-11 11:25
我搞不懂写0块数据里后面二字节是什么意思,不能写其它序列号,你研究过吗? ...

RC500的我没有研究过,但是我觉得会不会是校验位

petermxw 发表于 2016-1-16 18:12:49

elet 发表于 2016-1-10 04:23
请问petermxw兄,上面那个贴子中选卡后面的d0 6f和休眠后面的57 cd是什么东东,不加正常,加了后接收超时 ...

首先 RC500 没用过……。 我休眠以后没有看接收数据 直接发送的0x40 0x43接收超时可能是普通不可写的ic卡 我试过不可写的ic卡收不到数据。另我发现模块在3.3v供电的时候不可以写0扇区 5v可以……

LBQ691477940 发表于 2016-6-16 20:46:34

靠过了一年才解决这问题{:titter:}

自制的读写器

上位机界面








UID卡0扇区0块写成功

dswkl11 发表于 2017-8-19 16:44:02

elet 发表于 2016-1-11 11:26
FM1702SL源码
uint8_t M500PiccW40(void)
{


                while(1)
                {
                        M500PiccW40();
                        M500PiccW43();


    blockbuf++;

      MIF_Write((uint8_t *)blockbuf, 0);
                               
                        Delay(500);
                }

我在主程序里面加入这个结果 uid卡 寻卡都寻不了。。。这是怎么回事呢?

zede 发表于 2017-8-25 15:23:55

u8 aray={1,2,3,4,5,6,7,8,      \
             9,10,11,12,13,14,15,16};
u8 uShake[]={0xa0,0x00,0x5f,0xb1};
unsigned intunLen;

unsigned char ucComMF522Buf;
u8 b=0x43;
voidCopyProtection(void)
{
    PcdRequest(PICC_REQIDL,&MfCardInfo.paraBuf);// 26
    PcdAnticoll(MfCardInfo.nCsnBuf);//93 20
    PcdSelect(MfCardInfo.nCsnBuf,0x70); //93 70
    PcdHalt();//50 00 57 cd
    PcdRequest(0x40,&MfCardInfo.paraBuf);//40
    //PcdRequest(0x43,&MfCardInfo.paraBuf);//40
    {
   ucComMF522Buf = 0x43; //存入卡片命令字
   PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);   ----此处不能返回0x0a,前面都OK.
    }

    PcdComMF522(PCD_TRANSCEIVE,uShake,4,&MfCardInfo.paraBuf,&unLen);//a0 00 5f b1
    PcdWrite(0x01,aray);
}

zede 发表于 2017-8-25 15:25:31

现在还没有搞清楚什么原因,有木有高手搞定了的。。。还是现在的UID卡操作不一样了,换了指令?

zede 发表于 2017-8-25 17:39:05

搞定了 原来在发送完7位后要重新设置为8位 。
int8_tCopyProtection( void )
{
   int8_t state;
    PcdRequest(PICC_REQIDL,&MfCardInfo.paraBuf);// 26
    PcdAnticoll(MfCardInfo.nCsnBuf);//93 20
    PcdSelect(MfCardInfo.nCsnBuf,0x70); //93 70
    PcdHalt();//50 00 57 cd
    PcdSend_cmd(0x40);
    PcdSend_cmd(0x43);
    PcdHand_cmd();
    state =PcdWrite_UID(tid);//MI_CPY MI_OK
    return state;   
}

chengying 发表于 2017-9-6 09:52:02

学习了               

血刃修罗 发表于 2018-3-21 14:24:00

本帖最后由 血刃修罗 于 2018-3-21 16:21 编辑

zede 发表于 2017-8-25 17:39
**** 作者被禁止或删除 内容自动屏蔽 ****

感谢分享,已经解决了。

chengying 发表于 2019-4-28 09:37:12

elet 发表于 2016-1-10 21:30
你成功了吗?我测试成功了。
用FM1207SL的标准程序,只需要编写40和43的函数就好了,



数据有舍讲究呢,为何是18字节?

lovewind 发表于 2019-6-5 21:53:38

同问为什么是18字节正在研究UID
页: [1]
查看完整版本: RC522基站能否写UID卡0扇区0块