Samstag, 11. Februar 2012


Artikel

Juli 2003 | Artikel

Kontakt mit der Außenwelt

(Link zum Artikel: http://www.entwickler.de/dotnet//000397)

Parallelportansteuerung mit .NET

Text: von Markus Palme
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
Der etwas aus der Mode gekommene Parallelport stellt auch heute noch eine attraktive Möglichkeit dar, externe Geräte etc. anzusteuern. Dieser Artikel stellt die Grundlagen und Einsatzmöglichkeiten des Parallelports anhand einiger Beispiele vor.

Warum Parallelport?
Der Parallelport ist in den letzten Jahren von neuen Techniken wie USB und Firewire zunehmend in den Hintergrund gedrängt worden. Sein zweiter Name, Druckerport, offenbart auch schon den wichtigsten Einsatzzweck, die Ansteuerung von Druckern. Doch selbst in diesem Gebiet kann er den heutigen Anforderungen - hauptsächlich der nach höherer Geschwindigkeit - nur noch teilweise nachkommen. Wieso also sollte man sich heute noch mit dieser aus der Mode gekommenen und an Bedeutung verlierenden Schnittstelle beschäftigen?

Der Parallelport ist in der Anwendung sehr einfach, vor allem im Vergleich zu USB: Es sind keine eigenen Treiber und sonstigen hardwarenahen Komponenten nötig. Auch die Ansteuerung gestaltet sich, wie Sie sehen werden, einfach. Die nicht ganz überzeugende Geschwindigkeit ist bei vielen Anwendungen (Steuerung etc.) von nicht allzu großer Bedeutung, sodass sich ein näherer Blick auf jeden Fall lohnen kann. Für die meisten Anwendungen sind die gebotenen acht Ausgänge und fünf Eingänge zudem völlig ausreichend.
Technische Einzelheiten
Um sich vor unnötiger Frustration zu schützen, sollten Sie sich vergewissern, dass Ihre Druckerschnittstelle aktiviert ist. Gehen Sie dazu in das BIOS und hangeln sich in den Menüs bis zum Punkt I/O Device Configuration vor (im Award-BIOS unter Advanced zu finden). Dort haben Sie die Wahl zwischen drei Modi (diese Anzahl kann von BIOS zu BIOS variieren). Der Standardmodus bietet keinerlei bidirektionalen Datenverkehr, SPP/EPP bietet die Möglichkeit, in den bidirektionalen Verkehr zu wechseln, und ECP offeriert weitere Kontrollmöglichkeiten über einige Kontrollbits. In diesem kleinen Artikel soll lediglich auf den grundlegenden EPP-Modus eingegangen werden. Wenn Ihnen die Anzahl der Ein- bzw. Ausgänge zu gering ist, sollten Sie sich mit den anderen Modi auseinandersetzen, detaillierte Informationen finden Sie unter [1].
Seitens des Computers ist ein 25-poliger SUB-D Stecker zu finden, an den Enden gebräuchlicher Druckerkabel meist ein 36-Poliger Centronics-Stecker. In Tabelle 1 ist die Pinbelegung übersichtlich zusammengefasst. Es ist insbesondere zu beachten, dass die Pins an Computerseite nicht notwendig in der gleichen Reihenfolge wie am Centronics-Stecker angeordnet sind.
Pin Druckerport Pin Centronicsstecker Name Richtung
1 1 Strobe Eingang/Ausgang
2 2 Data 0 Ausgang
3 3 Data 1 Ausgang
4 4 Data 2 Ausgang
5 5 Data 3 Ausgang
6 6 Data 4 Ausgang
7 7 Data 5 Ausgang
8 8 Data 6 Ausgang
9 9 Data 7 Ausgang
10 10 Ack Eingang
11 11 Busy Eingang
12 12 Paper out Eingang
13 13 Select Eingang
14 14 Autolinefeed Eingang/Ausgang
15 32 Error Eingang
16 31 Initialize Eingang/Ausgang
17 36 SelectPrinter Eingang/Ausgang
18-25 19-30 Ground -
 
 
Ansteuerung
Doch genug der Vorrede, beginnen wir mit einem einfachen Beispiel, der Ansteuerung einer einzelnen Leuchtdiode (LED). Eine Standardleuchtdiode hat eine maximale Belastbarkeit von 20mA bei einer Spannung von 3V. Die Pegelstände sind folgendermaßen definiert: Der Low-Pegelstand geht von 0 bis 2 V, der High-Pegel von 2 bis 5V. Es ist also ein Vorwiderstand erforderlich, um das Überleben der Diode zu gewährleisten:
Damit ergibt sich folgendes Schaltpicture: Die Diode wird mit dem Minuspol nach einem Vorwiderstand an einen Ausgang (hier Ausgang 3) angeschlossen, mit dem Pluspol an einen der Massenpins (hier 19). Nach dem Einstecken sehen Sie - nichts. Wieso das? Zuerst muss der betreffende Ausgang noch auf den High-Pegel gesetzt werden - womit wir auch schon bei der Ansteuerung und somit der Programmierung wären. Da das .NET Framework aus Portabilitätsgründen (nicht unbedingt auf andere Betriebssysteme, eher auf Kleinstcomputer und andere Geräte) keinerlei Unterstützung in Form von Klassen für Hardwareansteuerung mitbringt, muss auf externe Funktionen, die per P/Invoke angesprochen werden, zurückgegriffen werden. Eine DLL, die den Zugriff auf den Parallelport ermöglicht, ist die InPout32.dll von [2], welche frei verwendet werden kann und unter sämtlichen Windowssystemem (auch NT/2000 und XP) funktionsfähig ist. Diese Bibliothek exportiert lediglich zwei Funktionen - übrigens die gleichen, die es schon unter QBasic gab - welche in C# folgendermaßen importiert werden:
  1. using System;
  2. using System.Runtime.InteropServices;
  3. public class ParPort
  4. {
  5. [DllImport("inpout32.dll", EntryPoint="Inp32")]
  6. public static extern int Input(int adress);
  7. [DllImport("inpout32.dll", EntryPoint="Out32")]
  8. public static extern void Output(int adress, int val);
  9. }
Relevant ist erst einmal nur die Output-Funktion, mit der sich Werte auf die Ausgänge schreiben lassen. Der erste Parameter, die Adresse, ist im Zweifelsfall dem BIOS zu entnehmen. Normalerweise erhält der erste Parallelport (LTP1) jedoch die Hexadezimaladresse 378, der zweite 278, in Dezimalschreibweise 888 und 632. Ein Programm zur Umrechnung der Adressen finden Sie im Zip-Archiv, einen Downloadlink finden Sie am Ende des Dokumentes. Der zweite Parameter gibt an, welcher Ausgang/welche Ausgänge geschaltet werden sollen. Diese Werte für die einzelnen Datenleitungen lassen sich über die Formel 2n berechnen, n steht dabei für die Datenleitung, es wird bei Null zu zählen begonnen. Somit ergeben sich die Werte 0 für die Leitung 0, 1 für die Leitung 1, 4 für die Leitung 2 usw. Um mehrere Leitungen gleichzeitig anzusteuern, werden die Werte einfach addiert, der Spezialwert 0 schaltet alle Leitungen aus. Lange Rede, kurzer Sinn, um die Diode anzuschalten, ist dieser Aufruf der statischen Funktion Output erforderlich:
  1. ParPort.Output(632, 6);
Programmtemplates
Im Folgenden werde ich Ihnen zwei Programme vorstellen, welche Sie als Grundlage für weitere Eigenentwicklungen verwenden können. Die erste der Applikationen geht noch einmal auf das Schreiben von Werten ein, die zweite auf das Lesen. Ziel ist es, komfortabel einzelne Werte zu schreiben, wie auch auf dem Screenshot in Abpictureung 4 ersichtlich.
Listing 1
  1. this.Size = new Size(400, 200);
  2. for(int i=0;i<8;i++)
  3. {
  4. boxes[i] = new CheckBox();
  5. boxes[i].Location = new Point(i * 40 + 12, 12);
  6. boxes[i].Width = 40;
  7. boxes[i].Text = (i + 1).ToString();
  8. boxes[i].Tag = i;
  9. boxes[i].CheckedChanged += new EventHandler(onBoxClick);
  10. Controls.Add(boxes[i]);
  11. }
  12. binaryLabel.Location = new Point(12, 40);
  13. binaryLabel.Text = "Value:";
  14. binaryLabel.Height = 12;
  15. Controls.Add(binaryLabel);
  16. binaryTextBox.Location = new Point(12, 60);
  17. binaryTextBox.Enabled = false;
  18. Controls.Add(binaryTextBox);
Zuerst wird das GUI im Konstruktor des Hauptformulars dynamisch aufgebaut (siehe Listing 1). In der EventHandler-Prozedur des CheckedChanged-Events der Checkboxen wird dann der binäre Werte berechnet und auf den Port geschrieben. Dort müssen Sie eventuell noch die Adresse an die individuellen Gegebenheiten anpassen:
  1. void onBoxClick(object sender, EventArgs e)
  2. {
  3. int val = 0;
  4. for(int i=0;i<8;i++)
  5. {
  6. if(((CheckBox)boxes[i]).Checked == true) {
  7. val += (int)Math.Pow(2, i);
  8. }
  9. }
  10. binaryTextBox.Text = val.ToString();
  11. ParPort.Output(632, val);
  12. }
Das zweite Beispiel zeigt die Werte der Eingänge an. Die Adresse der Eingänge liegt eins über der Basisadresse, also für den ersten Parallelport bei 633. Unschön ist, dass zum Einlesen Polling verwendet werden muss, sprich der Anwendung kriegt nicht mitgeteilt, wann sich etwas geändert hat, sondern diese muss sich per Timer selbst einen Überblick darüber verschaffen. Eigentlich ist dieses Verfahren heute nicht mehr akzeptabel, es ist aber keine andere Möglichkeit vorhanden. Wenn Sie die Masse mit einem der Eingänge verbinden, sollten Sie, um einen Kurzschluss zu verhindern, einen Widerstand von etwa 5k Ω vorschalten.

Download: Quellcode zum Artikel
Links und Literatur

Kommentare