Im ersten Teil haben wir uns mit der USB-Kommunikation über den virtuellen COM-Port beschäftigt. Das ist zwar sehr einfach, in den Möglichkeiten jedoch leider etwas eingeschränkt. Wenn Sie eigene Applikationen erstellen wollen, dann sind die Funktionen der DLL die richtige Wahl. Das Herunterladen haben Sie schon im ersten Teil kennen gelernt, die DLL wird ja mit dem VCP-Treiber in einer kombinierten Datei angeboten.
Bevor wir uns an das Erstellen der Software machen, brauchen wir eine möglichst einfache Hardware, um unsere Ergebnisse sofort überprüfen zu können. Es handelt sich um eine simple Steckbrettschaltung, die lediglich aus dem USBMOD4-Modul von Elexol, 8 LEDs und einem Widerstandsnetzwerk mit 8 x 470 Ohm besteht.
Oberhalb des USBMOD4-Moduls können sie 2 kleine Drahtbrücken erkennen, deren Funktion im 1. Teil beschrieben sind. Von den 8 Datenleitungen D0-D7 geht es direkt auf die Anode (langer Anschluss) der LED und von dort über das Widerstandsnetzwerk (schwarzer Balken hinter den LED) auf Masse. Wird ein Ausgang auf "high" gezogen, leuchtet also die LED. Mehr brauchen wir zum Testen nicht.
Nach der Installation des Treibers findet sich die Datei ftd2xx.dll im Systemverzeichnis ..windowssystem32. Alternativ können Sie die Datei auch in Ihr Projektverzeichnis kopieren. Für dieses Tutorial verwende ich Delphi 6 Professionell, es dürfte aber mit den meisten anderen Versionen und Varianten auch problemlos laufen.
Zunächst legen wir ein einfaches Projekt in Delphi an. Als Rückgabewert für die meisten Funktionen der ftd2xx.dll wird eine Variable vom Typ FT_Result verwendet, die wiederum vom Typ Integer ist. Um es ganz deutlich zu machen, habe ich also zunächst in einer Typdefinition FT_Result als Integer definiert und dann später eine Variable "Result" vom Typ FT_Result erzeugt. Das gleiche gilt für FT_Handle (Typ DWord).
Nun müssen wir die externen DLL-Funktionen bekannt machen. Die folgenden Zeilen binden die wichtigsten Funktionen ein:
Sie können die Befehle natürlich in eine Zeile schreiben, ich habe nur einen Umbruch verwendet, damit Sie nicht zu breit werden. Alle Funktionen, allerdings in C-Konvention, finden Sie in der DLL-API-Dokumentation.
Die erste Funktion, die wir benutzen wollen ist "FT_ListDevices". Dazu ziehen wir einen Button auf unser leeres Form und daneben setzen wir ein Edit-Feld. Durch Doppelklicken auf den Button kommen wir in den Quelltext-Editor und zwar an die Stelle, wo unser Code stehen muss, der durch das Anklicken des Buttons ausgeführt werden soll.
Der Programmcode ist recht simpel:
In der Variablen "dwDevCount" wird später die Anzahl der Module stehen, für den Rückgabewert der Funktion benötigen wir die schon angesprochene Variable "Result" vom Typ FT_Result. Die Funktion FT_ListDevices kann in einer Vielzahl von Varianten genutzt werden, uns interessiert lediglich die einfachste Form, die nur die Anzahl der gefunden Module zurückgibt. Deshalb verwenden wir als letztes Argument das Flag "FT_LIST_NUMBER_ONLY". Dieser Konstanten müssen wir am Programmanfang noch den Wert $80000000 zuweisen. Wenn Sie sich das sparen wollen, können Sie den Wert natürlich auch direkt übergeben.
Zu den weiteren Parametern: Mit @dwDevCount übergeben wir einen Zeiger auf die Variable dwDevCount und mit NIL einen Nullzeiger. Der 2. Parameter wird nur benötigt, wenn wir ein anderes Flag als 3. Argument verwenden.
Falls die Funktion erfolgreich durchgeführt wurde, ist der Wert von Result = 0 und unser Programm quittiert das mit der Ausgabe der gefundenen Module im Editfeld "ED_count". Tritt ein Fehler auf, so wird dies ebenfalls im Editfeld signalisiert.
Mit FT_ListDevices() haben wir festgestellt, ob und wie viele Module am USB-Bus angeschlossen sind. Falls Sie nur ein einziges Modul verwenden, brauchen Sie diese Funktion prinzipiell nicht aufzurufen. Die erste wirklich notwendige Funktion ist FT_Open(). Für den Aufruf sind lediglich zwei Parameter erforderlich:
Im 1. Parameter wird der Index des Moduls angegeben. Wir haben nur ein Modul, der Index dafür ist "0". Der 2. Parameter ist ein Zeiger auf unser Device-Handle FT_hd. Da fast alle folgenden Funktionen über den Device-Handle auf das Modul zugreifen, muss diese Variable global deklariert werden.
Das Ergebnis des Aufrufs wird ausgewertet und ein Text im Editfeld "ED_state" ausgegeben. Außerdem wird eine Combo-Box und ein Label-Feld aktiviert, die wir für die nächste Funktion benötigen.
Mit der 3. Funktion konfigurieren wir das Modul mit der passenden Datentransferrate. Dazu nutzen wir eine Combo-Box aus der Werte von 300 bis 115200 ausgewählt werden können. Die tatsächliche Übertragungsgeschwindigkeit ist allerdings 16-mal so groß, wie die angegebene Baudrate.
Der gewählte Wert aus der Combo-Box wird in die Variable iBaud übernommen und dann der Funktion übergeben. Der 1. Parameter ist wieder unser Device-Handle. Diesmal allerdings nicht als Zeiger, sondern als Variable selbst.
Danach erfolgt wiederum eine Prüfung, ob die Funktion fehlerfrei durchlaufen wurde und eine entsprechende Reaktion.
Der letzte Schritt der Vorbereitung ist das Setzen des Bit-Mode-Registers über die Funktion:
Der Aufruf benötigt 3 Parameter:
1. Den Device-Handle
2. Eine Variable vom Typ "unsigned char" mit der wir angeben, ob es sich um Ein- oder Ausgänge handelt (eine 1 schaltet den entsprechenden Pin auf Ausgang, eine 0 auf Eingang).
3. Die Angabe, welche Art von Kommunikation wir wählen. In unserem Beispiel ist dies eine $01 für asynchronen Bit-Bang-Modus. Eine $00 würde einen Reset auslösen.
Nachdem auch diese Funktion erfolgreich aufgerufen wurde, können wir zur eigentlichen Kommunikation kommen!
Die Daten werden nun mit der Funktion FT_Write in das Modul geschrieben. Dabei passiert folgendes: Stehen Daten an, werden Sie mit programmierten Übertragungsgeschwindigkeit am Ausgang ausgegeben. Wollen Sie nur ein einzelnes Zeichen ausgeben (z. B. um 8 I/O-Leitungen über den USB anzusteuern, nutzen Sie eine einfache Variable vom Typ Byte. Wollen Sie einen Datenstrom ausgeben, dann verwenden Sie ein Array.
In diesem simplen Beispiel kommt die Byte-Variable bO_Mask zum Einsatz. Die Write-Funktion sieht dann folgendermaßen aus:
1. Der Handle
2. Ein Zeiger auf unsere Variable oder ein Variablen-Array
3. Die Anzahl der zu schreibenden Bytes
4. Ein Zeiger auf eine Integer-Variable, die nach dem Aufruf die Zahl der tatsächlich geschriebenen Bytes enthält.
Rufen wir diese Funktion mit bO_Mask = $FF auf, so leuchten alle 8 LEDs.
Lesen können Sie die Anschlüsse übrigens mit der Funktion FT_Read().
Das war´s ... noch nicht ganz!
Am Schluss sollten Sie auf jeden Fall mit: FT_Close(FT_hd) das Modul wieder schließen und die Ressourcen frei geben.
Wichtig! Es ist durchaus möglich, dass Sie nur mit den Funktionen FT_Open und FT_Write schon Ergebnisse erzielen. Sie sollten aber auf jeden Fall auch FT_SetBaudRate und vor allem FT_SetBitMode gezielt aufrufen. Das folgende Testprogramm erlaubt bewusst den Aufruf von FT_Write ohne das Setzen des Baudrate- und Bitmodus-Registers und in diesem Fall können sehr unschöne Abstürze die Folge sein, da die Register wohl undefinierte Zustände annehmen können.
Sie können den ganzen Code für das Delphi-Programm im Anhang (ganz unten rechts) herunterladen. Im Archiv ist das komplette Projekt für Delphi 6 enthalten, aber auch das kompilierte Programm, damit Sie Ihr USBMOD-Modul sofort austesten können. Bei Fragen stehen wir Ihnen jederzeit gern über unser Kontaktfomular zur Verfügung.
Für weitere Informationen und Bestellungen einfach auf nachfolgende Links klicken:
Falls Sie Fragen zum Thema haben, wenden Sie sich einfach an uns.
Wir helfen Ihnen gern weiter!
Ihr Team von Böcker Systemelektronik
Hinweis: Unser Tutorialangebot wird in unregelmäßigen Abständen erweitert. Wenn Sie sofort über eine Neuerscheinung informiert werden möchten, tragen Sie sich bitte hier in unsere Benachrichtigungsliste "Tutorials" ein. Sie können diesen unverbindlichen Service jederzeit in Ihrem Kundenkonto oder per E-Mail wieder abbestellen.
Copyright © Böcker Systemelektronik