mikrocontroller.net

Forum: PC-Programmierung Datenempfang RS232 mit C++


Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

folgendes Problem:
Ich sende mit einem AVR ATmega16 (mit externem Quarz ohne Beschaltung
direkt angeschlossen) per serieller Schnittstelle einzelne Bytes, im
Abstand von einer einstellbaren Pausenzeit.

Diese Daten kommen auch am PC an, werden also im Terminalprogramm
richtig angezeigt.

Nun möchte ich diese Daten in mit einem C++ Programm verwenden. Also
einfach nur: immer wenn ein Byte auf der RS232 ankommt, soll das
Programm es aufnehmen und speichern.


Ich habe dazu ein Programm geschrieben, was genau diese Aufgabe auch
erfüllt. (siehe empfangenPC.cpp im Anhang zum Beitrag)

ABER:

Das klappt nur, wenn die Bytes in großem zeitlichen Abstand ankommen.
Wenn ich den Abstand verringere, sind die empfangenen Bytes nur
manchmal richtig, bei sehr kleinem Abstand fast immer falsch. Es werden
also falsche Zahlen abgespeichert und ausgegeben.
Damit meine ich nicht die Veränderung der Baudrate!! Bei 1200 und 9600
Baud tritt derselbe Fehler auf, wobei im Terminalprogramm immer alles
richtig ankommt.

Hat jemand eine Idee, woran das liegen könnte?

Ich habe scheinbar noch nicht alles verstanden, eingefallen ist mir
nur, folgende Befehle in verschiedenen Kombinationen mit einzufügen
(teilweise gefunden bei der Forenrecherche), was aber bisher alles
nicht zum Erfolg führte:

------------
SetCommMask (com1port, EV_RXCHAR);
------------
//if (WaitCommEvent(com1port, &dwCom1Status, 0))
//{
//  ReadFile (com1port, txt, 1, &bytes_read, NULL);
//}
------------
ClearCommError(com1port, &dwError, NULL);
if (WaitCommEvent(com1port,&dwCom1Status, NULL))
{
    ReadFile (com1port, txt, 1, &bytes_read, NULL);
}
else
  cout << "\nFehler bei WaitCommEvent";
break;
------------
//if (dwCom1Status & EV_RXCHAR)
//{
//    ReadFile (com1port, txt, 1, &bytes_read, NULL);
//}


Ich würde mich sehr freuen, wenn mir jemand einen Tipp geben kann.

Vielen Dank!
Martin

Autor: AndreasH (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiss jetzt ohne nachzusehen nicht was das:
COMMTIMEOUTS timeouts = {0,0,0,0,0};
macht.

Ich vermute mal ohne Timeout das ganze ablaufen lassen.
Das kann nicht funktionieren.

Wenn Dein Programm startet und der Controller sendet, das ist Zufall
wenn das übereinstimmt.

Zum Testen mach einfach mal folgendes.

Timeout mal auf 1/2 oder 1 Sekunde setzen.

Solange Schnittstelle abfragen bis das erste Zeichen gekommen ist.
Dann die restlichen 4 Zeichen einlesen.
Wenn es dan geht, kannst Du die Timeoutzeit immer noch runter setzen.
Wobei das egal ist. Die ist nur dann wichtig, wenn kein Zeichen kommt.
Sobald eins gekommen ist, kommt Readfile sowieso zurück.
Du müsstest dann nur einen Abbruch während dem Warten auf dem ersten
Zeichen ermöglichen.

Ich vermute, dass es dann geht.
Wenn es Commtimeouts auf unendlich steht dann vergiss das ganze.

Grüße
Andreas

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.