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.


Anmelden zum Antworten