mikrocontroller.net

Forum: PC-Programmierung Win API - ReadFile liest nichts von COM


Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche grade verzweifelt etwas vom COM Port zu lesen. Problem 
dabei ist, dass das nicht blockend sein darf, sprich er soll einfach den 
Kram den er im Puffer hat zurück geben und fertig. Momentan gibt die 
ReadFile Funktion nen Fehler zurück, GetLastError() sagt dann jedoch 
ERROR_IO_PENDING, also alles OK. Nur steht in der Variable wo die Anzahl 
der gelesenen Bytes drin steht 0 drin.
Hier mein zusammengefasstes Programm:
  this->HCom=CreateFileA(Port.toStdString().c_str(), GENERIC_READ | GENERIC_WRITE , 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
  if(this->HCom==INVALID_HANDLE_VALUE)
    return CREATEFILE;
  if(!SetupComm(this->HCom, 4096, 4096))
    return SETUPCOMM;
  if(!PurgeComm(this->HCom, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR))
    return PURGECOMM;
  if(!GetCommState(this->HCom, &DCBstruct))
    return GETCOMMSTATE;
  QString CommDCBStr=Port+": baud="+Baud+" parity=N data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off";
  if(!BuildCommDCBA(CommDCBStr.toStdString().c_str(), &this->DCBstruct))
    return BUILDCOMMDCB;
  //this->DCBstruct.fDtrControl=0x02;
  if(!SetCommState(this->HCom, &this->DCBstruct))
    return SETCOMMSTATE;
Und dann noch das lesen:
int ComPort::read(char *Data, int toRead)
{
  DWORD Readed=0;
  overlappedRead.Offset=0;
  overlappedRead.OffsetHigh=0;
  overlappedRead.Pointer=NULL;
  overlappedRead.hEvent=0;
  ReadFile(this->HCom, Data, toRead, &Readed, &overlappedRead);
  if(GetLastError()==ERROR_IO_PENDING)
  {
    return Readed;
  }
  return -1;
}

Autor: Fabian S. (jacky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habs nun mit Timeouts gelöst:
  COMMTIMEOUTS timeouts;
  if(!GetCommTimeouts(this->HCom, &timeouts))
    return SETCOMMTIMEOUTS;
  timeouts.ReadIntervalTimeout=0;
  timeouts.ReadTotalTimeoutMultiplier=0;
  timeouts.ReadTotalTimeoutConstant=1;
  timeouts.WriteTotalTimeoutMultiplier=0;
  timeouts.WriteTotalTimeoutConstant=0;
  SetCommTimeouts(this->HCom, &timeouts);

Autor: Reinhard R. (reinhardr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

alternativ kannst du auch mit der Funktion "ClearCommError" ein 
"COMSTAT" struct erhalten, welches in der Membervariable "cbInQue" die 
Anzahl der Zeichen im Eingangspuffer enthält. Wenn du dann beim 
Lesevorgang nicht mehr Zeichen einließt wird die Funktion vollständig 
aus dem Puffer bedient und wartet nicht auf weitere Zeichen oder 
Timeouts.
Ich habe das bei einem Gerät, dass immer 24byte große Frames verschickt, 
so gemacht dass ich immer nur ganzzahlige Vielfache von 24byte einlese. 
Dadurch werden keine unvollständigen Frames eingelesen, die man nachher 
wieder getrennt behandeln müsste.

Reinhard

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.