Mehr Funktion auf kleiner Fläche USB in Embedded-Systeme integrieren

Von Robert Perkel* 5 min Lesedauer

Anbieter zum Thema

USB ist in IT und industriellen PCs bereits fest etabliert, eröffnet aber auch in kompakten Embedded-Systemen neue Möglichkeiten. Welche Ansätze zur Integration gibt es, und wie lässt sich USB-Funktionalität in der Praxis effizient umsetzen?

USB ist eine vielfältig einsetzbare, aber vergleichsweise kompexe Form der seriellen Kommunikation, und daher in Embedded-Systemen eher selten anzutreffen. Doch die weite Verbreitung des Kommunikationsstandards macht ihn auch im Embedded-Umfeld interessant. Neue Entwicklungen im Bereich der Mikrocontroller vereinfachen die Implementierung in eingebettenen Systemen.(Bild:  frei lizenziert / Unsplash)
USB ist eine vielfältig einsetzbare, aber vergleichsweise kompexe Form der seriellen Kommunikation, und daher in Embedded-Systemen eher selten anzutreffen. Doch die weite Verbreitung des Kommunikationsstandards macht ihn auch im Embedded-Umfeld interessant. Neue Entwicklungen im Bereich der Mikrocontroller vereinfachen die Implementierung in eingebettenen Systemen.
(Bild: frei lizenziert / Unsplash)

USB ist zwar ein weit verbreitetes serielles Kommunikationsprotokoll, das in großen Mikrocontrollern (MCUs) und Mikroprozessoren (MPUs) zu finden ist, aber nicht immer in Embedded-Systemen. Dies liegt an mehreren Faktoren: Anforderungen an die elektrische Signalübertragung, Protokoll-Overhead und die Verfügbarkeit einfacherer Kommunikationsprotokolle wie Serial Peripheral Interface (SPI), I2C oder UART. USB wird die einfacheren Kommunikationsprotokolle zwar nicht verdrängen, ist aber für tragbare Anwendungen eine Überlegung wert.

Es gibt zwei Möglichkeiten, USB in ein Design zu integrieren: durch einen anwendungsspezifischen integrierten Schaltkreis (ASIC) oder durch Auswahl einer MCU mit USB-Hardware-Unterstützung. Jeder Ansatz hat seine Vor- und Nachteile.

USB mittels ASIC integrieren

Eine einfache Möglichkeit, USB in ein Design zu integrieren, ist ein ASIC, der die USB-Kommunikation intern verarbeitet und die gewünschten Daten und Signale ausgibt. Einer der gängigsten USB-ASICs ist eine USB-UART-Bridge, eine (relativ) transparente Schnittstelle für die Datenübertragung von einem USB-Host zu einem Embedded-System. Häufig handelt es sich dabei um einen virtuellen COM-Port auf dem Host, der von einer seriellen Terminal-Anwendung für die bidirektionale Kommunikation geöffnet werden kann. Oft bieten diese ASICs auch weitere Funktionen wie USB-I2C, I/O-Leitungssteuerung, analoge Abtastung etc. Diese Bausteine lassen sich direkt in ein Design integrieren und erfordern daher nur minimalen Implementierungsaufwand. Damit eignen sie sich ideal für die kurzfristige Ergänzung eines Designs.

Der Einsatz dieser ASICs unterliegt jedoch einigen Einschränkungen. Ein Nachteil ist der einheitliche Ansatz. Wenn bestimmte Funktionen mit dem ASIC nicht realisiert werden können, ist dieser Ansatz nicht praktikabel. Ein weiterer Nachteil sind die zusätzlichen Komponenten, die in die Stückliste (BOM) mit einfließen. Diese benötigen Platz auf der Leiterplatte und erhöhen die Kosten des Designs.

USB über einen Mikrocontroller integrieren

Wenn bereits vor der Auswahl einer MCU bekannt ist, dass USB-Kommunikation benötigt wird, ist ein Baustein mit integrierter USB-Hardware-Peripherie eine gute Option. Diese findet sich in zahlreichen MCUs, von hocheffizienten 8-Bit- bis hin zu leistungsstarken 32-Bit-Varianten. Die Auswahl der richtigen MCU hängt von der Anwendung ab.

Für einfache Anwendungen wie Tastaturen, Mäuse und USB-UART-Konverter sind 8-Bit-MCUs gut geeignet. Diese kombinieren geringe Baugröße, reduzierten Stromverbrauch, niedrige Kosten und nativen +5V-Betrieb.

Bild 1: Vergleich verschiedener Implementierungsansätze(Bild:  Microchip Technology)
Bild 1: Vergleich verschiedener Implementierungsansätze
(Bild: Microchip Technology)

Für rechenintensive Anwendungen sollten 32-Bit-MCUs in Betracht gezogen werden, die leistungsfähiger sind und über mehr Speicher verfügen. Allerdings können diese teuer und groß sein und einen begrenzten Betriebsspannungsbereich haben. Eine Tabelle mit den Vor- und Nachteilen der verschiedenen Ansätze ist hier aufgeführt.

USB-Anwendungen mit AVR DU

Es gibt zahlreiche MCUs mit USB-Peripherie. Dieser Abschnitt konzentriert sich auf die AVR-DU-Reihe, den Nachfolger der MCU-Serie XMEGA D.

AVR DU bietet gegenüber älteren MCUs mehrere Verbesserungen. Zum einen ist kein externer Quarz mehr erforderlich, was die Stücklisten-/BOM-Kosten senkt. Die DU-Reihe enthält auch einen integrierten Linear-Drop-Out-/LDO-Regler für die USB-Schaltung, wenn die MCU mit 3,9 V oder mehr versorgt wird. Schließlich kommt noch die Funktion „Program and Debug Interface Disable“ (PDID) hinzu, die den Baustein dauerhaft sperrt und verhindert, dass die MCU gelesen, gelöscht oder erneut programmiert werden kann.

Bild 2: Öffnen des USB-SPI/I2C-Projekts im MCC(Bild:  Microchip)
Bild 2: Öffnen des USB-SPI/I2C-Projekts im MCC
(Bild: Microchip)

Die folgenden Beispiele zeigen einfache Anwendungen, die auf der AVR-DU-Reihe entwickelt wurden. Sie nutzen den MPLAB Code Configurator (MCC), ein kostenloses Tool, das mithilfe der enthaltenen USB-Stack-Bibliothek eine API für die integrierte Hardware-Peripherie konfiguriert und generiert. Die Bibliothek unterstützt Kommunikation der CDC-Klasse (Communications Device Class) und Eingabegeräte/HIDs (Human Interface Devices) wie Tastaturen und Mäuse.

CDC-Anwendung: USB zu SPI/I2C

Dieses Beispiel stellt einen USB-zu-SPI/I2C-Konverter dar, der ohne speziellen Treiber funktioniert. Die MCU wird dabei als generischer CDC-Baustein identifiziert. Die meisten Betriebssysteme verfügen über einen generischen Treiber für diese Art der Kommunikation, mit dem Benutzer Daten ohne Installation eines speziellen Treibers senden und empfangen können.

Um eine serielle Operation zu starten, sendet der Benutzer einen speziell formatierten „Satz“ an die MCU. Die dort empfangenen Daten werden analysiert und (wenn möglich) in einen SPI- oder I2C-Busbetrieb umgewandelt. Anschließend meldet die MCU Befehls- und Kommunikationsfehler (nur I2C) oder während des Austauschs gelesene Daten. Für SPI werden die „Sätze“ wie folgt formatiert:

spi eeprom/dac/usd <byte data to send>

Dabei beziehen sich „eeprom“, „dac“ und „usd“ auf Komponenten des Curiosity Nano Explorer, der hier verwendet wird. Der folgende Ausschnitt ist ein Beispiel für einen „Satz“ des Benutzers zur Kommunikation mit einem EEPROM (25CSM04) auf dem Explorer-Board. Dieser Befehl liest das Identifikationsregister des Speicherchips aus.

Jetzt Newsletter abonnieren

Verpassen Sie nicht unsere besten Inhalte

Mit Klick auf „Newsletter abonnieren“ erkläre ich mich mit der Verarbeitung und Nutzung meiner Daten gemäß Einwilligungserklärung (bitte aufklappen für Details) einverstanden und akzeptiere die Nutzungsbedingungen. Weitere Informationen finde ich in unserer Datenschutzerklärung. Die Einwilligungserklärung bezieht sich u. a. auf die Zusendung von redaktionellen Newslettern per E-Mail und auf den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern (z. B. LinkedIn, Google, Meta).

Aufklappen für Details zu Ihrer Einwilligung
spi eeprom 9F 00 00 00 00 00> FF 29 CC 00 01 00

I2 verwendet drei ähnliche, aber unterschiedliche Formate für „Sätze“, da der I2-Bus von allen angeschlossenen Geräten gemeinsam genutzt wird.

i2c <address> r <number of bytes to read>i2c <address> w <bytes to write>i2c <address> wr <register address byte> <number of bytes to read>

Wie beim SPI lässt sich dies schnell testen, indem die Hersteller-ID eines Sensors gelesen wird – in diesem Fall eines MCP9808-Temperatursensors.

i2c 1c wr 06 02> 00 54

Dieses Beispiel ist auf Github verfügbar.

HID-Anwendung: USB-Tastatur

Ein einfaches, leicht anpassbares Beispiel für USB-Kommunikation ist die Implementierung einer Tastatur. Wird eine Taste gedrückt, wird ein Bericht an den Host gesendet, der angibt, welche Taste(n) der Benutzer gedrückt hat. Wird die Taste losgelassen, wird ein weiterer Bericht gesendet, um anzuzeigen, dass die Taste vom Benutzer losgelassen wurde.

Dieses Beispiel ist anders implementiert. Anstatt wie bei einer Standardtastatur eine einzelne Taste oder Schaltfläche zu melden, meldet dieses Beispiel mehrere Tasteneingaben für einen einzigen Tastendruck, um Funktionsmakros zu erstellen. Wird beispielsweise SW0 auf dem AVR64DU32 Curiosity Nano gedrückt, wird ein Bericht mit den Tasten „AVR DU“ an den Host-Computer gesendet. Die LED am Curiosity Nano zeigt den Status der Feststelltaste auf dem Host-System an.

Zusätzlich zum Curiosity Nano ist über das Curiosity Adapter Board auch ein 2x2 Click angeschlossen. Die Tasten sind den Makros CTRL + C (Kopieren), CTRL + V (Einfügen), CTRL + Z (Rückgängig) und CTRL + X (Ausschneiden) zugeordnet. Eine optionale externe Taste kann ebenfalls angeschlossen werden, um ALT + F4 an den Host zu senden. Dieses Beispiel ist auf Github verfügbar.

Fazit

USB ist zwar eine der komplexesten Arten der seriellen Kommunikation in Embedded-Systemen – seine Allgegenwärtigkeit bietet jedoch einen erheblichen Mehrwert für Designs. USB lässt sich über einen ASIC auf Kosten einer größeren Stückliste einfach in ein Design integrieren. Alternativ kann auch eine MCU mit integrierter USB-Hardware gewählt werden. Anschließend muss entschieden werden, ob das MCU-basierte Design die Leistungsfähigkeit eines 32-Bit-Bausteins erfordert oder ob eine einfachere, aber kostengünstigere 8-Bit-MCU aus der AVR-DU-Reihe ausreicht.  (sg)

* Robert Perkel ist Application Engineer in der 8-Bit MCU Business Unit bei Microchip Technology

(ID:50460854)