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