本读写器支持ISO14443 TYPE A标准的Mifare One系列卡。Mifare One卡的内部存储结构分为16个扇区,从第0区到第15区,每个扇区有独立的密码和权限控制字,可作为独立的电子钱包,每个扇区有4个块,序号为第0块、第1块、第2块、第3块,每块16个字节,第3块是卡的密码和权限控制字专用块,禁止在此存放数据。第0块、第1块、第2块可随意存放数据。但第0区的第0块已被固化了IC卡出厂信息,此块只能读出信息,不可更改。

每张卡都有一个全球统一的4个字节的序列号。许多公司销售的读卡模块只有读取卡序列号的功能,也能用于一般的考勤系统。但这类读卡模块跟本公司的读写器有着本质的不同,本公司的读写器不仅能读序列号,而且还有服务于IC卡所有用途的功能。

波特率参数为:19200,N,8,1

发送帧格式


帧长度(1字节)



帧内容(不超过62个字节)



帧内容的和校验(1字节)


接收帧格式


帧长度(1字节)



帧内容(不超过62个字节)



帧内容的和校验(1字节)


注:帧长度仅指帧内容的字节数

功能:驱动蜂鸣器响   


帧长度(1B)

帧数据

帧检验(1B)

发送数据

03

0F FF 00


F0



功能:读取IC卡序列号   


帧长度(1B)

帧数据

帧检验(1B)

发送数据

01

F0

F0

寻不到卡返回

01

08

08

寻到卡返回

05

4字节卡号

1字节检验

感应区有两张卡

01

09

09

无法选择卡片

01

0A

0A






功能:集成读卡,一次性读整个区的第0块、第1块、第2块共3块的信息,并且返回卡序列号   


帧长度(1B)

帧数据

帧检验(1B)

发送数据

0E

78 17 00 00 00 00 08 AA FF FF FF FF FF FF 

CD

寻不到卡返回

01

08

08

寻到卡返回

35

4字节卡号+48字节扇区内数据

1字节检验

感应区有两张以上的卡

01

09

09

无法选择卡片

01

0A

0A

密码装载失败


0B+4字节卡号


密码认证失败


0C+4字节卡号



功能:集成写卡,可以一次性写整个区的第0块、第1块、第2块信息   


帧长度(1B)

帧数据

帧检验(1B)

发送数据

3E

69 17 00 00 00 00 08 AA FF FF FF FF FF FF [48字节的写卡数据]

CD

寻不到卡返回

01

08

08

感应区有两张以上的卡

01

09

09

无法选择卡片

01

0A

0A

密码装载失败


0B+4字节卡号


密码认证失败


0C+4字节卡号



RS232串口IC卡读写器控制协议_单片机

Delphi7串口控件源码:

打开串口------------------------------------------------------------------------------------------------------------------------------------------------------

procedure TForm1.BitBtn1Click(Sender: TObject);

begin

  if(BitBtn1.Caption = '打开串口') then

  begin

    try

        Comm1.CommName:='\\.\'+ComboBox1.Text;

        //以下代码一定要复制过去

        Comm1.BaudRate:=strtoint(ComboBox2.text);        //19200;

        Comm1.ByteSize:=_8;

        Comm1.ParityCheck:=False;

        case combobox3.ItemIndex of

             0: Comm1.Parity:=None;

             1: Comm1.Parity:=Odd;

             2: Comm1.Parity:=Even;

             3: Comm1.Parity:=Mark;

        else

                Comm1.Parity:=Space;

        end;

        Comm1.StopBits:=_1;

        Comm1.XoffChar:='#';

        comm1.ReadIntervalTimeout:= StrToInt(RichEdit13.Lines[0]);

        Comm1.StartComm; //打开串口

        BitBtn1.Caption := '关闭串口';

        ComboBox1.Enabled:=False;

    except

        ShowMessage('打开端口失败!');

    end;

  end

  else

  begin

    try

        timer2.Enabled :=false;

        Comm1.StopComm; //关闭串口

        BitBtn1.Caption := '打开串口';

        ComboBox1.Enabled:=True;

    except

    end;

  end;

end;

串口发送指令读卡号-------------------------------------------------------------------------------------------------------------------------

procedure TForm1.BitBtn2Click(Sender: TObject);

var

   sendd:array[0..2]of Byte;   //发送字节缓冲

   SendDataStr:string;

   i:integer;

begin

    if(BitBtn1.Caption <> '关闭串口') then

    begin

       Application.MessageBox('请先打开串口再进行修改在线设备站号的操作!', '警告', MB_OK+MB_ICONSTOP);

       Exit;

    end;

    sendd[0] := $01;

    sendd[1] := $F0;

    sendd[2] := $F0;

    FuncCode:=1;   //驱动读卡序列号

    issendwaitrev1 := True;

    sendwaitrevsize := 0;

    Comm1.WriteCommData(@sendd[0], 3);

    SendDataStr:='串口发送数据:';

    for i:=0 to 2 do

    begin

         SendDataStr:=SendDataStr+inttohex(sendd[i],2)+' ';

    end;

    ListBox1.Items.Add(SendDataStr);

    listbox1.ItemIndex:=listbox1.Count-1;

end;

串口接收指令后并返回信息------------------------------------------------------------------------------------------------------------

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;

  BufferLength: Word);

var

i,para:integer;

answ:integer;

GetdataStr:string;

SendDataStr:string;

cardhao:Longword;

strls1:string;

CRC:byte;

sendd:array[0..7]of Byte;   //发送字节缓冲

begin

  GetdataStr:='串口接收数据:';

  if issendwaitrev1 then

  begin//在有发送指令等待返回

    issendwaitrev1 := False;

    sendwaitrevsize := BufferLength;

    move(Buffer^,pchar(@(sendwaitData[0]))^,BufferLength);

    for i:=0 to  BufferLength-1  do

    begin

        GetdataStr:=GetdataStr+inttohex(sendwaitData[i],2)+' ';

        if i=32 then

        begin

              ListBox1.Items.Add(GetdataStr);

              listbox1.ItemIndex:=listbox1.Count-1;

              GetdataStr:='             ' ;

        end;

    end;

    if  length(trim(GetdataStr))>0 then

    begin

        ListBox1.Items.Add(GetdataStr);

        listbox1.ItemIndex:=listbox1.Count-1;

    end;

    crc:=0;

    for i:=1 to BufferLength-1 do

    begin

       crc:=crc xor sendwaitData[i];

    end;

    if crc=0 then

    begin

    case FuncCode of

         1,2,3,4:

         begin

             if (sendwaitData[0]=1)  then

             begin

                  case sendwaitData[1] of

                        1:

                        edit3.Text :='密码认证成功,卡片序列号已知,但读取扇区内容失败!';

                        2:

                        edit3.Text :='第0块读出,但第1、2块没读出,仅扇区内容前16个字节的数据有效!';

                        3:

                        edit3.Text :='第0、1块读出,但第2块没读出,仅扇区内容前32个字节的数据有效!';

                        8:

                        edit3.Text :='未寻到卡!';

                        9:

                        edit3.Text :='两张以上卡片同时在感应区,发生冲突!';

                        10:

                        edit3.Text :='无法选择激活卡片!';

                        11:

                        edit3.Text :='密码装载失败,卡片序列号已知!';

                        12:

                        edit3.Text :='密码认证失败,卡片序列号已知!';

                  end;

             end

             else

             begin

                 if (sendwaitData[0]=5) then

                 begin

                     cardhao := sendwaitData[5] + sendwaitData[4]*256 + sendwaitData[3]*256*256 + sendwaitData[2]*256*256*256;

                     case sendwaitData[1] of

                        0:

                        begin

                              if FuncCode=2 then  strls1:='读卡成功 ' else if  FuncCode=3 then  strls1:='写卡成功 ' else if  FuncCode=4 then strls1:='更改密码成功 ' ;

                        end;

                        1:

                        strls1:='密码认证成功,卡片序列号已知,但读取扇区内容失败!';

                        2:

                        strls1:='第0块读出,但第1、2块没读出,仅扇区内容前16个字节的数据有效!';

                        3:

                        strls1:='第0、1块读出,但第2块没读出,仅扇区内容前32个字节的数据有效!';

                        8:

                        strls1:='未寻到卡!';

                        9:

                        strls1:='两张以上卡片同时在感应区,发生冲突!';

                        10:

                        strls1:='无法选择激活卡片!';

                        11:

                        strls1:='密码装载失败,卡片序列号已知!';

                        12:

                        strls1:='密码认证失败,卡片序列号已知!';

                     end;

                     strls1:=strls1+'物理卡号:'+inttohex(sendwaitData[2],2)+'-'+inttohex(sendwaitData[3],2)+'-'+inttohex(sendwaitData[4],2)+'-'+inttohex(sendwaitData[5],2);

                     strls1:=strls1+' 换算成十位卡号:'+ RightStr('000000000' + IntToStr(cardhao),10);

                     edit3.Text :=strls1;

                 end

                 else

                 begin

                     if (sendwaitData[0]=53) then

                     begin

                         cardhao := sendwaitData[5] + sendwaitData[4]*256 + sendwaitData[3]*256*256 + sendwaitData[2]*256*256*256;

                         strls1:='物理卡号:'+inttohex(sendwaitData[2],2)+'-'+inttohex(sendwaitData[3],2)+'-'+inttohex(sendwaitData[4],2)+'-'+inttohex(sendwaitData[5],2);

                         strls1:=strls1+' 换算成十位卡号:'+ RightStr('000000000' + IntToStr(cardhao),10);

                         edit3.Text :=strls1;

                         GetdataStr:='';

                         for i:=6 to BufferLength-2 do

                         begin

                             GetdataStr:=GetdataStr+inttohex(sendwaitData[i],2)+' ';

                         end;

                         RichEdit3.Text :=GetdataStr;

                     end;

                 end;

             end;

         end;

     end;

   end;

   end;

end;