2015-11-08 101 views
0

由於我使用的讀卡器,檢索MIFARE卡的序列號的協議如下:獲取MIFARE卡的序列號不正確

的Mifare防撞,0x0202
功能卡的防衝突
格式            aa bb 05 00 00 00 02 02 00
響應  aa bb 0a 00 52 51 02 02 00 46 ff a6 b8 a4

其中46 ff a6 b8是上述響應中的卡序列號。

我實現在C#這個協議如下:

private SerialPort _serialPort = new SerialPort(); 
private string _receivedData = null; 

public MifareCardReader(string comPort, int baudRate) 
{ 
    _serialPort = new SerialPort(); 
    _serialPort.PortName = comPort; 
    _serialPort.BaudRate = baudRate; 
    _serialPort.DataBits = 8; 
    _serialPort.Parity = Parity.None; 
    _serialPort.StopBits = StopBits.One; 
    _serialPort.Handshake = Handshake.None; 
    _serialPort.Open(); 

    // Add event 
    _serialPort.DataReceived += SerialPort_DataReceived;  
} 

public string MifareAnticollision() 
{ 
    if (_serialPort != null && _serialPort.IsOpen) 
    { 
     string message = "AABB050000000202000D"; 
     byte[] data = StringToByteArray(message); 
     _serialPort.Write(data, 0, data.Length); 
    } 
} 

private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    _receivedData += _serialPort.ReadExisting(); 
    byte[] data = Encoding.ASCII.GetBytes(receivedData); 
    if (data.Length >= 9) 
    { 
     if (data[8] == 0) // OK 
     { 
      // Response data is complete 
      if (data.Length == 14) 
      { 
       StringBuilder hex = new StringBuilder(8); 
       hex.AppendFormat("{0:X2}", data[9]); 
       hex.AppendFormat("{0:X2}", data[10]); 
       hex.AppendFormat("{0:X2}", data[11]); 
       hex.AppendFormat("{0:X2}", data[12]); 

       string cardID = hex.ToString(); 
       _receivedData = string.Empty; 
      } 
     } 
     else // fail 
     { 
      _receivedData = string.Empty; 
     } 
    } 
} 

我用3個不同MIFARE卡測試這一點,但是,輸出是不符合期望:

  • 卡1:接收到: 3F463F3F,預計:974682D6
  • 卡2:收到:3F450B3F,預計:EA450B91
  • Card 3:received:070D3F3F,expected:070DEBD6

需要更改哪些內容才能獲得正確的輸出?

+1

但你有什麼問題嗎? –

+0

我沒有完全按照協議,但沒有得到正確的卡片序列號。我不知道爲什麼。我的算法錯誤或協議丟失? –

+0

確定,所以你有不良的輸出,給我你的輸入十六進制值和ü想,我會解決它的ü:) Card3輸出的3個例子:070D3F3F是壞的輸出?或者它是輸入? –

回答

1

您遇到的問題似乎是將0x7F以上的字節替換爲0x3F(問號(「?」)字符)。即只有7位值顯示正確,第8位設置的值變爲「?」 (0x3F)。例如。對於卡1,由於0x97,0x820xD6設置了其第8位,所以974682D6被「接收」爲3F463F3F

此問題的根源在於您正在使用ReadExisting()方法從串口讀取字符串值。默認情況下,ReadExisting()從串口讀取字節,使用ASCII編碼(System.Text.ASCIIEncoding)翻譯它們,並返回結果字符串。然後您將該字符串轉換回字節數組(再次使用ASCII編碼)。

有問題的步驟是使用System.Text.ASCIIEncoding/的轉換。所述documentation說:

由於ASCII是一個7位編碼,ASCII字符限制爲最低的128個 Unicode字符,從U + 0000到U + 007F。 在該範圍之外的字符是在執行編碼操作之前用問號(?)代替。

因此,您應該使用Read()ReadByte()方法將字節直接讀入字節數組中。例如。與

byte[] buffer = new byte[_serialPort.ReadBufferSize]; 
int bytesRead = _serialPort.Read(buffer, 0, buffer.Length);