RS232串口IC卡讀寫器控制協議

        本讀寫器支持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字節卡號  

 

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;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章