Forum: PC-Programmierung COM-Port richtig initialisieren


von Der A. (der-albi)


Lesenswert?

Hallo.
Ich bin gerade dabei eine Verbindung von meinem AVR zu meinem PC 
aufzubauen. Funktioniert auch fast soweit...

Mein Problem ist, dass ich vorher erst das Hyperterminal öffnen muss.. 
nur dann kommt auch in meinem Programm die Verbindung richtig zu Stande.
Ich vermute daher, dass Hyperterminal irgendwas mit dem COM-Port macht.

Ich hole mir bis jetzt den COM-Status über GetCommState, dann setze ich 
Baudrate, Stopbits usw. und schreibe die veränderte Struktur wieder mit 
SetCommState zurück.

Was macht Hyperterminal mehr, als ich?? Weiß das jemand? Bzw kennt 
jemand das Phänomen? Ich hab ja schon diverse Quellen im INet 
durchsucht.. aber mehr als S(G)etCommState wird da auch nicht wirklich 
aufgerufen.

MFG

von René K. (king)


Lesenswert?

> Was macht Hyperterminal mehr, als ich??

Hyperterminal initialisiert den Port, Du nicht (oder eben nur 
teilweise). Gehe den DCB von oben bis unten durch und initialisiere ihn 
vollständig. Die einzelnen Felder sind gut dokumentiert, deswegen ist 
das auch kein Problem (aber etwas Fleiß-Arbeit).

Es reicht nicht, nur die Baudrate umzusetzen. Da gibt es noch so Sachen 
wie Flow-Control, Handshaking usw.. Wie das genau auszusehen hat, kannst 
nur Du allein Wissen. Dieses Wissen mußt Du an das System weitergeben!

GetCommState belegt Dir den DCB mit den Werten, die das vorherige 
Programm nach der Initialisierung hinterlassen hat (deswegen 
funktioniert es nachdem Du das Terminal offen hattest). Auf diese Werte 
kannst Du Dich, wie Du es gerade herausgefunden hast, nicht verlassen.

Also: Immer vollständig initialisieren.

von Franko P. (sgssn)


Lesenswert?

Hi

irgendwas stimmt da aber nicht. Wenn Hyperterminal z.B. den COM1 öffnet, 
kann ein anderes Programm nicht mehr darauf zugreifen. zumindest nicht 
Legal (Legal aus Sicht von Windows). Ich denke mal, "der Albi" du hast 
das öffnen des COM-Ports vergessen.

Gerhard

von Der A. (der-albi)


Lesenswert?

Der Com-Port wird natürlich geöffnet... welches Handle sollte ich sonst 
bei ReadFile angeben ;)
Und es liegt auch nicht an der uninitalisierten DCB-Struktur. Die 
vorgeschlagenen Maßmahmen hatte ich alle bereits getroffen, um zu 
prüfen, an was es liegen könnte. Das ging sogar so weit, dass ich eine 
funktionierende DCB-Struktur in eine Datei abgespeichert hatte, um diese 
nach einem Neustart wieder zu laden. Doch auch das hat nicht wirklich 
viel gebracht.

Mein Frage zielte eigentlich darauf ab, ob unbedingt noch mehr als 
SetCommState nötig ist. Es gibt ja noch eine (kleine) Menge weiterer 
Comm-Funktionen. Doch habe ich in keinem COM-Initialisierungsbeispiel 
bisher diese Funktionen gesehen. Und die Dokumentationen dazu geben mir 
eigentlich auch nicht das Gefühl, dass ich dem Fehler auf der Spur 
bin...

MFG

von René K. (king)


Lesenswert?

Wenn Du den Port vollständig initialisierst, brauchst Du GetCommState 
nicht. Das ist jetzt bei Dir der Fall, verstehe ich das richtig?

Ansonsten mußt Du den Fehler 'geht nicht' etwas besser erläutern. 
Welchen Fehler liefert denn ReadFile (nach dem Fehlschlag GetLastError 
aufrufen)?

Du könntest natürlich auch ein Code-Schnippsel liefern, damit wir da mal 
drüberschauen können. Hellsehen kann hier nämlich keiner (glaube ich 
jedenfalls).

Eine Möglichkeit fällt mir gerade noch ein: Die fehlende Initialisierung 
der TimeOuts. Oder ist das sowieso hinfällig, da Du den Port OVERLAPPED 
öffnest?

von Der A. (der-albi)


Lesenswert?

Zum Öffnen:

ComInterface = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, 
OPEN_EXISTING, 0, NULL);
if (ComInterface == INVALID_HANDLE_VALUE) return false;
DCB dcb = {0};
if (!GetCommState(ComInterface, &dcb)) return false;
//dcb initialiserien, verändern, oder aus Datei laden
if (!SetCommState(ComInterface, &dcb)) return false;
return true;

Das Lesen erfolgt dann in einer Endlosschleife, die das Gelesene 
analysiert.
Das ReadFile schlägt aber nicht fehl... es ließt nur halt nur "Mist" 
d.h. es fehlt manchmal etwas vom String, sodass es nicht ausgewertet 
werden kann.
Die Daten vom AVR werden immer im gleichen Zeitintervall gesendet.
Für mich persönlich würde es naheliegen, zu sagen, dass ich gerade 
einfach mal in einem ungünstigen Moment lese und der String einfach noch 
nicht komplett da ist... doch es spricht dagegen, dass es nach einer 
Hyperterminalbenutzung sehr gut funktoiniert und seht wohl immer alles 
da ist, was da sein soll.

Das mit den TimeOuts interessiert mich. Verändern die das Verhalten des 
COM-Ports? und wenn ja, wie?

MFG

von Blackbird (Gast)


Lesenswert?

ReadBuffer-Länge setzen, Timeouts setzen - ist in der MSDN gut 
beschrieben.
Gelesen wird nicht einfach per Polling, sondern nur wenn was angekommen 
ist per Event. Ist auch in der MSDN beschrieben.

Blackbird

von Christian R. (supachris)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.