Inhaltsverzeichnis:

RC522 und PN532 RFID-Grundlagen - Gunook
RC522 und PN532 RFID-Grundlagen - Gunook

Video: RC522 und PN532 RFID-Grundlagen - Gunook

Video: RC522 und PN532 RFID-Grundlagen - Gunook
Video: Знакомство с RFID и подключение модуля RC522 к Arduino 2024, Juli
Anonim
RC522 und PN532 RFID-Grundlagen
RC522 und PN532 RFID-Grundlagen

HINWEIS: Ich habe jetzt Instructables, die Arduino-Code für RC522 und PN532 anbieten.

Vor einiger Zeit habe ich mir zum Experimentieren drei verschiedene RFID-Module gekauft. In einem früheren Projekt habe ich beschrieben, wie ein einfaches 125-kHz-Modul verwendet wird, um eine grundlegende Sicherheitsfunktion auszuführen. Module wie diese verwenden schreibgeschützte Tags, sodass der Prozess nach der ID gescannt, bei Bedarf gespeichert und mit gespeicherten IDs verglichen wird. Die anderen Module, die ich gekauft habe, arbeiten mit 13,56 MHz und verwenden Tags, die sowohl gelesen als auch geschrieben werden können, daher ist es eine Verschwendung, sie einfach für die grundlegende Sicherheit zu verwenden. Die beiden gängigen Module verwenden entweder den RC522-Chip oder den PN532-Chip – beide von NXP.

Wenn Sie eines meiner anderen Projekte gelesen haben, wissen Sie, dass ich gerne billige PIC-Mikrocontroller verwende und in Assembler programmiere. Was ich also suchte, war eine Abfolge von Schritten, die erforderlich sind, um mit den Modulen und den RFID-Tags zu sprechen. Während es für die Module viele Beispielprogramme online gibt, sind die meisten von ihnen in 'C'-Software für den Arduino geschrieben und verwenden die SPI-Schnittstelle. Auch die Handbücher für die Chips und für die Mifare-Tags sind etwas entzifferbar. In diesem Beitrag geht es in erster Linie um die Informationen, die ich mir wünschte, als ich das Projekt gestartet habe. Ich schließe auch PIC-Assembly-Softwareprogramme ein, um die grundlegenden Befehle auszuführen, die von jedem Modul benötigt werden. Auch wenn Sie keine PIC- und/oder Assemblersprache verwenden, sollte Ihnen der Quellcode zumindest eine gute Vorstellung von den spezifischen Befehlen vermitteln, die für die einzelnen Schritte erforderlich sind.

Schritt 1: Serielle Schnittstellen

Serielle Schnittstellen
Serielle Schnittstellen
Serielle Schnittstellen
Serielle Schnittstellen
Serielle Schnittstellen
Serielle Schnittstellen
Serielle Schnittstellen
Serielle Schnittstellen

Beide Chips, die auf diesen Modulen verwendet werden, können über SPI, I2C oder UART (HSSP) verbunden werden. Das PN532-Modul verfügt über einen DIP-Schalter, mit dem die gewünschte Schnittstelle ausgewählt wird, das MFRC522-Modul ist jedoch für die SPI-Schnittstelle fest verdrahtet. Ich bevorzuge es, den eingebauten UART des PIC zu verwenden, also habe ich online gesucht, um zu sehen, ob es eine Möglichkeit gibt, das MFRC522-Modul in den UART-Modus zu versetzen. Was ich herausfand, war, dass das Schneiden einer Spur auf dem Brett den Zweck erfüllen würde. Der Schnitt entfernt effektiv 3,3 Volt vom EA-Pin des Chips. Technisch sollte der EA-Pin dann mit Masse verbunden werden, aber angesichts der Chip-Pin-Dichte können nicht viele Leute diese Lötleistung hinbekommen. Aber keine Sorge, denn der EA-Pin hat keinen internen Pull-Up und "schwebt" nicht wie die alten TTL-Logikeingänge. Beziehen Sie sich auf das Chip-Diagramm und das Platinenabschnittsbild für die zu schneidende Stelle. Stellen Sie sicher, dass Sie nur die kurze Spur schneiden, die direkt zum EA-Pin führt.

Schritt 2: Hardware

Hardware
Hardware

Die Hardwareverbindungen für die UART-Kommunikation sind im obigen Diagramm dargestellt. Die UART-Anschlüsse für den MFRC522 sind auf der Platine nicht markiert, aber wie im Schaltplan gezeigt, empfängt der SDA-Pin UART-Daten und der MISO-Pin überträgt UART-Daten. Das PN532-Modul hat die UART-Markierungen auf der Unterseite der Platine.

Beide Module laufen mit 3,3 Volt und der 5-Volt-Logikpegel vom PIC-TX-Pin muss ebenfalls begrenzt werden. Die LCD-Verbindung ist das Standard-4-Bit-Setup, das in einer Reihe meiner früheren Projekte verwendet wurde. Das Standardformat für alle Meldungen ist für das Standard-LCD 1602 (16 Zeichen mal 2 Zeilen) eingestellt. Ich habe auch ein 40 Zeichen mal 2 Zeilen LCD, das ich für Rohdaten-Dumps während des Debuggens verwende, also habe ich eine Definition in die Software integriert, die es mir ermöglicht, den zusätzlichen Anzeigeraum zu nutzen.

Schritt 3: Datenblöcke

Die für dieses Projekt verwendeten Mifare Classic 1k Tags sind als 16 Sektoren, vier Datenblöcke pro Sektor, 16 Byte pro Datenblock konfiguriert. Von den 64 Datenblöcken sind nur 47 tatsächlich nutzbar. Der Datenblock 0 enthält Herstellerdaten und die Blöcke 3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59 und 63 werden Trailer-Blöcke genannt. Die Trailer-Blöcke sind die letzten in jedem Sektor und enthalten zwei Schlüssel und die Blockzugriffsbits. Die Schlüssel und Blockzugriffsbits gelten nur für die Datenblöcke in diesem Sektor, sodass Sie für jeden Sektor unterschiedliche Schlüssel und Zugriffsregeln haben könnten. Die Standardtasten sind auf „FF FF FF FF FFh“eingestellt. Für dieses Basisprojekt verwende ich nur einen Datenblock und behalte die Standardschlüssel und Zugriffsbits bei. Es gibt viele Dokumente zu diesen Karten. Suchen Sie einfach online nach „Mifare“oder besuchen Sie die NXP-Website, wenn Sie sie genauer erkunden möchten.

Schritt 4: Allgemeiner Betrieb

Obwohl beide Module in der Art und Weise, wie auf sie zugegriffen wird und auf die Tags zugreifen, einzigartig sind, gibt es einen allgemeinen Prozess, der erforderlich ist, um die Aufgabe zu erledigen. Für dieses Projekt gehen wir davon aus, dass die Tags vom Typ Mifare Classic 1k sind und wir jeweils nur ein Tag im Antennenfeld zulassen. Die grundlegenden Schritte sind unten definiert.

· Initialisieren des Moduls: Im Allgemeinen erfordert dies Dinge wie das Schreiben von Werten in Register im Chip, das Senden von „Wakeup“-Befehlen und das Einschalten der Antenne. In einer batteriebetriebenen Anwendung möchten Sie die Antenne ein- und ausschalten können, um den Akku zu schonen, aber für diese einfache Anwendung schalten wir sie einmal ein und lassen sie dann eingeschaltet.

· Krypto-Flag löschen (nur 522): Wenn ein Tag authentifiziert wird, wird ein Flag gesetzt, um den Benutzer darüber zu informieren, dass die Kommunikation mit dem Tag verschlüsselt wird. Dieses Flag muss vom Benutzer vor dem nächsten Scan gelöscht werden, auch wenn das gescannte Tag dasselbe ist.

· Nach einem Tag scannen: Das Modul fragt im Grunde "Ist jemand da draußen?" und das Tag antwortet "Ich bin hier". Wenn das Modul keine schnelle Antwort erhält, hört es auf zu hören. Das bedeutet, dass wir wiederholt Scanbefehle an das Modul senden müssen, bis es ein Tag findet.

· Rufen Sie die Benutzer-Identifikationsnummer (UID) des Tags ab: Das Tag antwortet auf die Scan-Anfrage mit einigen eingeschränkten Informationen, wie z. B. dem Typ des Tags. Das bedeutet, dass wir möglicherweise einen weiteren Befehl senden müssen, um seine UID zu erhalten. Die UID beträgt vier Byte für die Mifare Classic 1k-Tags. Es kann für andere Tags länger sein, aber dieses Projekt behandelt sie nicht.

· Tag auswählen (nur 522): Die UID wird verwendet, um das Tag auszuwählen, das der Benutzer für Lese- und Schreibvorgänge authentifizieren möchte. Dies basiert auf der Möglichkeit, dass sich im Antennenfeld mehr als ein Tag befinden kann. Dies ist bei unserer einfachen Anwendung nicht der Fall, aber wir müssen das Tag trotzdem auswählen.

· Tag authentifizieren: Dieser Schritt ist erforderlich, wenn wir das Tag lesen oder schreiben möchten. Wenn wir nur zwischen Tags für eine einfache Sicherheitsanwendung unterscheiden wollen, reicht die UID aus. Die Authentifizierung erfordert, dass wir die UID und den Kryptoschlüssel für den Datensektor des Tags kennen, auf den wir zugreifen möchten. Für dieses Projekt bleiben wir bei den Standardschlüsseln, aber mein Folgeprojekt ändert die Schlüssel, damit das Tag als elektronische Geldbörse verwendet werden kann.

· Tag lesen oder schreiben: Reads geben immer alle 16 Bytes des angeforderten Datenblocks zurück. Schreibvorgänge erfordern, dass alle 16 Bytes gleichzeitig geschrieben werden. Wenn Sie einen weiteren Block im gleichen Datensektor lesen oder schreiben möchten, muss der Tag nicht erneut authentifiziert werden. Wenn Sie einen Block in einem anderen Datensektor lesen oder schreiben möchten, muss der Tag erneut mit dem Schlüssel für diesen Sektor authentifiziert werden.

Schritt 5: MFRC522-Modulzugriffssequenz

Die Startroutine umfasst diese grundlegenden Schritte, die in den meisten Anwendungen zu finden sind, die ich mir angesehen habe:

· Dummy-Datenbyte senden (siehe nächster Absatz)

· Soft-Reset

· HF-Empfängerverstärkung einstellen (wenn etwas anderes als die Standardeinstellung gewünscht wird)

· Stellen Sie den ASK-Modulationsprozentsatz auf 100 % ein

· Seed-Wert für CRC-Berechnungen setzen

· Schalten Sie die Antenne ein

· Firmware-Version abrufen (nicht erforderlich)

Aus irgendeinem unerklärlichen Grund fährt mein Modul hoch und denkt, dass es einen Schreibbefehl ohne das Datenbyte erhalten hat. Ich weiß nicht, ob dies nur ein Problem mit meinem Modul ist, aber ich habe an anderer Stelle keine Hinweise darauf gesehen. Ich habe sowohl mit Hardware- als auch mit Software-Resets experimentiert und das Problem nicht behoben. Meine Lösung bestand darin, zu Beginn der Modulinitialisierungsroutine einen Dummy-Leseaufruf zum Register „0“(undefiniert) hinzuzufügen. Wenn das Modul dies als Daten für den unbekannten Schreibbefehl sieht, scheint es keine negativen Auswirkungen zu geben. Wenn es als Lesebefehl betrachtet wird, passiert nichts Nützliches. Es stört mich, dass ich das Problem nicht vollständig definieren kann, insbesondere da ein Hardware-Reset nur des Moduls das Problem nicht behebt.

Der RC522-Chip besteht aus einer Reihe von Registern, von denen die meisten sowohl lesend als auch schreibend sind. Um einen Schreibvorgang durchzuführen, wird die Registernummer gefolgt vom zu schreibenden Wert an das Modul gesendet. Um einen Lesevorgang durchzuführen, wird der Registernummer 0x80 hinzugefügt und an das Modul gesendet. Die Antwort auf einen Schreibbefehl ist ein Echo des Registers, auf das zugegriffen wird. Die Antwort auf einen Lesebefehl ist der Inhalt des Registers. Die Software nutzt dieses Wissen, um zu überprüfen, ob der Befehl ordnungsgemäß ausgeführt wurde.

Schritt 6: PN532-Modulzugriffssequenz

Die Startroutine umfasst die folgenden erforderlichen Schritte:

· Senden Sie eine Initialisierungszeichenfolge: Dies ist spezifisch für die UART-Schnittstelle. Im Handbuch steht, dass die UART-Schnittstelle bei der fünften an der Schnittstelle erkannten steigenden Flanke aufwacht. Es wird empfohlen, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00 zu senden. Meist müssen nur genügend Zeichen mit steigenden Flanken vorhanden sein und sie dürfen nicht wie eine Befehlspräambel aussehen (00 00 FF).

· Modul aufwecken: In der Bedienungsanleitung vergraben steht, dass das Modul in eine Art Schlafzustand namens „LowVbat“initialisiert wird. Um diesen Zustand zu verlassen, müssen wir einen „SAMConfiguration“-Befehl senden.

Der PN532 erwartet, dass Befehle in einem definierten Nachrichtenformat gesendet werden, das eine Präambel, die Nachricht und eine Postambel enthält. Die Antwortnachrichten haben das gleiche Format. Die Befehls- und Antwortnachrichten enthalten beide einen TFI (Frame Identifier) und eine Befehlsversion. Der Befehl verwendet einen TFI von 0xD4 und die Antwort verwendet 0xD5. Die Befehlsversionen variieren, aber die Antwort erhöht immer die Befehlsversion und gibt sie im Byte nach dem TFI zurück. Diese Konsistenz ermöglicht ein einfaches Durchsuchen der Antwortnachrichten nach den relevanten Informationen.

Jede Befehlsnachricht (nach der Präambel) besteht aus der Nachrichtenlänge, dem 2er-Komplement der Nachrichtenlänge, TFI, Befehl, Daten, Prüfsumme und Postambel. Die Software baut die einzelnen Befehle auf und ruft dann eine Routine auf, die die Prüfsumme berechnet und die Postambel anhängt.

Das Nachrichtenformat für die Antwort ähnelt dem des Befehls. Eine typische Antwort enthält ein ACK (00 00 FF 00 FF 00), gefolgt von der spezifischen Antwort auf den Befehl. Jede Befehlsantwort beginnt mit einer Präambel von 00 00 FF. Die Antwort sollte auch ein TFI-Byte von D5 haben, gefolgt von der um 1 erhöhten Befehlsnummer. Für unseren „SAMConfiguration“-Befehl (14) wäre das 15. Der „SAMConfiguration“-Befehl erhält diese Antwort: 00 00 FF 00 FF 00 00 00 FF 02 FE D5 15 16 00.

Es gibt andere modulspezifische Befehle, die gesendet werden können, aber sie werden für diese Anwendung nicht benötigt. Ich habe jedoch eine Routine eingebaut, die aufgerufen werden kann, um die Firmware-Versionsnummer abzurufen. Eine typische Antwort (nach ACK und Präambel) wäre: 06 FA D5 03 32 01 06 07 E8 00. Die „01 06 07“gibt die Firmware-Versionsnummer 1.6.7 an.

Schritt 7: Tag-Zugriffssequenz

Nachdem das Modul fertig ist, können wir spezifische Befehle für die Tags senden. Um Tag-Daten zu lesen oder zu schreiben, benötigen wir deren Identifikationsnummer (UID). Die UID und der Schlüssel werden dann verwendet, um einen bestimmten Tag-Datensektor für Lese-/Schreibvorgänge zu autorisieren. Lese-/Schreibvorgänge von Tag-Daten erfolgen immer an allen 16 Bytes in einem angegebenen Datenblock. Das bedeutet, dass die typische Anwendung den Datenblock liest, die Daten wie gewünscht modifiziert und dann die neuen Daten zurück auf das Tag schreibt.

Schritt 8: Software

Die Interrupt-Handler-Software wird immer dann aufgerufen, wenn der PIC-UART ein Datenbyte empfängt. In einigen meiner früheren UART-Projekte konnte ich nur das RX-Interrupt-Flag abfragen, anstatt einen Interrupt-Handler verwenden zu müssen. Dies ist bei dieser Software nicht der Fall, insbesondere bei der PN532, die mit einer viel höheren Baudrate kommuniziert als die RC522. Die UART-Schnittstelle des RC522 ist auf 9600 Baud begrenzt, während der Standard für den PN532 115k beträgt und bis zu 1.288M Baud eingestellt werden kann. Die empfangenen Bytes werden in einem Pufferbereich gespeichert und der Hauptteil der Software ruft sie bei Bedarf ab.

Das Flag New_Msg zeigt an, dass Bytes empfangen wurden und Byte_Count gibt an, wie viele. Ich habe eine „Disp_Buff“-Routine in die Software integriert, die aufgerufen werden kann, um den Inhalt des Empfangspuffers während des Debuggens anzuzeigen. Einige der Rückmeldungen überlaufen ein typisches 1602-Display, aber ich habe ein 40 Zeichen mal 2 Zeilen LCD, das ich auf einer Online-Site für überschüssige Elektronik gefunden habe. Die „Max_Line“-Definition kann für Ihre LCD-Größe eingestellt werden. Wird „Max_Line“erreicht, fährt die Routine „Disp_Buff“mit dem Schreiben in die zweite Zeile fort. Sie könnten dieser Routine einen kleinen Code hinzufügen, um mit den Zeilen drei und vier fortzufahren, wenn Sie ein 4-zeiliges LCD haben. Für den PN532 gibt es ein Flag, das so gesetzt werden kann, dass die Routine entweder alle empfangenen Bytes ausgibt oder nur die 16 Datenbytes einer Leseantwort ausgibt.

Es besteht keine Notwendigkeit, den Empfangspuffer oder Byte_Count zu löschen, da das Löschen des New_Msg-Flags dazu führt, dass Byte_Count vom Interrupt-Handler gelöscht wird und das als Index in den Puffer verwendet wird. New_Msg wird normalerweise vor jedem Befehlsschritt gelöscht, damit die für diesen Befehl spezifischen Ergebnisse leicht gefunden und überprüft werden können. Das bedeutet beim RC522, dass der Empfangspuffer in der Regel nur 1 bis 4 Byte groß ist. In einigen Fällen, wie zum Beispiel beim Lesen von Datenblöcken, muss der Read_FIFO-Befehl mehrmals ausgegeben werden, um die Bytes aus dem FIFO in den Empfangspuffer zu verschieben. Alle Befehlsergebnisse für den PN532 landen im Empfangspuffer, sodass ein Scanvorgang durchgeführt wird, um die spezifischen benötigten Bytes zu finden.

Die Hauptschleife in der Software sucht nach einem Tag und authentifiziert dann das Tag für Lese-/Schreibvorgänge. Für die hier enthaltene Testsoftware wird die Variable Junk_Num jedes Mal durch die Hauptschleife geändert und beim Schreiben auf das Tag verwendet. Die geschriebenen Werte wechseln zwischen dem Wert von Junk_Num und dem 1er-Komplement von Junk_Num. Abschließend werden die 16 geschriebenen Werte gelesen und angezeigt. Es gibt Anzeigenachrichten für jeden Schritt mit Verzögerungsroutinenaufrufen, um Zeit zum Lesen jeder Nachricht zu geben. Fehlermeldungen werden ebenfalls angezeigt, sollten aber normalerweise nur auftreten, wenn das Tag während einer Operation entfernt wird.

Ein Teil der Software-Initialisierung ist ein Codeabschnitt, der nur beim Einschalten ausgeführt und übersprungen wird, wenn ein Software-Reset erkannt wird. Die Fehlermeldungen enden in der Regel mit einem Software-Reset, um die Hauptschleife zu verlassen. Das Zurücksetzen erfolgt in der "Tilt"-Routine, die einfach den Watchdog-Timer aktiviert und dann in eine Endlosschleife übergeht, die auf den Timeout wartet.

Schritt 9: MFRC522 einzigartige Software

Der RC522-Chip erfordert mehr Low-Level-Befehle als der PN532-Chip, um die Kommunikation mit Tags zu ermöglichen. Es ist eine Art Programmieren in Assembler im Vergleich zu Programmieren in "C". Ein weiterer wesentlicher Unterschied besteht darin, dass der RC522 erfordert, dass die Kommunikation mit dem Tag über einen FIFO-Puffer geleitet wird. Die Routinen „Write_FIFO“und „Read_FIFO“übernehmen diese Aufgaben. Die MFRC522-Software enthält einen Abschnitt für viele der untergeordneten Befehle, aus denen die Hauptfunktionen aufgebaut sind.

Die Prüfsummenberechnung für Tag-Befehle unterscheidet sich beim RC522 stark von der beim PN532. Nachdem der Tag-Befehl in den FIFO eingebaut wurde, wird ein Modulbefehl gesendet, um die Prüfsumme zu berechnen. Das 16-Bit-Ergebnis wird nicht automatisch an den Tag-Befehl angehängt, sondern steht zum Lesen aus zwei 8-Bit-Registern zur Verfügung. Die Prüfsummenberechnung löscht die Daten im FIFO, sodass die erforderliche Reihenfolge wie folgt ist:

· Erstellen Sie den Befehl im FIFO

· Beauftragen Sie eine Prüfsummenberechnung

· Bauen Sie den Befehl im FIFO neu auf

· Lesen Sie die CRC-Register und schreiben Sie die Prüfsummenbytes in das FIFO

· Senden Sie entweder einen Transceive- oder Authenticate-Befehl

Der Transceive-Befehl überträgt den FIFO-Puffer und wechselt dann automatisch in den Empfangsmodus, um auf die Antwort des Tags zu warten. Dem Transceive-Befehl muss das Setzen des StartSend-Bits im BitFramingRegister folgen, um die Daten tatsächlich zu übertragen. Der Befehl Authenticate hat diese Anforderung nicht.

Im Allgemeinen verwenden die online verfügbaren Arduino-C-Code-Anwendungen die Interrupt-Flag-Register und das Timeout-Register, um sicherzustellen, dass die richtige Antwort rechtzeitig empfangen wird. Das ist meiner Meinung nach übertrieben für diese nicht zeitkritische Anwendung. Stattdessen verwende ich kurze Software-Timeouts, um auf die Antwort zu warten und dann zu überprüfen, ob sie korrekt ist. Das Handbuch für die Mifare-Tags beschreibt das Timing für die verschiedenen Transaktionen und die Zeit, die auch für die erwartete Anzahl der zu empfangenden Bytes zulässig ist. Diese Zeitverzögerungen sind in die meisten Befehlsunterprogramme auf niedriger Ebene eingebaut.

Schritt 10: Einzigartige Software PN532

Nachdem das Modul initialisiert wurde, werden die zum Auffinden und Authentifizieren des Tags erforderlichen Schritte durch Schreiben des entsprechenden Befehls gefolgt von den erforderlichen Daten ausgeführt. Der Scan-Befehl gibt die UID zurück, die dann für die Authentifizierung verwendet wird. Danach werden beim Lesen und Schreiben des Tags die 16 Byte für den adressierten Datenblock gesendet oder zurückgegeben.

Die Initialisierungssequenz wurde zuvor detailliert beschrieben und dieselbe Softwareroutine sendet auch den SAMConfiguration-Befehl, um das Modul aus dem "LowVbat"-Zustand zu holen. Der Rest der grundlegenden Befehle, wie z. B. Scannen, Authentifizieren, Tag lesen/schreiben, werden nur sequentiell in die entsprechenden Routinen eingebaut. Die Prüfsumme wird berechnet, indem man einfach die Befehlsbytes addiert, ein Komplement macht und dann 1 addiert, um es zu einem 2er-Komplement zu machen. Das 8-Bit-Ergebnis wird direkt vor der Postambel an die Befehlszeichenfolge angehängt.

Da es kein FIFO wie beim RC522 gibt, werden die vollständigen Antwortnachrichten automatisch empfangen. Die Routine „Find_Response“durchsucht den Empfangsdatenpuffer nach dem TFI (0xD5). Die Routine nutzt das Wissen um die erwarteten Nachrichten und ignoriert einfache ACK-Antworten, die keine Daten enthalten. Sobald der TFI gefunden wurde, sind die gewünschten Antworten ein bekannter Offset davon. Das Befehlsecho und die Befehlsstatusbytes werden von der Routine „Read_Buff“zur späteren Überprüfung gespeichert.

Das war's für diesen Beitrag. Schauen Sie sich meine anderen Elektronikprojekte an: www.boomerrules.wordpress.com

Empfohlen: