Danke, das erwähnen viele Quellen, die ich im Internet gefunden habe, gar nicht.
[FONT="Courier New"]out [com1], whatever[/FONT] wäre so schön anschaulich gewesen. Dadurch, dass ich nun vorher den zu versendenden Wert an AL und die Port-Adresse an DX senden muss, verdreifacht sich die Schreibarbeit und der Quelltext wird recht unübersichtlich, aber dagegen lässt sich wohl nicht viel machen.
Gibt es eigentlich irgendeine Möglichkeit, einen Timer unter Assembler einzusetzen? Ich würde die Schleife, die auf Daten von dem Gerät wartet, ganz gerne unterbrechen, wenn nach beispielsweise 2 Sekunden noch keine Daten gesendet worden sind.
Gibt es eigentlich irgendeine Möglichkeit, einen Timer unter Assembler einzusetzen? Ich würde die Schleife, die auf Daten von dem Gerät wartet, ganz gerne unterbrechen, wenn nach beispielsweise 2 Sekunden noch keine Daten gesendet worden sind.
...
Du könntest dir ja selbst einen kleinen Timer schreiben. Wie man die Uhrzeit ausliest etc. dürfte man mit Google schnell finden. Oder du nutzt einen fertigen, wie zum Beispiel den Timer der WinAPI. Am einfachsten wäre es aber, eine Schleife zu schreiben, die immer überprüft, ob ein neues Zeichen da ist, und nur dann vom Port liest, wenn ein neue Wert vorhanden ist.
Am einfachsten wäre es aber, eine Schleife zu schreiben, die immer überprüft, ob ein neues Zeichen da ist, und nur dann vom Port liest, wenn ein neue Wert vorhanden ist.
...
Das habe ich ja getan. Die Schleife bricht im Moment nur dann ab, wenn 14 Bytes von dem Gerät empfangen wurden (14 hängt mit dem Datenformat des Multimeters zusammen). Aber es kann ja auch vorkommen, dass das Gerät aus irgendeinem Grund nichts sendet, dann muss die Schleife nach einer gewissen Zeit auch abgebrochen und eine Fehlermeldung ausgegeben werden. Dafür brauche ich den Timer.
Naja, ich werde einfach mal suchen, dafür gibt es sicher fertige DOS-Interrupts, die man aufrufen kann. Aber nicht mehr heute. ^^
Ich habe das von Crash-Override gepostete Programm mal ausprobiert und festgestellt, dass das Gerät funktioniert. Man sendet ein großes "D" und das Gerät gibt die derzeitige Messwertanzeige zurück.
Mein Programm funktioniert allerdings nicht, es gibt nichts aus und wird einfach kurz nach dem Start beendet (nichteinmal eine halbe Sekunde). Ich habe keine Ahnung, wo der Fehler liegt.
Die Empfangsschleife wird mehrfach durchlaufen, dass habe ich schon überprüft. Genaueres kann ich nicht sagen, da das Gerät in der Schule steht und ich es hier (zuhause) nicht testen kann.
Nachtrag:
Ok, ich habe bei der Initialisierung vergessen, die Interrupts richtig einzustellen, das habe ich jetzt geändert (allerdings nicht im obigen Quelltext). Ich werde es morgen erstmal ausprobieren.
Nachtrag #2:
Es hat zwar noch nicht funktioniert, aber ich bin auf dem richtigen Weg. ^^
Ich habe jetzt verschiedene Fehler beseitigt, aber das Programm läuft immernoch nicht. Irgendwas stimmt noch nicht. Ich überprüfe im Programm den Status der seriellen Schnittstelle und bekomme einen Apostroph raus (ASCII-Codierung des Statusbytes). Allerdings gibt es im ASCII-Zeichensatz 4 oder 5 verschiedene Apostrophen, die in meinen Augen alle relativ gleich aussehen, aber eben durch unterschiedliche Bitkombinationen codiert werden. Weiß zufällig jemand, wie ich die einzelnen Bits eines Bytes direkt ausgeben kann?
Ja, ich bin tatsächlich skrupellos genug für einen tripple post.
Nachtrag:
Oh, vergesst es, ist nicht so wichtig. 3 der 5 möglichen Zeichen fallen raus, weil das höchste Bit, das eigentlich immer 0 ist, dann 1 sein müsste. Es gibt also noch zwei mögliche Statusmöglichkeiten:
00100111 >> Daten vorhanden, Überlauf, Paritätsfehler, Senderegister enthält noch Daten
01100000 >> Senderegister enthält noch Daten / sendet gerade Daten
Zu deiner Frage nach den einzelnen Bits abfragen ... sowas macht man idR mit AND und einer Konstanten.
Das AND wird bitweise auf die ganze Zahl angewendet.
Zur Erinnerung: 0 AND 0 = 0, 1 AND 0 = 0; 0 AND 1 = 0; 1 AND 1 = 1
Wenn die verwendete Konstante nun gerade die Zweierpotenz ist, die dein Bit repraesentiert (z.B. 1 SHL 5 = 32 = 00100000b = nur bit 5 gesetzt [merke nullindexiert]) und man diese Konstante mit der Zahl AND verknuepft, dann kommt nur dann ein Ergebniss ungleich 0 raus, wenn das entsprechende Bit gesetzt ist.
10110110b AND 00100000b
00100000b
01011010b AND 00100000b
00000000b
Das geht natuerlich auch, wenn du mehere Bits gleichzeitig abfragen willst. Hierbei treten dann 3 verschiedenen Faelle ein
a) Zahl AND Konstante == Konstante -> alle Bits aus Konstante sind gesetzt
b) Zahl AND Konstante != 0 -> mindestens ein Bit stimmt ueberein, Wert sind die uebereinstimmenden Bits
c) Zahl AND Konstante == 0 -> keines der Bits ist gesetzt.
Und um die Sache komplett zu machen: mit OR kann man Bits in einem Wert setzen und mit XOR abwechselnd an und aus stellen.
Joa, die AND-Verknüpfung wende ich in meinem Programm auch mehrfach an. Meine Frage war eher, wie man ein Byte, also zum Beispiel irgendein Statusregister, das einen interessiert, in Form von Einsen und Nullen auf dem Bildschirm ausgeben kann. Ich habe nur Möglichkeiten gefunden, ASCII-Zeichen auszugeben, die durch die Kombination aus Einsen und Nullen im auszugebenden Byte codiert sind.
Ich gebe also das Register, das ich betrachten will, als ASCII-Zeichen aus und erhalte ein Apostroph (oder irgendwas in der Art). Das Problem war nur, dass ich zwischen "acute accent", "accent grave", dem Apostroph, "left single quotation mark" und "right single quotation mark" keinen großen Unterschied entdecken konnte, zumindest nicht in der von DOS verwendeten Schriftart.
Das Problem hat sich aber inzwischen gelöst. Ich muss das Programm ja bloß mit DEBUG Schritt für Schritt ausführen lassen und prüfen, welcher Wert im jeweiligen Register steht.
Hier ist mal der aktuelle Quelltext. Ich habe keine Ahnung, warum es nicht funktioniert.
Ach ja, das Gerät hat nur die Anschlüsse TxD (Senden), RxD (Empfangen), GND (Erdung/Masse), RTS (Request-To-Send, PC will Daten empfangen) und DTR (Data-Terminal-Ready, PC signalisiert, dass er eingeschaltet ist).
Wegen der Binaerausgabe ...
Wenn du die einzelnen Bits abfragen kannst, kannst du auch entsprechend eine Kette von Einsen und Nullen auf dem Bildschirm ausgeben. Eine Nette moeglichkeit waere beispielsweise ein Right Shift oder Right Rotate, wobei das ausgeschobene Bit ins Carryflag kommt. Dann koenntest du sowas machen ...
Wie du die Unterprogramme/Makros zum Ausgeben der Buchstaben machst, solltest du eigentlich wissen ...
Aus irgendeinem Grund hat es sich mein Programm anders überlegt und funktioniert jetzt, dabei bin ich der Meinung, nichts gemacht zu haben. Falls es jemanden interessiert ist hier nochmal der Quelltext des funktionierenden Programms. Es ist zwar sehr speziell an diese eine Aufgabe angepasst, aber mit ausreichend Kommentaren versehen, so dass man es mit ein paar Veränderungen auch für andere Aufgaben umschreiben könnte.
Jetzt versuche ich noch, das Ganze interruptgesteuert ablaufen zu lassen, das wäre natürlich etwas eleganter. Um das Ganze zu testen habe ich erstmal versucht, bei Tastatureingabe bzw. dem entsprechenden Interrupt eine bestimmte Aktion auszuführen, aber irgendwie funktioniert es nicht. Weiß vielleicht jemand, woran es liegen könnte? Ich habe inzwischen rausgefunden, dass offensichtlich irgendwas schiefläuft, während ich die Speicheradresse meiner Interrupt-Service-Routine in die Interrupt-Vektor-Tabelle schreibe. Es funktioniert aber auch nicht, wenn ich die vorgefertigten Funktionen dafür benutze, das habe ich schon ausprobiert.