2x RS232 auf USB (mit modifizierten Daten)

Gast #3601639
Lesenswert?

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
Gast #3601643
Lesenswert?

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?
Gast #3601683
Lesenswert?

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.
#3607029
Lesenswert?

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
Gast #3607313
Lesenswert?

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
#3608370
Lesenswert?

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
Persönliche Seite #3608438
Lesenswert?

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 ...
#3608500
Lesenswert?

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.
#3608975
Lesenswert?

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
#3647908
Lesenswert?

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.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren