Probleme mit der RS232



  • Hallo Leute,

    ich habe hier ein Problem mit der RS232-Schnittstelle. Ich versuche das schon ne ganze Weile, aber es will einfach nichts senden.

    Zunächst Definitionen:

    #include <termios.h> 
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #define Anschluss	"/dev/ttyS1"	
    #define Baudrate	B38400
    

    Damit wird die Schnittstelle geöffnet, habe ich aus dem Buch von Martin Gräfe.

    int OpenRS232(char device[11], int baudrate) 
    {
    	int devicehandle; 			// Hiermit wird später auf das geöffnete Device zugegriffen
    	int old_flags;
    	struct termios term_attr; 	// hält die Kommunikations-Konfig-Daten
    
    	//erzeugt einen Device-Knoten für das benötigte Interface
    	//Bedingung ist eine Konfiguration des Kanales durch den Kernel.
    	//Falls der Knoten bereits vorhanden ist, gibt es nur eine Meldung. 
    	switch(device[9])
    	{
    		case '0' : system("mknod /dev/ttyS0 c 4 64"); break;
    		case '1' : system("mknod /dev/ttyS1 c 4 65"); break;
    		case '2' : system("mknod /dev/ttyS2 c 4 66"); break;
    		case '3' : system("mknod /dev/ttyS3 c 4 67"); break;
    		case '4' : system("mknod /dev/ttyS4 c 4 68"); break;
    	}
    
    	//RS232-Kanal öffnen (lesen und Schreiben erlaubt)
    	if((devicehandle=open(device, O_RDWR)) == -1)
    	{			
    		perror(device " nicht gefunden, Kernelunterstützung überprüfen!");
    		return(1);
    	}
    
    	//RS232 konfigurieren
    	if(tcgetattr(devicehandle, &term_attr) !=0)
    	{ 
    		perror("Kann Konfiguration nicht lesen. Folgendes Gerät kann nicht inititalisiert werden: " device);
    		return(1);
    	}
    	term_attr.c_cflag = baudrate | CS8 | CRTSCTS | CLOCAL; 	//control-Mode flags
    	term_attr.c_iflag = 0; 									//input-Mode flags
    	term_attr.c_oflag = OPOST | ONLCR; 						//output-Mode flags
    	term_attr.c_lflag = 0; 									//local-Mode flags
    
    	if (tcsetattr(devicehandle, TCSAFLUSH, &term_attr) != 0)
    	{
    		perror("Kann Konfiguration nicht setzen für: " device);
    		return(1);
    	}
    
    	return(devicehandle);
    }
    

    Und damit versuche ich was zu senden:

    int main()
    {
    	int rfidhandle;
    	rfidhandle=OpenRS232(Anschluss,Baudrate);
    	write(rfidhandle, "hallo", 5);
    	CloseDevice(rfidhandle);
    }
    

    Aber irgendwie geht es nicht. Ich habe mir jetzt mal mit nem Oszi die Pegel angesehen. Der TX-Pegel geht einfach nur auf eins und bleibt dort auch nach Beendigung des Programms.

    Ich bin jetzt ziemlich Ratlos. Ist denn meine Initialisierung und der Zugriff generell richtig?

    Danke schonmal,

    Günther



  • Hallo nochmal,

    Ich habe jetzt selbst nochmal gesucht und etwas passendes gefunden. Da leider beide Beispiele nicht sonderlich umfangreich dokumentiert sind, erschließt sich mir jetzt nicht auf Anhieb, warum das eine geht und das andere nicht. Und besonders komisch finde ich, dass das erste Beispiel hier auch in den FAQs ist. Vermutlich hab ich mich irgendwo vertan. Naja egal.

    Also das ist jetzt meine funktionierende Initialisierung, die mir zumindest zu erwartende Signalpegel liefert:

    int OpenRS232(char device[11], int baudrate) 
    {
    	int devicehandle; 			// Hiermit wird später auf das geöffnete Device zugegriffen
    	struct termios options; 	// hält die Kommunikations-Konfig-Daten
    
    	//erzeugt eine Device-Definition für das benötigte Interface
    	//Bedingung ist eine Konfiguration des Kanales durch den Kernel.
    	//Falls die Device-Definition bereits vorhanden ist, gibt es nur eine Meldung. 
    	switch(device[9])
    	{
    		case '0' : system("mknod /dev/ttyS0 c 4 64 >/dev/tty1"); break;
    		case '1' : system("mknod /dev/ttyS1 c 4 65 >/dev/tty1"); break;
    		case '2' : system("mknod /dev/ttyS2 c 4 66 >/dev/tty1"); break;
    		case '3' : system("mknod /dev/ttyS3 c 4 67 >/dev/tty1"); break;
    		case '4' : system("mknod /dev/ttyS4 c 4 68 >/dev/tty1"); break;
    	}
    
    	//RS232-Kanal öffnen (lesen und Schreiben erlaubt)
    	if((devicehandle=open(device, O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1)
    	{			
    		perror(device " nicht gefunden, Kernelunterstützung überprüfen!");
    		return(1);
    	}
    
    	//RS232 konfigurieren
    	if(tcgetattr(devicehandle, &options) !=0)
    	{ 
    		perror("Kann Konfiguration nicht lesen. Folgendes Gerät kann nicht inititalisiert werden: " device);
    		return(1);
    	}
    
    	//setzte baudrate
        cfsetispeed(&options, baudrate);
        cfsetospeed(&options, baudrate);
    
    	//Read und Local setzen
    	options.c_cflag |= (CLOCAL | CREAD);
    
    	//set: 8N1
    	options.c_cflag &= ~PARENB;
    	options.c_cflag &= ~CSTOPB;
    	options.c_cflag &= ~CSIZE;
    	options.c_cflag |= CS8;
    
    	//Disable hardware flowcontrol
    	options.c_cflag &= ~CRTSCTS;
    
    	//Raw data Einlesen
    	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    	options.c_iflag |= IGNPAR;
    	//Software flowcontrol ausschalten
    	options.c_iflag &= ~(IXON | IXOFF | IXANY);
    
    	//Raw Data Ausgabe
    	options.c_oflag &= ~OPOST;
    
    	//Puffer leeren
    	tcflush(devicehandle, TCIFLUSH);
    
    	//Neue Einstellungen auf Port übertagen
    	if (tcsetattr(devicehandle, TCSANOW, &options) != 0)
    	{
    		perror("Kann Konfiguration nicht setzen für: " device);
    		return(1);
    	}
    
    	return(devicehandle);
    }
    

    Vielleicht kann mir je trotzdem mal einer sagen, warum das nicht ging. Ich vermute mal, ich habe mich irgendwo vertippt.

    Danke schonmal immer,

    Günther



  • Die Antwort ist ganz einfach:
    Bei dem ersten Beispiel (aus meinem Buch) wird Hardware-Handshaking (CRTSCTS) eingeschaltet, im zweiten Beispiel wird es dagegen explizit deaktiviert (Zeile 46). Wenn also kein Empfänger angeschlossen ist, der dem PC über die CTS-Leitung Empfangsbereitschaft signalisiert, sendet der PC auch nichts!

    Martin



  • Ah, alles klar. Dann kann es ja nicht gehen. Wieder was gelernt. Stand aber (meines Wissens) nicht im Buch und ist auch im Quelltext nicht dokumentiert. Vielleicht könnte man die FAQ entsprechend erweitern?

    Wie auch immer, ist doch okay so.

    Danke und eine schöne Woche.

    Günther.



  • Hallo nochmal,

    Also ich habe hier ein sehr dubioses Problem. Zunächst mein Code. Hab mal alle Fehlerbehandlung usw. rausgelassen.

    int handle=OpenRS232("/dev/ttyS1", 38400);
    
    unsigned char buffer[1]=0xFF;
    
    printf("Sende %02X\n", buffer[0]); //reelle Ausgabe ist hier: FF
    
    write(handle, buffer, 1);
    
    tcdrain(handle); //warten, bis alles gesendet.
    
    read(handle, buffer, 1);
    
    printf("Empfange %02X\n", buffer[0]); //Ausgabe sollte sein A8, ist aber 28
    
    close(handle);
    

    Also mein Gerät bekommt 0xFF gesendet und müsste laut Datenblatt und Aussage des Supports 0xA8 zurücksenden. In meinem Empfangspuffer liegt aber nur 0x28. Das erste Bit fehlt also.

    Aber warum? Ein Anzeigefehler schließt sich aus, da das 0xFF auch ordentlich angezeigt wird.

    Es sieht ganz so aus, als würden nur 7 Bit gelesen oder in die Variable geschrieben.

    Komisch komisch. Hat jemand ne Idee??? 😕

    Danke, Günther


Anmelden zum Antworten