Hallo Community, leider bin ich über die Suchfunktion nicht auf eine Lösung gestoßen. Es geht darum 2x serielle Schnittstellen (RS232) am PC auszulesen. Die Daten gehören zu einer Punkt zu Punkt Linienstromverbindung (2 kanalig, daher auch 2xRS232. Eine Leitung gehört sozusagen dem Master, die zweite dem Slave). Um die Daten mithorchen zu können, benötige ich die Daten in der Richtigen Reihenfolge. Beispiel: Master | Slave Request -> <- positive Quittierung Daten 1 -> Daten 2 -> Daten Ende -> <- positive Quittierung Mein erster Ansatz an die Daten zu gelangen war die Nutzung von zwei USB <-> RS232 Konvertern. Das Problem ist eine Kombination aus der Scheduling- und Packet-basierten USB-Übertragung und der sehr unterschiedlichen Datagramm-Größen des seriellen Protokolls. Die Folge war das die Reihenfolge der Daten vertauscht ankam, sozusagen die zeitliche Zuordnung nicht möglich ist. Die Daten wurden empfangen und unmittelbar in einer gemeinsamen TextBox angezeigt. (Farblich unterschieden) Von daher hatte ich folgende Überlegung: (<-> ist jeweils ein Konverter) 2x RS232 zu 2x RS232 <-> UART zu z.B. ATmega1280 (da 4x UART) (dort Daten modifizieren) zu UART <-> USB Dieses Lösung hätte den Vorteil, das ich den einzelnen Daten beim Modifizieren schon außerhalb des Betriebssystems die zugehörigen Sender zuordne und dann nur noch am PC auswerten muss. Mein momentanes Wissen zu IC's und µC Programmierung ist noch relativ dürftig. Deswegen hoffe ich auf Anregungen, die mir bei der IC Wahl helfen und auch bei der Programmierung des µC, da ich die Daten ja auch verlässlich modifizieren muss. Oder es kennt jemand eine andere Lösung für mein Problem :) Vielen Dank Stefan
was ist wenn auf RS232 ein großes Packet und etwas später auf dem 2. RS232 ein kleineres Packet ankommt. Das kleiner Packet ist zuerst fertig. Welches packet wurde nun zu erst empfangen? Gilt also der Start oder das ende der Übertragung?
Das sollte eigentlich nicht vorkommen, da es sich ja um eine Punkt zu Punkt Verbindung handelt. Die zweite Leitung wird erst wieder beansprucht, wenn das Signal "Daten Ende" von der ersten Leitung erhalten wurde. Somit kann wenn überhaupt nur ein Problem auftreten, wenn beide gleichzeitig mit einer Übertragung starten wollen. Dafür ist aber in der PtP Verbindung eine Prioritätenregelung hinterlegt. Es geht Insgesamt auch nur darum, die Daten der PtP Verbindung abzuhören. Es wird nichts gesendet.
Hat vielleicht jemand schon mal etwas ähnliches gemacht oder gebaut ?
Nimm doch einfach einen Logic Analyzer wie den hier. https://www.saleae.com/logic Das ist ein fertiges Gerät, mit dem Du das Timing exakt erfassen und Deine beiden UART-Kanäle dekodieren kannst. Wenn Du Deine Arbeitszeit einrechnest, ist das die billigste Lösung - und mit Sicherheit die einfachste. Der Logic Analyzer kann allerdings keine RS232-Pegel direkt verarbeiten, aber ein Max232 ist ja schnell aufgebaut. fchk
Frank K. schrieb: > Der Logic Analyzer kann allerdings keine RS232-Pegel direkt verarbeiten, > aber ein Max232 ist ja schnell aufgebaut. Den braucht man zum Mithören nicht, da reicht ein 1489/75189. Der enthält keine Ladungspumpe, braucht also nicht die vier Kondensatoren, an deren Dimensionierung hier üblicherweise 15% der Forennutzer scheitern.
Frank K. schrieb: > Nimm doch einfach einen Logic Analyzer wie den hier. Das sieht an sich viel versprechend aus...nur muss ich die Daten ja in mein eigenes Programm bekommen und nicht in deren Anzeige/Terminal. Dazu kommt, das ich wirklich nur die zwei Kanäle brauche und keine 8. Es ist für mich eigentlich zu groß dimensioniert und damit teurer als notwendig.
Und eine PCI/PCIe-Karte mit echten UARTs kannst Du in Deinen Rechner nicht einbauen? fchk
Nein bei dem Laptop sind keine Steckplätze vorhanden. Und außerdem soll das ganze System/PC unabhängig sein. Es soll sozusagen eine Mobile Lösung sein.
oder du schnappst dir einen beliebigen Controller mit >=3 UART, bufferst die 2 Eingänge und schiebst sie in richtiger reihenfolge zum 3. wieder raus. Dann hast du mit dem PC nur eine Schnittstelle und da kommen die Daten dann schon in der richtigen Reihenfolge. Der Controller muss halt noch davor schreiben zu welchem Anschluss das Paket gehört und der 3. UART muss die Baudraten der beiden anderen zusammen packen. lg
Mat schrieb: > oder du schnappst dir einen beliebigen Controller mit >=3 UART, > bufferst die 2 Eingänge und schiebst sie in richtiger reihenfolge zum 3. > wieder raus. Dann hast du mit dem PC nur eine Schnittstelle und da > kommen die Daten dann schon in der richtigen Reihenfolge. Genau das wäre mein Ansatz :) Dazu will ich einen ATmega640 verwenden der die beiden seriellen RS232 Pegel mittels MAX232 wandelt. Auf der anderen Seite will ich ein FT232RL für die USB Übertragung nutzen. Den µC will ich Interrupt gesteuert programmieren, sprich immer wenn Daten per UART kommen, direkt per USB-UART weiter senden. Kann das so funktionieren ? Edit: Rufus Τ. Firefly schrieb: > Nun, dann hilft das hier: > https://iftools.com/analyzer/msb-rs232/index.de.php Danke für den Hinweis, das sieht vielversprechend aus
:
Bearbeitet durch User
Dafuer gibt es fertige Geraete, die genau das machen fuer relaiv wenig Geld. Eine Streichholzschachtel mit USB dran
Stefan Schmidt schrieb: > Dazu will ich einen ATmega640 verwenden Hat der drei serielle Schnittstellen? Die brauchst Du nämlich dafür - zwar verwendest Du von jeder Schnittstelle nur die Hälfte, nämlich von je zwei nur den RxD-Pin (zum Mithören) und von einer den TxD-Pin (zum Senden via FT232), aber die dritte ist erforderlich, weil die mit (mindestens) der doppelten Baudrate der beiden anderen Schnittstellen betrieben werden muss. Deswegen kannst Du nicht den TxD-Pin einer der beiden Mithör-Schnittstellen verwenden, um die empfangenen Daten zum PC zu senden. Und wenn Du das Gerät mit etwas Komfort betreiben willst, willst Du natürlich auch die verwendete Mithörbaudrate und gegebenenfalls noch andere Parameter vom PC aus einstellen können, wozu sich der RxD-Pin der dritten Schnittstelle anbietet, der ebenfalls mit dem FT232 zu verbinden ist. Möchtest Du weiteren Komfort, wie z.B. Erkennung von Übertragungsfehlern wie Parity- oder Framing-Fehlern, dann muss die Schnittstelle zum PC mit noch höherer Datenrate betrieben werden, weil Du dann für jedes einzelne empfangene Byte auch noch ein Statusbyte übertragen musst. Das könntest Du auch noch benutzen, um den Zustand der Handshakeleitungen zu übertragen, die Du mit deinem Mithörer ebenfalls aufzeichnen kannst. Ein sicherlich schickes Projekt, wenn die pc-seitige Auswertungssoftware auch noch schick gemacht wird. Dann aber landet man irgendwann bei so etwas wie dem von mir erwähnten Gerät ...
думлихер троль schrieb: > Dafuer gibt es fertige Geraete, die genau das machen fuer relaiv wenig > Geld. Eine Streichholzschachtel mit USB dran Unter welchem Suchbegriff sind diese denn zu finden ? Ich habe sie nämlich noch nicht gefunden :)
Rufus Τ. Firefly schrieb: > Stefan Schmidt schrieb: >> Dazu will ich einen ATmega640 verwenden > > Hat der drei serielle Schnittstellen? > Ja der hat 4 UART Schnittstellen. > Und wenn Du das Gerät mit etwas Komfort betreiben willst, willst Du > natürlich auch die verwendete Mithörbaudrate und gegebenenfalls noch > andere Parameter vom PC aus einstellen können, wozu sich der RxD-Pin der > dritten Schnittstelle anbietet, der ebenfalls mit dem FT232 zu verbinden > ist. Habe ich auch vor. Die maximale Baudrate auf der Abhöhrseite sollte bei 19,2k liegen. Die USB-Seite Baudrate versuche ich auf das 3-4 fache zu setzen.
Stefan Schmidt schrieb: > Dazu will ich einen ATmega640 verwenden der die beiden seriellen RS232 > Pegel mittels MAX232 wandelt. Auf der anderen Seite will ich ein FT232RL > für die USB Übertragung nutzen. Den µC will ich Interrupt gesteuert > programmieren, sprich immer wenn Daten per UART kommen, direkt per > USB-UART weiter senden. Dann solltest Du für jedes empfangene Byte noch die Portnummer und einen Timestamp mitsenden. Das Timing am USB-Port ist nicht vorhersehbar, und der Mikrocontroller ist der einzige, der einen Timestamp liefern kann. Wind wenn Du statt des FT232 einen FT245 nimmst, brauchst Du keinen 100-Pin AVR und hast eine schnellere Hostschnittstelle, weil der FT245 ein paralleles Interface hat. Du kannst zwar weiterhin PC-seitig eine Bitrate einstellen, die aber ignoriert wird. Wahlweise kannst Du auch einen FT2232D oder FT2232H verwenden. Die eleganteste und technisch beste Lösung wäre ein Controller mit 2 UARTS und USB-Hardware. Leider gibts es keine AVR, der diese Bedingung erfüllt. Ein PIC24FJ64GB002 (28 Pins, auch DIL) würde das alles können. fchk
So, die Platine ist gelötet und funktioniert soweit. Allerdings bin ich nun auf ein Programmier Problem gestoßen. Ich verwende einen ATmega1280 mit einem externen Quarz (7,3728MHz). Ich möchte mit meinem Programm erstmal nur die Daten von USART1 und USART2 an USART3 schicken. Zwei von drei ISR funktionieren, aber sind alle identisch. Meine Interrupt Routinen funktionieren auch, bis auf die von USART1. Das senden über USART1 funktioniert (also TxD). Nur RxD löst die ISR nicht aus. Die anderen beiden ISR funktionieren hingegen. Ich bin ratlos. Muss ich den UART-Interrupt für diesen Port besonders einstellen ? Auf dem RxD Pin kann auch ein externen Interrupt eingestellt werden (INT2 Pin 45). Kann daher das Problem kommen ? ------------------------------------------------------------------ Hier mein Programm:
1 | //Includes
|
2 | //#include "defines.h"
|
3 | #include <avr/interrupt.h> |
4 | #include <avr/io.h> |
5 | //#include <avr/iomxx0_1.h>
|
6 | #include <string.h> |
7 | #include <util/delay.h> |
8 | |
9 | |
10 | void uart_send_byte(char c){ |
11 | while (!(UCSR3A & (1<<UDRE3))); |
12 | UDR3=c; |
13 | }
|
14 | void uart_send_string(const char *c){ |
15 | while ( *c != '\n' ) |
16 | uart_send_byte(*(c++)); |
17 | }
|
18 | |
19 | |
20 | int main(void){ |
21 | DDRJ = 0b00000010; |
22 | DDRH = 0b00000010; |
23 | DDRD = 0b00001000; |
24 | DDRA = 0b00001111; |
25 | |
26 | UBRR3H = 0x00; |
27 | UBRR3L = 3; //115200Hz bei 7,382700 MHZ Quarz |
28 | |
29 | UBRR2H = 0x00; |
30 | UBRR2L = 47; //9600Hz bei 7,382700 MHZ Quarz |
31 | |
32 | UBRR1H = 0x00; |
33 | UBRR1L = 47; //9600Hz bei 7,382700 MHZ Quarz |
34 | |
35 | |
36 | UCSR1B |= (1<<TXEN1)|(1<<RXEN1)|(1<<RXCIE1); // UART1 RX und Interupt einschalten |
37 | |
38 | UCSR3B |= (1<<TXEN3)|(1<<RXEN3)|(1<<RXCIE3); // UART TX einschalten |
39 | |
40 | UCSR2B |= (1<<TXEN2)|(1<<RXEN2)|(1<<RXCIE2); // UART TX einschalten |
41 | |
42 | _delay_ms(2000); |
43 | |
44 | PORTA |= (1<<PA3); //LED Test |
45 | |
46 | sei(); |
47 | |
48 | while(1){ |
49 | |
50 | |
51 | UDR3='3'; |
52 | _delay_ms(2000); |
53 | UDR2='2'; |
54 | PORTA &= ~(1<<PA3); |
55 | |
56 | _delay_ms(2000); |
57 | UDR1='1'; |
58 | PORTA |= (1<<PA3); |
59 | _delay_ms(2000); |
60 | }
|
61 | }
|
62 | |
63 | //ISR(USART1_RX_vect) {
|
64 | // cli();
|
65 | //// if ( (UCSR1A & ( 1<<FE1)) != 0 )
|
66 | //// uart_send_string("Frame ERROR1\n");
|
67 | //// if ( (UCSR1A & ( 1<<DOR1)) != 0 )
|
68 | //// uart_send_string("Data OverRun1\n");
|
69 | //// if ( (UCSR1A & ( 1<<UPE1)) != 0 )
|
70 | //// uart_send_string("Parity Error1\n");
|
71 | ////
|
72 | //// while (!(UCSR3A & (1<<UDRE3)));
|
73 | //// UDR3='!';
|
74 | //// while (!(UCSR3A & (1<<UDRE3)));
|
75 | //// UDR3=UDR2;
|
76 | //// while (!(UCSR3A & (1<<UDRE3)));
|
77 | //// UDR3='\\';
|
78 | //
|
79 | // while(1) {
|
80 | // PORTA &= ~(1<<PA2);
|
81 | // _delay_ms(500);
|
82 | // PORTA |= (1<<PA2);
|
83 | // _delay_ms(500);
|
84 | //
|
85 | // }
|
86 | // sei();
|
87 | //}
|
88 | |
89 | ISR(_VECTOR(36)) { //Funktioniert auch nicht, Vectornummer oben stimmt überein |
90 | cli(); |
91 | while(1) { |
92 | PORTA &= ~(1<<PA2); |
93 | _delay_ms(500); |
94 | PORTA |= (1<<PA2); |
95 | _delay_ms(500); |
96 | |
97 | }
|
98 | sei(); |
99 | }
|
100 | ISR(USART2_RX_vect){ |
101 | cli(); |
102 | PORTA &= ~(1<<PA3); |
103 | if ( (UCSR2A & ( 1<<FE2)) != 0 ) |
104 | uart_send_string("Frame ERROR2\n"); |
105 | if ( (UCSR2A & ( 1<<DOR2)) != 0 ) |
106 | uart_send_string("Data OverRun2\n"); |
107 | if ( (UCSR2A & ( 1<<UPE2)) != 0 ) |
108 | uart_send_string("Parity Error2\n"); |
109 | |
110 | while (!(UCSR3A & (1<<UDRE3))); |
111 | UDR3='!'; |
112 | while (!(UCSR3A & (1<<UDRE3))); |
113 | UDR3=UDR2; |
114 | while (!(UCSR3A & (1<<UDRE3))); |
115 | UDR3='\\'; |
116 | |
117 | sei(); |
118 | PORTA |= (1<<PA3); |
119 | }
|
120 | |
121 | ISR(USART3_RX_vect){ |
122 | cli(); |
123 | if ( (UCSR3A & ( 1<<FE3)) != 0 ) |
124 | uart_send_string("Frame ERROR\n"); |
125 | if ( (UCSR3A & ( 1<<DOR3)) != 0 ) |
126 | uart_send_string("Data OverRun\n"); |
127 | if ( (UCSR3A & ( 1<<UPE3)) != 0 ) |
128 | uart_send_string("Parity Error\n"); |
129 | //char recChar = UDR3;
|
130 | |
131 | while (!(UCSR3A & (1<<UDRE3))); |
132 | UDR3=UDR3; |
133 | |
134 | sei(); |
135 | }
|
-------------------------------------------------------------------- Vielen Dank schonmal für eure hoffentlich zielführenden Antworten.
:
Bearbeitet durch User
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.