RS-232 Daten senden und empfangen



  • Hallo,

    bin in C++ relativ unerfahren. Und hab auch gesehen, dass es schon ein paar Artikel zu dem Thema gibt. Die haben mir aber leider nicht sehr weitergeholfen.
    Versuche die Kommunikation zwischen einem Endgerät und meinem PC hin zu bekommen. Das Problem ist allerdings, das die Kommunikation zwischen den beiden Geräten zufällig abläuft. D.h.: mal sendet das Gerät an den PC, mal andersrum, allerdings nicht zwingend abwechselnd.

    Ich hab die Kommunikation bisher in die eine ODER die andere Richtung hingekriegt. Wie realisiere ich jetzt allerdings, dass Signale die zum PC kommen registriert werden, ohne das die RS232 permanent ausgelesen wird? Art Interrupts sind ja unter c++ nicht möglich. Hab was über Threads gelesen, kam da aber auch nicht weiter.

    Mein Code sieht zum einlesen bisher wie folgt aus:

    WaitCommEvent (hCom, &dwEvtMask, &o); // Event mit Empfangssignalen verknüpfen
    
    	if (WAIT_OBJECT_0 == WaitForSingleObject (o.hEvent, INFINITE)) // warten bis Event
    		{
    		 if (dwEvtMask & EV_RXCHAR) // Zeichen an RxD empfangen:
    			{
    			 bRet = ReadFile (hCom, &InString, sizeof (InString), &dwRead, NULL);
    
    						if (!bRet)
    							{ // Fehlerausgabe:
    							   cout<<"Fehler aufgetreten!"<<endl;
    							}
    						else
    							{ // Ausgabe (oder Verarbeitung) der empfangenen Bytes:
    								InString[dwRead] = '\0';
    								printf (TEXT("\r\n\tRxD (%d Byte(s)): %s"), dwRead, InString);
    								WriteFile (hCom, &InString, dwRead, &iBytesWritten, &o); // Senden eines Bytes
    								cout<<"Folgenden Text empfangen: "<<InString[1]<<endl;
    							}
    						}
    				}
    

    Zum auslesen:

    cout<<"Was soll gesendet werden?"<<endl;
    		cin>>Buchstabe;
    		int String[1] = {Buchstabe};
    		WriteFile (hCom, &String, 1, &iBytesWritten, &o); // Senden eines Bytes
    

    Initialiseren tu ich das ganze wie folgt:

    DCB dcb;
    	DWORD			iBytesWritten;
    	BOOL			bRet      = true;
    	DWORD			dwRead    = 0;
    	DWORD			dwSetMask = EV_RXCHAR | EV_ERR;
    	DWORD			dwEvtMask;
    	OVERLAPPED		o;
    	float			Entscheider;
    	unsigned char	InString[COM_BUFFER_SIZE + 1];
    	char			Buchstabe;
    	float			i;
    
    	memset (&o, 0, sizeof (OVERLAPPED)); // Struktur mit 0en füllen
    	o.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); // einen Event setzten
    
    	HANDLE hCom = CreateFile ("COM2", GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, &o);                     
    
    	dcb.DCBlength = sizeof(DCB);  // Laenge des Blockes MUSS gesetzt sein!
    	GetCommState (hCom, &dcb);    // COM-Einstellungen holen und aendern
    	dcb.BaudRate  = 9600;      // Baudrate
    	dcb.ByteSize  = 8;            // Datenbits
    	dcb.Parity    = NOPARITY;     // Parität
    	dcb.StopBits  = ONESTOPBIT;   // Stopbits
    	SetCommState (hCom, &dcb);    // COM-Einstellungen speichern
    
    	// Zwischenspeicher des serial-Drivers einstellen (für read und write):
    	SetupComm (hCom, COM_BUFFER_SIZE, COM_BUFFER_SIZE);
    
    	SetCommMask (hCom, dwSetMask); // Empfangssignale definieren
    

    Vielen Dank
    Grüße



  • Auf www.codeproject.com findest Du eine Klasse CSerial oder auch CSerialMFC. Die bindest Du in Dein Projekt ein. Es gibt hier schon einige Threads dazu. Wenn Du was an das Gerät senden willst so gibt es dafür eine Funktion, sendet Dein Gerät etwas an den Rechner wird eine Windows-Nachricht generiert, auf die Du dann in einer Nachrichtenbehandlungsroutine reagieren kannst. Du brauchst Dich da nicht auf ein permanentes Abfragen der Schnittstelle zu konzentrieren, auch der zusätzliche Thread wird von dieser Klasse gekapselt. Wenn Du nicht weiter kommst melde Dich einfach.



  • Du brauchst einen eigenen Thread um die Daten zu empfangen.
    Ich empfehle (mal wieder) die Verwendung einer fertigen Klasse, da die serielle Kommunikation wirklich nicht trivial ist (wie Du ja selber festgestellt hast):
    http://www.codeproject.com/system/serial.asp


Anmelden zum Antworten