Hi zusammen, Ich hab' mal wieder ein weiteres Problem mit der RS232. Ich möchte mit VS 2005 unter Vista ein Programm schreiben, das Daten über die Rs sendet und empfängt. Und zwar "Overlapped". Das Lesen ist kein Problem. das Funktioniert einwandfrei. Nur mit dem Schreiben hab' ich ein Problem. Wenn ich WriteFile() aufruf, kommt sie gleich mit false zurück, wie sie das auch soll und was verständlich ist, da sie auch nicht zaubern kann. Danach prüfe ich mit "GetLastError()" ob die Schnittstelle noch am Senden ist. Das liefert mir dann auch immer ERROR_IO_PENDING zurück. Dann warte ich mit WaitForSingleObject() darauf, dass das Event gesetzt wird. Wenn das passiert ist, müsste ja alles klar sein. Aber die Variable, in die WriteFile() schreibt, ist dann immer noch "0". Und es sind auch keine Daten aus der Schnittstelle herausbekommen. Hier ist erstmal das öffnen des Ports: ------------------------------------------------------------------------ -- HANDLE Port::OpenPort(char* s1) { OVERLAPPED sOverlapped; OVERLAPPED sOverlapped_W; HANDLE hEvent; HANDLE hEvent_W; HANDLE hComm; DCB sDcb; //Overlapped-Struct löschen, wie von Microsoft empfohlen ZeroMemory(&sOverlapped,sizeof(OVERLAPPED)); ZeroMemory(&sOverlapped_W,sizeof(OVERLAPPED)); //Events erstellen sOverlapped.hEvent = CreateEvent(NULL,false,false,NULL); sOverlapped_W.hEvent = CreateEvent(NULL,true,false,NULL); hComm = INVALID_HANDLE_VALUE; //Port öffnen hComm = CreateFileA(s1,GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); GetCommState(hPort,&sDcb); //Parameter anpassen (komplett ohne Handshake) sDcb.BaudRate = CBR_38400; sDcb.ByteSize = 8; sDcb.Parity = NOPARITY; sDcb.fParity = false; sDcb.fDsrSensitivity = false; sDcb.StopBits = ONESTOPBIT; sDcb.fDtrControl = DTR_CONTROL_DISABLE; sDcb.fRtsControl = RTS_CONTROL_DISABLE; sDcb.fNull = true; SetCommState(hPort,&sDcb); } Und hier nun meine Funktion zum Senden: ------------------------------------------------------------------------ --- int Port::Send(char *buffer, int iBytesToWrite) DWORD dwBytesWritten = 0; if(WriteFile(hPort, buffer, iBytesToWrite, &dwBytesWritten, &sOverlapped_W)) { return dwBytesWritten; } else { if(ERROR_IO_PENDING == GetLastError()) { //Ist noch am Senden... cout << "Braucht Noch" << endl; if(WAIT_OBJECT_0 == WaitForSingleObject(sOverlapped_W.hEvent,1000)) { //Jetzt wurde der Event gesetzt //Hier kommt das Programm auch immer an cout << "Müsste gesendet haben" << endl; //Problem!!!!!!!!!!!!!!1!!!! //Jetzt hat aber "dwBytesWritten" den Wert 0 return dwBytesWritten; //Problem!!!!!!!!!!!!!!!!!!!! } else { cout << "Timeout 1000ms" << endl; } } else { cout << "Es ist ein Fehler aufgetreten" << endl; return 0; } } } ------------------------------------------------------------------------ --- So steht's auch im MSDN. Darum hab' ich keine Ahnung, was ich noch vergessen oder falsch gemacht hab'. Falls ihr noch was wissen müsst, sagt bitte bescheid. Wär euch dankbar, wenn mir einer von euch "Cracks" :-) helfen könnte. Danke schon mal
Du musst noch die Funktion GetOverlappedResult aufrufen, sonst wird Dein dwBytesWritten nie verändert.
Benutz mal GetOverlappedResult um die echt geschiebene Bytezahl zu bekommen http://msdn2.microsoft.com/en-us/library/ms683209(VS.85).aspx Edit: Zu langsam, aber immerhin mit Link ;)
Hey Danke, das ging ja schnell. Ok, hab's gemacht. Jetzt passt's. Muss nur noch rausfinden ob wirklich was gesendet wird. Dann hätt ich nur noch ne Verständnisfrage: Wenn ich WriteFile() ohne Overlapped aufrufe dann schreibt es ja auch in die Variable. Macht sie des in meinem Beispiel nur wegen dem Overlapped nicht? Nochmals vielen Dank
Direkt aus der M$-Doku zu WriteFile:
1 | "If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. |
2 | If this is an overlapped write operation, you can get the number |
3 | of bytes written by calling GetOverlappedResult." |
CU
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.