Probleme mit Ansteuerung der COMM Schnittstelle
-
Hallo Leute,
möchte an die serielle Schnittstelle paar Daten schicken und habe gemerkt, dass es ohne die winapi nicht so einfach ist. Daher habe ich einen Quellcode gefunden mit dem einfach gehen soll. Alles schön und gut, aber beim Setzen der COMM Parameter liefert er mir einen Fehler. Kann mir einer sagen warum?
Undzwar in Methode Open() im letzen Abschnitt liefert mit SetCommState() false.
Ich weis nur nicht wieso er die Parameter der Struktur dcb nicht in hComm setzen kann.OK: Ich bekomme den Error 87 der für "The parameter is incorrect." steht.
Welchen Parameter hab ich falsch eingegeben?
Aufrufen tue ich es so:Open(1, 9600, 8, 0, 1); SendData((char*)helpstream, 128); Close();
Serial.cpp
BOOL CSerial::Open (int nComPortNr, int nBaud, int nBits, int nParity, int nStopp) { if (INVALID_HANDLE_VALUE != hComm) { return (TRUE); } char szPort[16]; wsprintf (szPort, "\\\\.\\COM%d", nComPortNr); hComm = CreateFile (szPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hComm == INVALID_HANDLE_VALUE) return (FALSE); if (!GetCommTimeouts(hComm, &timeouts_alt)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD ; timeouts.ReadTotalTimeoutMultiplier = MAXDWORD ; timeouts.ReadTotalTimeoutConstant = 3000; // Timeout ist 3000ms timeouts.WriteTotalTimeoutMultiplier = 1000; timeouts.WriteTotalTimeoutConstant = 1000; if (!SetCommTimeouts(hComm, &timeouts)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } DCB dcb; ZeroMemory (&dcb, sizeof(dcb)); dcb.DCBlength = sizeof(DCB); if (!GetCommState (hComm, &dcb)) { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } dcb_alt = dcb; dcb.fBinary = TRUE; // muss immer "TRUE" sein! dcb.fParity = TRUE; dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.fDsrSensitivity = FALSE; dcb.fTXContinueOnXoff = TRUE; dcb.fOutX = FALSE; dcb.fInX = FALSE; dcb.fErrorChar = FALSE; dcb.fNull = FALSE; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.fAbortOnError = FALSE; dcb.wReserved = 0; // muss immer "0" sein! dcb.BaudRate = nBaud; dcb.ByteSize = (BYTE)nBits; dcb.Parity = (BYTE)nParity; dcb.StopBits = (BYTE)nStopp; dcb.fParity = (dcb.Parity != NOPARITY); if (!SetCommState(hComm, &dcb)) //<--------------hier ist mein Problem { DWORD dwError = GetLastError(); Close (); SetLastError(dwError); return (FALSE); } return(TRUE); }
-
JDHawk schrieb:
Alles schön und gut, aber beim Setzen der COMM Parameter liefert er mir einen Fehler. Kann mir einer sagen warum?
Gegenfrage: Wer (Compiler/Linker/laufendes Programm)? und welchen Fehler?
-
Hi.
In der Schleife gibt es ja diese Funktion:GetLastError()
Diese liefert mir 87 -> was für wrong parameter steht.
Weist Du vielleicht welcher Parameter falsch ist?
-
Ok,
klappt. Habe eine 0 und 1 verwechselt. Sorry für die Aufregung.
Man muss die Werte setzen, die bei Windows im Gerätemanager gesetzt sind.
Man kann diese also nicht verändern.Dennoch Danke
-
Ok habe folgendes gemacht:
An einem PC gekreuztes RS232 Kabel an beide COM-Schn.st.
Sender und Empfänger gestartet, und folgendes Phänomen erkannt:Undzwar empfängt mein Empfänger immer das 1.Byte obwohl der Sender noch nicht mal seinen Port geöffnet, geschweige denn gesendet hat.
Als Folge wartet der Empfänger auf das letzte Byte, und es passier ein Timeout.Am Ende klappt zwar alles, aber dennoch wundert mich, dass er das 1.Byte schon hat, bevor der Sender sendet.
Mit einem Portscanner habe ich das erkannt. Dort sieht man, dass der Empfänger das erste Byte 0x01 "Read"ed bevor Serial0 überhaupt mit "Create" sein Port öffnet.
Was kann ich dagegen tun?
-
Die Puffer leeren (purge com heisst das dann glaube ich).
Gruss Simon
-
Danke, hat leider nichts geändert.
Vielleicht habe ich irgendwas falsch eingestellt.
Hier der Ausschnitt der Log Datei, in der man sieht, dass ich in Zeile 18 die Puffer vom Empfänger leere, er dennoch das 1.Byte liest obwohl von Serial 0 noch gar nicht gesendet. in Zeile 38 macht Serial 0 dann mit der 0x7A weiter.0.00007040 rs232.exe IRP_MJ_CREATE Serial1 SUCCESS Options: Open 0.00000419 rs232.exe IOCTL_SERIAL_GET_TIMEOUTS Serial1 SUCCESS 0.00000307 rs232.exe IOCTL_SERIAL_SET_TIMEOUTS Serial1 SUCCESS RI:-1 RM:-1 RC:3000 WM:1000 WC:1000 0.00000251 rs232.exe IOCTL_SERIAL_GET_BAUD_RATE Serial1 SUCCESS 0.00000279 rs232.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial1 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_CHARS Serial1 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_HANDFLOW Serial1 SUCCESS 0.00000223 rs232.exe IOCTL_SERIAL_GET_BAUD_RATE Serial1 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial1 SUCCESS 0.00000223 rs232.exe IOCTL_SERIAL_GET_CHARS Serial1 SUCCESS 0.00000223 rs232.exe IOCTL_SERIAL_GET_HANDFLOW Serial1 SUCCESS 0.00001034 rs232.exe IOCTL_SERIAL_SET_BAUD_RATE Serial1 SUCCESS Rate: 9600 0.00000559 rs232.exe IOCTL_SERIAL_SET_RTS Serial1 SUCCESS 0.00000559 rs232.exe IOCTL_SERIAL_SET_DTR Serial1 SUCCESS 0.00000475 rs232.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial1 SUCCESS StopBits: 1 Parity: ODD WordLength: 8 0.00000279 rs232.exe IOCTL_SERIAL_SET_CHAR Serial1 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13 0.00000419 rs232.exe IOCTL_SERIAL_SET_HANDFLOW Serial1 SUCCESS Shake:1 Replace:80000040 XonLimit:2048 XoffLimit:512 0.00000363 rs232.exe IOCTL_SERIAL_PURGE Serial1 SUCCESS Purge: TXCLEAR RXCLEAR 0.01609255 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 01 0.00008213 rs232.exe IRP_MJ_CREATE Serial0 SUCCESS Options: Open 0.00000475 rs232.exe IOCTL_SERIAL_GET_TIMEOUTS Serial0 SUCCESS 0.00000307 rs232.exe IOCTL_SERIAL_SET_TIMEOUTS Serial0 SUCCESS RI:-1 RM:-1 RC:3000 WM:1000 WC:1000 0.00000251 rs232.exe IOCTL_SERIAL_GET_BAUD_RATE Serial0 SUCCESS 0.00000279 rs232.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial0 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_CHARS Serial0 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_HANDFLOW Serial0 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_BAUD_RATE Serial0 SUCCESS 0.00000223 rs232.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial0 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_CHARS Serial0 SUCCESS 0.00000251 rs232.exe IOCTL_SERIAL_GET_HANDFLOW Serial0 SUCCESS 0.00000978 rs232.exe IOCTL_SERIAL_SET_BAUD_RATE Serial0 SUCCESS Rate: 9600 0.00000587 rs232.exe IOCTL_SERIAL_SET_RTS Serial0 SUCCESS 0.00000559 rs232.exe IOCTL_SERIAL_SET_DTR Serial0 SUCCESS 0.00000447 rs232.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial0 SUCCESS StopBits: 1 Parity: ODD WordLength: 8 0.00000279 rs232.exe IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13 0.00000419 rs232.exe IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake:1 Replace:80000040 XonLimit:2048 XoffLimit:512 0.01734159 rs232.exe IRP_MJ_WRITE Serial0 SUCCESS Length 21: 01 7A 08 00 00 00 00 00 0A D4 31 4D 4F 53 54 31 32 33 34 35 36 0.00001173 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 7A 0.00000447 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 08 0.00000419 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 00 0.00000419 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 00 0.00000391 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 00 0.00000419 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 00 0.00000419 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 00 0.00891733 rs232.exe IRP_MJ_READ Serial1 SUCCESS Length 1: 0A
-
Hat einer einen Vorschlag, wie ich eine Synchronisation zwischen zwei Threads realisieren kann, die beide Senden und Empfangen.
Es soll dabei der eine erst dann lesen, wenn er wirklich was empfängt, also nicht schon vorher, auch wenn er im Programmablauf schneller als der andere ist.