Q-basic -- serielle schnittstelle programmiere

Hallo GeoK,

uiii, das tut mir aber leid. Ich kann es hier nicht ausprobieren oder verbessern, weil meine Computer zu weit auseinanderstehen und mir jemand obendrein das Nullmodemkabel geklaut hat.

Zähneknirschend muß ich gestehen, daß ich mit OPEN geschweige denn OPEN COM in Basic öfters auch nicht klarkomme (könnte aber an win98 liegen), ich dachte, wenn mans aus einem guten Buch hat, wirds schon klappen.

Mein Artikel zu OUT und der ganzen PORT-Sache muß bis zum Wochende warten. Vielleicht kriegen wir es hin, daß Ganze unter Umgehung von OPEN zu deichseln.

Wenn dieser Thread bis dahin verschwunden ist, mußt Du Dich entweder an mich direkt wenden oder noch einen Artikel schreiben.

cu
ralph

Hallo GeoK,

uiii, das tut mir aber leid. Ich kann es
hier nicht ausprobieren oder verbessern,
weil meine Computer zu weit
auseinanderstehen und mir jemand obendrein
das Nullmodemkabel geklaut hat.

Zähneknirschend muß ich gestehen, daß ich
mit OPEN geschweige denn OPEN COM in Basic
öfters auch nicht klarkomme (könnte aber
an win98 liegen), ich dachte, wenn mans
aus einem guten Buch hat, wirds schon
klappen.

Mein Artikel zu OUT und der ganzen
PORT-Sache muß bis zum Wochende warten.
Vielleicht kriegen wir es hin, daß Ganze
unter Umgehung von OPEN zu deichseln.

Wenn dieser Thread bis dahin verschwunden
ist, mußt Du Dich entweder an mich direkt
wenden oder noch einen Artikel schreiben.

cu
ralph

du willst das port ansteuern ohne eine open anweisung, also direkt ???
dazu braucht man eigentlich assembler, wenn du das kannst fin ich das super, anderes könnte ich mir aber nicht vorstellen, dass man das irgendwie hinkriegt.
meine assembler-kenntnisse reichen leider noch nicht aus um so etwas zu schreiben.
wäre aber super wenn wir das irgendwie hinkriegen könnten.
vielleicht wärs es geschieter wenn wir ab jetzt per e-mail kommunizieren…

yours,
geoka

Hallo GeoK,

Assembler braucht man eigentlich nur, wenn man volle Kontrolle über die Maschine haben will. Das sind dann kritische Aufgaben, z.B. zeitkritisch: das Programm muß so schnell wie möglich laufen. Oder steuerungskritisch: Das Programm darf nicht irgendwie (Interrupts) unterbrochen werden. Und was Dich ganz aufgeregt macht, nämlich jemand anderem einen Virus, Trojaner oder Wurm unbemerkt in das System zu schleusen, das mache ich nicht mit. Um Assembler programmieren zu können, mußt Du anfangen zu denken wie die Maschine – und außerdem ist es wahnsinnig umständlich. Wenn Dich das aber interessiert, dann schaff dir ein Turbo-Pascal 6 oder 7 (nicht 5) an und ein Anfänger-Handbuch (nicht nur Turbo-Pascal sondern Assembler) und experimentiere mit dem ASM-END-Befehl herum.

Das meiste geht auch in QBasic. Die beiden Befehle OUT und INP steuern die Hardware an. Der PC ist so organisiert, daß die Ansteuerung des Speichers über einen Leitungsstrang (Bus) und die Ansteuerung der übrigen Hardware über einen anderen Strang erfolgt. Uns interessiert hier nur der „andere“ Strang, der ganz verschiedene Namen hat (z.B. PCI-Bus). Hier läuft es normalerweise so, daß zunächst eine Zahl in den Raum geworfen wird und ein Gerät sich angesprochen fühlt. Direkt hinter dieser „Adressierung“ folgt eine weitere Zahl, damit das angesprochene Gerät weiß, was es zu tun hat. Wenn man erst abwartet, bis das Gerät „hier!“ brüllt, dann spricht man von Handshake-Modus. Die erste Zahl, die gesendet wird, um die Aufmerksamkeit eines Geräts zu erringen, nennt man Port-Adresse. Die zwanghaft germanische Übersetzung in der QBasic-Hilfe spricht von Hardware-E/A-Anschluß. OUT (764), 8 heißt also: Zuerst 764, dann 8 senden.

Manche Geräte haben mehrere Port-Adressen. Schon allein an der Zahl, die gesendet wird, weiß das Gerät also schon: „Aha, der Wille des Prozessors geht in diese und jene Richtung“. Die zweite serielle Schnittstelle (COM2) fühlt sich angesprochen bei den Port-Adressen 760 bis 766.

Schnitt: An dieser Stelle mußt Du Dich mit Hexadezimalzahlen anfreunden. Hexadezimalzahlen sind die allgemein übliche Darstellungsform von Binär- (Dual-)zahlen. Und Binärzählen sind die Darstellung dessen, was sich da auf dem Bus tut. Der Bus auf Deinem AT hat sechzehn Leitungen, mit denen die Adressen und Befehle gesendet werden. Um die Zahl 764 zu senden, wird die Spannung auf den Leitungen (wir haben es ja mit Strom zu tun) wie folgt gesetzt (1 steht für Spannung=hoch, 0 steht für Spannung=niedrig/manchmal negativ): 0000001011111100. Du kannst Dir leicht vorstellen, daß man innerhalb kürzester Zeit wahnsinnig wird, wenn man mit solchen Ungetümen umgehen muß. Man faßt dieses Ding also zu Vierergruppen (bei Dreiergruppen sind wir im Oktalsystem) zusammen und zählt wie folgt:

Binär Dezimal Hexadezimal
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 8
1001 9 9
1010 10 A
1011 11 B
1100 12 C
1101 13 D
1110 14 E
1111 15 F

Sinn der Sache ist, daß vier Bits (Binärzahlen) immer nur durch eine Ziffer dargestellt werden soll. Die Zahl 764 wird im Hexadezimalsystem als 02FC dargestellt. Gewöhne Dir die führende Null an, sie erspart einem manches Mißverständnis. Um die Hexadezimalzahl für eine Dezimalzahl herauszukriegen ist der HEX$-Befehl in QBasic ideal. Auch der Rechner von Windows kann umrechnen.

QBasic würde „02FC“ als Variable und nicht als Zahl auffassen. Eine Angabe wie Port=02FC, würde also zu Port=0 führen, weil die Variable mit dem Namen „02FC“ zu diesem Zeitpunkt sicherlich noch nicht existiert hat. Also muß man QBasic extra erzählen, daß es sich hier um eine Hexadezimalzahl handelt. Dies geschieht, indem man ein „&H“ vor die Hexadezimalzahl schreibt, also: &H02FC. In Turbo Pascal ist es ein „$“ ($02FC) in C ein „0x“ (0x02FC), in Assembler wird hinten ein „h“ angehängt (02FCh).

Die serielle Schnittstelle sendet (und empfängt) grundsätzlich wie ein Radio: Es ist völlig egal, ob jemand zuhört, die Musik dudelt. Das ist flapsig ausgedrückt die Baudrate. Baudrate ist die Zahl der Bits, die pro Sekunde gesendet und empfangen werden. Wenn Du also ein „A“ durch die Leitung schicken willst, dann wird der Buchstabe in ein Byte (=8 Bits umgewandelt) und bitweise hintereinander gesendet ohne Rücksicht darauf, ob es am anderen Ende ankommt. Meistens wird noch ein neuntes Bit gesendet, das sogenannte Stoppbit. Wenn ich das aus den wichtigtuerischen Artikeln richtig herausgelesen habe, handelt es sich eher um eine Verschnaufpause für Uraltgeräte. Die Baudrate muß auf beiden Seiten gleich eingestellt sein, sonst gibt es Mißverständnisse. Bei einer Baudrate von 9600 (9600 Bits pro Sekunde) würde also der Buchstabe A mit 9 Bit eine Sendezeit von 9/9600 s, also etwa eine Tausendstel Sekunde benötigen. Das müßte für Nibbles eigentlich genügen. Die Baudrate direkt über Port-Adressierung einzustellen, ist etwas kompliziert, wie Du gleich bemerken wirst. Es muß auch programmiert werden, aus wievielen Bits ein Byte bestehen und was die überzähligen Bits bedeuten sollen.
Der RS232-Schnittstelle muß man auch noch erzählen, daß sie jetzt aufpassen soll, was an ihrem Ausgang passiert. Man simuliert mittels Programm ein Peripheriegerät, daß anfängt zu senden und zu empfangen. Dafür sind die Leitungen DTR und RTS im Kabel und die beiden letzten Bits des Ports &H02FC zuständig. Sind DTR (Data Terminal Ready) und RTS (Request To Send) hochgesetzt (unter Spannung), bedeutet das, die Schnittstelle (Terminal) ist bereit (ready) ist, zu senden und zu empfangen, und auch ein Peripheriegerät (hier der andere Computer) willig ist (request), Daten empfangen.

Bevor ich nachfolgend das nächste ungeprüfte Programm schicke, versuch mal, ob sich alles in Wohlgefallen auflöst, wenn Du ganz am Anfang meines letzten Programms folgende Zeile einfügst:

RESET

Versuch mal, ob folgendes Programm (auf beiden Rechnern gestartet) funktioniert. Es ist übrigens auch ein hervorragendes Beispiel, was sogenannter Spaghetti-Code ist.

REM Open Com
OUT (&H02FB), &H80 : REM Baudeingabe aktivieren
OUT (&H02F8), &H12 : REM Baudrate 9600
OUT (&H02F9), 0 : REM was auch immer
OUT (&H02FB), &H03 : REM 8 Bit, Kein Parity-Bit, 1 Stopbit
OUT (&H02FC), &H03 : REM DTR=1, RTS=1
Dummy = INP (&H02F8) : REM Empfangspuffer lesen und leeren
REM Los gehts
Tastaturabfrage:
A$ = INKEY$
If A$ = „“ THEN GOTO Empfangen ELSE GOTO Senden
Senden:
IF A$ = „e“ THEN GOTO Ende
WHILE (INP (&H02FD) AND &H20) = &H20: WEND : REM Warten bis Sendepuffer leer ist
B = ASC (A$)
OUT (&H02F8), B
GOTO Tastaturabfrage
Empfangen:
IF (INP (&H02FD) AND &H01) = &H01 THEN B=INP(&H02F8) : REM Zeichen lesen, wenn Zeichen anliegt
A$ = CHR$(B)
PRINT A$
GOTO Tastaturabfrage
Ende:
OUT (&H02FC), 0 : REM Schließen – DTR=0, CTS=0
END

Sollte es nicht klappen, dann beschreibe bitte genau, was Du in welcher Reihenfolge getan hast und wie der Computer reagiert hat. Übrigens, das Nullmodemkabel muß an beiden Seiten an der zweiten seriellen Schnittstelle hängen, da ich davon ausgehe, daß an COM1 die Mäuse angeschlossen sind.

Alles weitere direkt, wobei ich allerdings ein bißchen einschränken möchte, daß ich keinen Fernunterricht mache. Nicht böse sein :o))).

Grüsse
ralph