Forum: PC-Programmierung Probleme Kommunikation mit COM-Port


von Visitor (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich bin dabei mir ein kleines Progamm schreiben, um mit dem PC über die 
serielle Schnittstelle mit einem AVR zu kommunizieren.

Programmiersprache C++,
Verwendeter Compiler Microsoft Visual C++ 4.2 (ich weiß, ziemlich alt).
Betriebssystem Windows 7.

Die Verbindung mit dem COM3-Port wird NON-OVERLAPPED in dem 
Unterprogramma "afx_msg void WinRS232::CmConnectRS232()" hergestellt. 
Das gesamte Programm befindet sich im Anhang.

Mein Problem ist folgender Programmteil:

//***************************************************************
afx_msg void WinRS232::CmRead()
//***************************************************************
{
  ButtonRead->EnableWindow(FALSE);
  int Flag = 0;
  memset(BufferRead, 0, 100);
  for(;;)
  {
    if(WaitCommEvent(h_Com, &dwEventMask, NULL) == TRUE)
    {
      ReadFile(h_Com, BufferRead, 100, &NumBytesRead, NULL);
      Flag = 1;
    }
    if(Flag == 1)
    {
      EditRead->SetWindowText(BufferRead);
      Flag = 0;
      memset(BufferRead, 0, 100);
      AfxMessageBox("Read OK",MB_OK);
      break;
    }
  }//for
  ButtonRead->EnableWindow(TRUE);
  return;
}
//---------------------------------------------------------------------- 
--------

Dass Unterprogramm wartet nach dem Drücken eines"Read-Buttons" in der 
for-Schleife auf den String vom COM-Port und gibt diesen dann in einem 
Textfeld aus.
Das Programm tut das, was es soll, auch wenn ich zu Testzwecken den 
"break"-Befehl entferne, um sozusagen dauerhaft in einer Endlosschleife 
Strings einlesen und ausgeben zu können. Abgesehen davon daß sich der PC 
in einer Endlosschleife befindet und über den Task-Manager abgeschossen 
werden muß.

Wenn ich allerdings den break- UND den AfxMessageBox-Befehl entferne, 
funktioniert das Programm nicht mehr, d.h. es wird nichts mehr in dem 
Textfeld ausgegeben. Warum ist das so?


Vielen Dank im Voraus.

von Visitor (Gast)


Lesenswert?

Entschuldigung, das Programm wurde zweimal angehängt.

von Nicht"Gast" (Gast)


Lesenswert?

Hi,

das ist ganz einfach. Dein Programm hängt dann in der Schleife fest.
Dadurch kann es nicht mehr auf die Messages reagieren
z.B. auf das Eintragen der Daten in das Textfenster.

Achtung persönliche Meinung: quäl dich nicht länger mit dem alten 
Scheiß. Wenn du unbedingt bei C++ bleiben willst, schau dir mal QT an, 
ansonsten kann ich dir nur den Umstieg auf C# empfehlen. der Einstieg 
fällt ziemlich leicht, wenn man vorher C++ programmiert hat.

grüße

von Visitor (Gast)


Lesenswert?

>Dein Programm hängt dann in der Schleife fest.
>Dadurch kann es nicht mehr auf die Messages reagieren

Nach der Entfernung des Break-Befehls befindet sich das Programm bereits 
in der Endlos-Schleife, reagiert aber trotzdem noch auf die Message.

Erst nach zusätzlichen Entfernung des Meldungsfenster-Befehls reagiert 
das Programm nicht mehr.

>Wenn du unbedingt bei C++ bleiben willst, schau dir mal QT an,

Denkst du, dass das Problem vom Compiler abhängen könnte?

von nicht"Gast" (Gast)


Lesenswert?

Hallo,

Das hängt nicht am Compiler, sondern am MFC Müll. Das hat mit deinem 
Problem eigentlich gar nichts zu tun. Das war nur ein Hinweis, dass du 
dir keinen Gefallen tust, an der veralteten Technik fest zu halten. 
Moderne Frameworks sind deutlich besser aufgebaut.

Ich hab zwar in der MSDN AfxMessageBox gefunden, aber ist die blocking 
oder nonblocking? Wenn sie Blocking ist, dann kann es durchaus sein, 
dass Nachrichten wieder von der Hauptschleife verarbeitet werden. 
(Achtung, an dieser Stelle verbreite ich gefährliches Halbwissen. Meine 
MFC Zeiten sind schon sehr lange vorbei, Gottseidank :) Mögen mich 
andere berichtigen oder bestätigen.

Die korrekte Lösung für dein Problem wäre die serielle Leserei in einem 
separaten Thread laufen zu lassen. Dann wird dein Programm nicht mehr 
blockiert.

In der MSDN hab ich auch noch was gefunden. Vielleicht hilft es dir ja 
weiter.
http://msdn.microsoft.com/en-us/library/ff802693.aspx


Grüße,

von Christian R. (supachris)


Lesenswert?

Auch mit .NET oder anderem wird sich die Endlosschleife so verhalten. 
Mach einen Lese Thread und arbeite dort am besten noch mit overlapped 
Modus und waitforsingleobject(). Bei CodeGuru gibts ein RS232 
Beispielprojekt für MfC.

von nicht"Gast" (Gast)


Lesenswert?

Natürlich, wenn du das genau so programmieren willst.

In .Net kannst du aber der SerialPort Klasse ein Event werfen lassen, 
wenn Daten eintrudeln.

Dort musst du dich dann nicht endlos drin aufhalten, sondern kannst die 
Daten einlesen, verarbeiten und die Methode dann wieder verlassen.

von Visitor (Gast)


Lesenswert?

>Vielleicht hilft es dir ja weiter.
>http://msdn.microsoft.com/en-us/library/ff802693.aspx

Von diesem Artikel habe ich mich zumindest "inspirieren" lassen.


>Die korrekte Lösung für dein Problem wäre die serielle Leserei in einem
>separaten Thread laufen zu lassen. Dann wird dein Programm nicht mehr
>blockiert.

Dann werde ich mich mal damit auseinandersetzten.

Vielen Dank bisher.

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.