Moin, ich habe ein Problem. Ich habe einen Hutschienen PC mit einer RS485 Schnittstelle(16550A) an der Schnittstelle hängt ein Elster A1500 Zähler. Wenn ich nun per minicom den Zähler /?! sende geht sein Display aus und er sendet, aber leider kommt am PC nicht an!!! Warum kann per cat /dev/ttyS0 nicht sehen?? Ich habe schon etwas geguckt und es kann an den Flow Controll liegen, schaltet das nicht aber automatisch um? Als System habe ich ein aktuelles Debian installiert. Evtl kann mir ja mal wer einen Tip geben. Lars
So ich bin mal ein Ticken weiter:
1 | #include "stdio.h" |
2 | #include "string.h" |
3 | #include "unistd.h" |
4 | #include "fcntl.h" |
5 | #include "errno.h" |
6 | #include "sys/types.h" |
7 | #include "sys/stat.h" |
8 | #include "stdlib.h" |
9 | #include "stdarg.h" |
10 | #include "termios.h" |
11 | #include "linux/serial.h" |
12 | |
13 | #define TIOCSRS485 0x542F
|
14 | |
15 | int main(void) { |
16 | char txBuffer[10]; |
17 | char rxBuffer[10]; |
18 | int fd; |
19 | struct termios tty_attributes; |
20 | struct serial_rs485 rs485conf; |
21 | |
22 | if ((fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NONBLOCK))<0) { |
23 | fprintf (stderr,"Open error on %s\n", strerror(errno)); |
24 | exit(EXIT_FAILURE); |
25 | } else { |
26 | tcgetattr(fd,&tty_attributes); |
27 | |
28 | // c_cflag
|
29 | // Enable receiver
|
30 | tty_attributes.c_cflag |= CREAD; |
31 | |
32 | // 8 data bit
|
33 | tty_attributes.c_cflag |= CS8; |
34 | |
35 | // c_iflag
|
36 | // Ignore framing errors and parity errors.
|
37 | tty_attributes.c_iflag |= IGNPAR; |
38 | |
39 | // c_lflag
|
40 | // DISABLE canonical mode.
|
41 | // Disables the special characters EOF, EOL, EOL2,
|
42 | // ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.
|
43 | |
44 | // DISABLE this: Echo input characters.
|
45 | tty_attributes.c_lflag &= ~(ICANON); |
46 | |
47 | tty_attributes.c_lflag &= ~(ECHO); |
48 | |
49 | // DISABLE this: If ICANON is also set, the ERASE character erases the preceding input
|
50 | // character, and WERASE erases the preceding word.
|
51 | tty_attributes.c_lflag &= ~(ECHOE); |
52 | |
53 | // DISABLE this: When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal.
|
54 | tty_attributes.c_lflag &= ~(ISIG); |
55 | |
56 | // Minimum number of characters for non-canonical read.
|
57 | tty_attributes.c_cc[VMIN]=1; |
58 | |
59 | // Timeout in deciseconds for non-canonical read.
|
60 | tty_attributes.c_cc[VTIME]=0; |
61 | |
62 | // Set the baud rate
|
63 | cfsetospeed(&tty_attributes,B300); |
64 | cfsetispeed(&tty_attributes,B300); |
65 | |
66 | tcsetattr(fd, TCSANOW, &tty_attributes); |
67 | |
68 | // Set RS485 mode:
|
69 | rs485conf.flags |= SER_RS485_ENABLED; |
70 | if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { |
71 | printf("ioctl error\n"); |
72 | }
|
73 | |
74 | txBuffer[0]='A'; |
75 | write(fd,txBuffer,1); |
76 | |
77 | // Read a char
|
78 | if (read(fd,&rxBuffer,1)==1) { |
79 | printf("%c",rxBuffer[0]); |
80 | printf("\n"); |
81 | }
|
82 | }
|
83 | |
84 | close(fd); |
85 | return EXIT_SUCCESS; |
86 | }
|
Diesen Code habe ich mal getestet, aber leider sagt der: ioctl error Irgendwie lässt sich der 16550A nicht in den Rs485 Mode versetzen.... // Set RS485 mode: rs485conf.flags |= SER_RS485_ENABLED; if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { printf("ioctl error\n"); }
Hast Du folgendes bedacht: RS485 ist ein Bus, und bei der Kommunikation mit dem Elster Zähler wird das diff. Adernpaar für RX und TX benutzt. Das heißt, kurz vor dem Senden muß irgendwie der RS485 Treiber auf TX geschaltet werden, direkt nach dem Senden wieder disabled werden. Sonst hält er den Bus auf einen festen Pegel, und die Antowrt des Zählers kommt nicht an. Sieht bei Dir danach aus - der Zähler reagiert rigendwie, aber Du siehst die Antwort nicht. Sehr oft wird so etwas mit einer Handshake-Leitung gemacht. Versuch doch mal, erst RTS zu setzen, zu senden und direkt danach wieder zurückzusetzen. (Oder umgekehrt) -Schorsch
Lars schrieb: > Irgendwie lässt sich der 16550A nicht in den Rs485 Mode versetzen.... Der 16550 kennt keinen RS485-Mode. Die für den RS485-Betrieb zwingend erforderliche Sender-/Empfänger-Umschaltung musst Du mit Deinem Programm selber vornehmen, was üble Frickelei ist, denn nach dem Absenden von Daten musst Du solange warten, bis diese nicht nur das Hardware-Sende-Fifo des 16550 verlassen haben, sondern auch das Sendeschieberegister. Abhilfe: Nimm einen USB-RS485-Adapter auf Basis des FT232, der bietet eine hardwaremäßige RS485-Unterstützung (siehe Schaltungsbeispiel im Datenblatt), und da musst Du Dich um gar nichts kümmern.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.