Forum: PC-Programmierung RS232: Fehler beim Lesen; nur wenn schon Daten gesendet werden


von franzi (Gast)


Lesenswert?

Hallo,

habe es geschafft meine RS232-Schnittstelle zu öffnen und Daten 
einzulesen, jetzt habe ich aber noch folgendes Problem:

die Schnittstelle kann ich jederzeit öffnen, auch wenn noch keine Daten 
gesendet werden, wenn die Schnittstelle offen ist und dann erst anfange 
Daten über diese zu senden, dann zeigt er mir an, das er nicht lesen 
kann.
werden aber daten schon gesendet und ich öffne die Schnittstelle, dann 
kann er sie lesen.

hier ein teil meines programms:


Die Funktionen:

// Initialisieren der Schnittstelle
void rs232::rs_init()
{
  cout << "Portnr.: ";
  cin >> portnr;

  cout << "Baudrate: ";
  cin >> baudrate;
}


// Öffnen der Schnittstelle
int rs232::rs_open()
{
  TCHAR portcom[10];

  wsprintf(portcom, Z("COM%d"), portnr);

  hComm = CreateFile( portcom,
            GENERIC_READ,
            0,
            0,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            0);

  if (hComm == INVALID_HANDLE_VALUE)
  {
    cout << "Fehler beim Oeffnen des Ports\n";
    return FALSE;
  }

  GetCommState(hComm, &dcb);
  dcb.BaudRate = baudrate;
  dcb.ByteSize = 8;
  dcb.Parity = NOPARITY;
  dcb.StopBits = ONESTOPBIT;
  SetCommState(hComm, &dcb);

  GetCommTimeouts(hComm, &to);
  to.ReadIntervalTimeout = 0;
  to.ReadTotalTimeoutMultiplier = 0;
  to.ReadTotalTimeoutConstant = 0;
  SetCommTimeouts(hComm, &to);

  return TRUE;
}

// Schließen der Schnittstelle
void rs232::rs_close()
{
  CloseHandle(hComm);
}


// Einlesen der Schnittstelle
unsigned char rs232::rs_read()
{
  unsigned char receive_data = 0;

  DWORD buffer = 0;
  BOOL result = FALSE;

  if (&rs232::rs_open==FALSE)
  {
    cout << "Schnittstelle nicht bereit!\n";
    return 0;
  }

  result=ReadFile(hComm, (LPVOID)&receive_data, 1, &buffer, 0);

  if(result==FALSE)
  {
    cout << "Error!\n";
    exit (0);
  }
  else
    return receive_data;
}


Teil des Hauptprogramms:

#include "receiver_klassen.h"

void main()
{
  rs232 my_rs;
  data my_data;

  int open;
  int block = SYNCHRON1;
  int i;
  int f;
  unsigned char receive_data;
  unsigned short length;

  my_rs.rs_init();
  open = my_rs.rs_open();

  if (open==TRUE)
    cout << "Schnittstelle bereit!\n\n";
  else
  {
    cout << "Schnittstelle nicht bereit!\n";
    exit(1);
  }

  //Endlosschleife
  for( ; ; )
  {
    switch (block)
    {
    case SYNCHRON1:                          //Synchronisationsblock 
Teil1
      if (my_rs.rs_read()==165)
        block = SYNCHRON2;
      break;
...

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Du setzt die Timeouts, d.h die Zeit, die maximal gewartet wird, ob Daten 
vorliegen auf 0. Wenn keine da sind kehrt die Funktion sofort zurück und 
gibt dir nätürlich die Info, dass nichts da ist.

So weit ich das sehe sollte für deinen Fall der Timeout auf unendlich 
stehen, damit das lesen solange blockiert, bis auch wirklich Daten 
vorliegen und die Funktion erst dann zurückkehrt.

Die genauen Parameter findest du in der Hilfe zu SetCommTimeouts()

von franzi (Gast)


Lesenswert?

aha und wie setzt man einen Wert am besten auf unendlich???

reicht dafür dann nur das ReadIntervallTimeout oder müssen die anderen 
dann auch auf unendlich gesetzt werden???

von Berti (Gast)


Lesenswert?

Hi franzi,

Du hast die Timeouts schon korrekt gesetzt. Laut MSDN blockiert 
ReadFile, wenn alle drei Read...Timeouts auf 0 gesetzt werden.
Du schreibst "...dann zeigt er mir an, das er nicht lesen kann.". Was 
heißt das denn genau? Bekommst Du 'ne Fehlermeldung? Falls ja, dann 
solltest Du den Fehler mit GetLastError() genauer eingrenzen:
...
  if(result==0)
  {
    cout << "Error!\n";
    cout << "Windows-Fehlernummer:" << GetLastError() <<"\n";
  }

Im Übrigen erscheint mir die Zeile
"if (&rs232::rs_open==FALSE)"
recht kurios, denn die prüft eigentlich nur, ob die Funktion "rs_open" 
vorhanden ist. Ist das so gewollt? (ist eh immer true)

Gruß,

von Curby (Gast)


Lesenswert?

Ich greif das mal auf.
Ich habe alle Timeouts auf 0 gesetzt und Versuche von einer seriellen 
Schnittstelle ein Byte zu empfangen, an dieser gar nichts angeschlossen 
ist.

Nun soll das Ding sofort abbrechen, wenn nichts empfangen wird, es 
wartet aber scheinbar unendlich lange, also es passiert nix.

Was kann man da tun?

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.