Forum: Mikrocontroller und Digitale Elektronik (Echter) UART Baud (und mehr) Detektor


von Peter L. (localhost)


Lesenswert?

Moin,

ich würde gerne ein Bauteil entwerfen, dass die Baudrate (und später 
evtl. auch andere UART Parameter) einer UART Leitung erkennt. Leider 
konnte ich hierzu keine zufriedenstellende Lösung im Internet finden. 
Lösungen die ich gefunden habe basierten zumeist auf dem Erkennen von 
bestimmten Zeichen. Das Gerät soll mit Binärdaten klarkommen.

Für den Einstieg können wir folgende Annahmen treffen:
-UART läuft in der allgemein üblichen Konfiguration 8N1, sprich 8 
Datenbits und ein Stopbit sowie kein Paritätbit.
-Der Sender läuft in einer der üblichen Frequenzen, sodass bei 
Berechnungen der Frequenz gegen die nächst übliche gerundet werden kann.
-Kontinuirlicher Datenstrom oder zumindest "genügend" viele Daten.


Ideen:
-Messen der Zeiten zwischen zwei Bits, oder zwischen Start- und Stopbit.
Start- und Stopbit müssten erstmal gefunden werden.
Bei niedrigen Frequenzen (300 Baud z.B.) sollte es einfach sein die 
Zeiten zwischen zwei Bits zu messen. Dabei treten verschiedene Längen 
auf (0101 vs 0001), aus der kürzesten wird dann die Frequenz errechnet.
Wie genau kann man mit einem uC typischerweise die Zeit messen (z.B. 
Zeit zwischen zwei Interrupts)?

-Naiver Ansatz: Die Quelle an an mehrere UART Einheiten leiten, die auf 
verschiedene Baudraten eingestellt sind. Die Einheit, die mit der 
Baudrate des Senders läuft, sollte die meisten Daten ausgeben. -> Idee: 
Einheiten mit anderen Baudraten verwerfen Daten aufgrund fehlendem 
Stopbit.
Ein STM32F4 hat z.B. 6 UART Einheiten, in 2 Durchgängen sollte man alle 
üblichen Frequenzen prüfen können.


Als uC für eine Implementierung stell ich mir einen stm32 vor.

Hat jemand Ideen, oder einen Link wo das schon jemand gebaut hat?

von Mike A. (Gast)


Lesenswert?

peter l. schrieb:
> Wie genau kann man mit einem uC typischerweise die Zeit messen (z.B.
> Zeit zwischen zwei Interrupts)?

Nehmen wir eine µC mit 16MHz. Damit taktest du den Timer und nutzt die 
Capture Funktion. Die Genauigkeit entspricht dann dem Quarz zuzüglich 
dem Quantisierungsrauschen wegen der Synchronisation. Die Auflösung 
ergibt sich direkt aus der Periodendauer der Timertaktes und ist 
unabhängig vom Interrupt, weil der Interrupt nur dazu dient, die in den 
Capture Registern festgehaltenen Zählerstände auszulesen.

von m.n. (Gast)


Lesenswert?

peter l. schrieb:
> Wie genau kann man mit einem uC typischerweise die Zeit messen (z.B.
> Zeit zwischen zwei Interrupts)?

> Als uC für eine Implementierung stell ich mir einen stm32 vor.

Die Tage hatte ich soetwas mit einem STM32F407 gemacht: 
Beitrag "Frequenz- und Pulsweitenmessung mit STM32F407"

Etwas einfache ist eine Schaltung mit AVR, die per capture-Register 
abwechselnd positive und negative Flanken sucht.
http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm#lcd6

Vielleicht hift es Dir weiter.

von m.n. (Gast)


Lesenswert?

r
l

Die Buchstaben hatte ich vergessen ;-)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

peter l. schrieb:
> Hat jemand Ideen, oder einen Link wo das schon jemand gebaut hat?

 LOL.
 Also, ich habe das früher so gemacht, dass einfach die kürzeste bitzeit
 genommen wurde.
 Egal, was man misst, Log.0 oder oder Log.1, ein einzelner bit muss
 irgendwann kommen und das ist dann deine bitzeit.

 Für Pinabfrage in loop braucht man etwa 5-7 Takte, das ist schnell
 genug, um bis 38400B und 8MHz Mega überhaupt keine Probleme mit der
 Genauigkeit zu haben.
 Bei 38,4KB dauert ein bit 26,04us, das sind etwa 208 Takte oder 35
 Durchläufe. Ob du 34 oder 36 gezählt hast, ist ziemlich egal.

 Eine Tabelle mit den üblichen Baudraten kann auch nützlich sein -
 beschleunigt das Ganze ziemlich.

von c-hater (Gast)


Lesenswert?

peter l. schrieb:

> -Kontinuirlicher Datenstrom oder zumindest "genügend" viele Daten.

Da hast du schonmal ein Problem. OK, Baudrate geht relativ schnell zu 
erkennen. Aber andere Parameter deutlich schlechter, bzw. die Erkennung 
könnte u.U. lange Zeit mehrdeutig bleiben, wenn keine zur Unterscheidung 
geeigneten Daten über die Leitung gehen.

> Ideen:
> -Messen der Zeiten zwischen zwei Bits, oder zwischen Start- und Stopbit.
> Start- und Stopbit müssten erstmal gefunden werden.

Man misst einfach alles, was an Flankenwechseln reinkommt und clustert 
die Ergebnisse. Dann sucht man nach Clustern, deren mittlere Dauern 
näherungsweise ganzzahlige Vielfache voneinander sind.

Das Verfahren braucht zwar geringfügig länger, ist aber dafür sehr 
störsicher und liefert sehr genaue Ergebnisse.

> Wie genau kann man mit einem uC typischerweise die Zeit messen (z.B.
> Zeit zwischen zwei Interrupts)?

Dafür gibt es Capture-Einheiten. Damit kannst du die Zeit auf einen 
Timertakt genau ermitteln.

> Als uC für eine Implementierung stell ich mir einen stm32 vor.

Warum nicht gleich einen Intel I7 mit 3,8GHz single core boost, damit 
wärst du dann ganz auf der sicheren Seite? Meine Fresse...

Bei den üblichen Bitrate bis 115,2 schafft das locker ein AVR. Und wenn 
man ein bissel Grips in das Programm reinsteckt, schafft der auch noch 
die 921,6.

von Georg (Gast)


Lesenswert?

Marc Vesely schrieb:
> ein einzelner bit muss
>  irgendwann kommen

Wer sagt das - es gibt jede Menge gültige Zeichen, in denen zusammen mit 
Start- und Stoppbit immer mindestens 2 gleiche Bits aufeinander 
folgen.Nimm z.B. 0011001111. Noch gemeiner: 0000011111.

Georg

von Humphrey Bogart (Gast)


Lesenswert?

c-hater schrieb:
> Meine Fresse...

Meine Fresse, Meine Fresse, Meine Fresse...

Du denkst nur an Dich! Die Fresse von Anderen inetressiert Dich nicht 
die Bohne. Egoist.

von m.n. (Gast)


Lesenswert?

c-hater schrieb:
>> Als uC für eine Implementierung stell ich mir einen stm32 vor.
>
> Warum nicht gleich einen Intel I7 mit 3,8GHz single core boost, damit
> wärst du dann ganz auf der sicheren Seite?

Wenn er den STM32 sowieso schon verwendet, warum ihn nicht dafür mit 
nutzen?
Es gibt bei einigen Timern vom STM32Fxxx einen Meßmodus für PWM, wobei 
zwei capture-Register den Timerwert für pos. und neg. Flanken 
'einfangen' und bei einer der Flanken der Timer auch noch gelöscht wird.
Damit kann man auch höhere Baudraten recht genau erkennen, ohne auf 
Ausführungszeiten der Software Rücksicht nehmen zu müssen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Georg schrieb:
> Marc Vesely schrieb:
>> ein einzelner bit muss irgendwann kommen
>
> Wer sagt das - es gibt jede Menge gültige Zeichen, in denen zusammen mit
> Start- und Stoppbit immer mindestens 2 gleiche Bits aufeinander
> folgen.Nimm z.B. 0011001111. Noch gemeiner: 0000011111.
>

 Der TO sagt das.
peter l. schrieb:
> -Kontinuirlicher Datenstrom oder zumindest "genügend" viele Daten.

 Selbst wenn man Stoppbit nicht mitrechnet:
 Von 0 bis 127 gibt es viel mehr Zeichen mit zumindest einem einzelnen
 bit als ohne (bei Zeichen über 127 wird Startbit gemessen).
 Ohne jetzt genau nachzurechnen, aber das sind mindestens 200 von 256
 Zeichen die man auswerten kann. Theoretisch würden also 5 Zeichen
 vollkommen  genügen. In der Praxis natürlich nicht, aber selbst bei
 9600B dauern 100 Zeichen nur 104ms.
 So schnell kannst du nicht mal blinzeln.

von Bernd K. (prof7bit)


Lesenswert?

Marc Vesely schrieb:
> bei Zeichen über 127 wird Startbit gemessen

Anders rum! (lsb first)

Bei allen Zeichen zwischen 0x40 und 0x7f kann man das höchste Bit (eine 
0 nach einer 1 gefolgt vom Stopbit) messen und zusätzlich bei allen 
ungeraden Zeichen (niedrigstes Bit eine 1) kann man das Startbit messen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernd K. schrieb:
> Anders rum! (lsb first)
 Ja, natürlich.
 Hab das so auf die schnelle geschrieben weil ich nicht sehe, warum
 aus so etwas einfachem ein Drama gemacht wird.


c-hater schrieb:
> Warum nicht gleich einen Intel I7 mit 3,8GHz single core boost, damit
> wärst du dann ganz auf der sicheren Seite? Meine Fresse...

 Ich würde mindestens 4 Stück parallel laufen lassen,
 nur zur Sicherheit...
 Meine Fresse dazu...

von Karl H. (kbuchegg)


Lesenswert?

Im übrigen

> -Naiver Ansatz: Die Quelle an an mehrere UART Einheiten leiten,
> die auf verschiedene Baudraten eingestellt sind. Die Einheit, die
> mit der Baudrate des Senders läuft, sollte die meisten Daten ausgeben.


Nope. Das funktioniert so nicht.
Stell mal den Sender auf 9600 Baud und den Empfänger auf 300. Aus dem 
Empfänger purzelt eine Anzahl an Bytes raus, die wesentlich höher ist, 
als das was der Sender auf den Weg bringt. Du könntest dich maximal noch 
an den Frame Errors orientieren, aber wenn man die Annahme treffen kann, 
dass man es mit einem bunten Mix an Bytewerten zu tun hat, ist Bitzeiten 
messen der einfachere Weg. Irgendwann hat man dann mal ein einzelnes Bit 
und dieses irgendwann wird sich in der Praxis auch nicht im 
Stundenbereich bewegen.

von Karl H. (kbuchegg)


Lesenswert?

m.n. schrieb:
> c-hater schrieb:
>>> Als uC für eine Implementierung stell ich mir einen stm32 vor.
>>
>> Warum nicht gleich einen Intel I7 mit 3,8GHz single core boost, damit
>> wärst du dann ganz auf der sicheren Seite?
>
> Wenn er den STM32 sowieso schon verwendet, warum ihn nicht dafür mit
> nutzen?

Wenn er einen STM32 sowieso schon verwendet hätte, hätte er es schon 
längst implementiert und nicht hier gefragt.

von Klaus (Gast)


Lesenswert?

Ich nehme einfach meinen saleae und benutze die Autobaud Funktion

MfG Klaus

von m.n. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Wenn er einen STM32 sowieso schon verwendet hätte, hätte er es schon
> längst implementiert und nicht hier gefragt.

Der TO stellt sich einen STM32 als Zielprozessor vor; dazu muß er ihn 
nicht schon verwendet haben. Das ergibt sich aus dem Zusammenhang auch 
ohne Betonung des Futur.

Erst denken, dann schreiben.

von Karl H. (kbuchegg)


Lesenswert?

m.n. schrieb:
> Karl Heinz schrieb:
>> Wenn er einen STM32 sowieso schon verwendet hätte, hätte er es schon
>> längst implementiert und nicht hier gefragt.
>
> Der TO stellt sich einen STM32 als Zielprozessor vor; dazu muß er ihn
> nicht schon verwendet haben.

Du warst derjenige, der in den Raum gestellt hat, dass der TO 
möglicherweise einen STM schon verwendet hat oder bereits verwendet.

> Erst denken, dann schreiben.

Gleichfalls.
Und nicht die Zitatzeilen löschen in der Hoffnung, das würde schon 
keinem auffallen.

von Peter D. (peda)


Lesenswert?

Wenn der Sender keine größeren Pausen macht, kann man nicht feststellen, 
was ein Startbit ist oder ein 0-Datenbit.

Ich hab mal nen MC senden lassen und dann das PC-Terminalprogramm 
gestartet.
Es gab seitenweise nur Kauderwelsch.
Erst nach Reset des MC kamen lesbare Daten.

Eine Autobaud-/Autostarterkennung braucht immer Hilfe vom Sender.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter Dannegger schrieb:
> Wenn der Sender keine größeren Pausen macht, kann man nicht feststellen,
> was ein Startbit ist oder ein 0-Datenbit.

 Muss man ja auch nicht unbedingt.
 Es genügt festzustellen, ob nach einem Null-bit und 8 x-bits ein
 Stoppbit folgt.
 Wie schon gesagt, Baudrate feststellen sollte nicht mehr als
 100ms dauern.
 Danach den Start- bzw. Stoppbit zu finden und den Empfang im richtigen
 Moment zu starten, sollte auch nicht mehr als 100ms dauern.

von Karl H. (kbuchegg)


Lesenswert?

Marc Vesely schrieb:
> Peter Dannegger schrieb:
>> Wenn der Sender keine größeren Pausen macht, kann man nicht feststellen,
>> was ein Startbit ist oder ein 0-Datenbit.
>
>  Muss man ja auch nicht unbedingt.
>  Es genügt festzustellen, ob nach einem Null-bit und 8 x-bits ein
>  Stoppbit folgt.

Auch das kannst du nicht zuverlässig.

>  Danach den Start- bzw. Stoppbit zu finden und den Empfang im richtigen
>  Moment zu starten, sollte auch nicht mehr als 100ms dauern.

Wenn der Sender auf Dauernsenden ist, kannst du Start und Stop Bit nicht 
zuverlässig finden. Die heissen zwar so, unterscheiden sich aber in 
nichts von irgendwelchen anderen Bits. Letzten Endes hast du nur 
ständige Pegelwechsel auf der Leitung. Nicht weist darauf hin, was ein 
Startbit sein könnte bzw. was ein Stoppbit sein könnte. Hat man eine 
UART in Software, dann könnte man eventuell versuchen, ein paar Bits 
einfach auszulassen, wenn man auf laufende Frame-Errors kommt, in der 
Annahme, dass man die falsche Flanke als Startbit interpretiert. Ich 
kenne allerdings keine Hardware UART, die sowas machen würde.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Marc Vesely schrieb:
>  Es genügt festzustellen, ob nach einem Null-bit und 8 x-bits ein
>  Stoppbit folgt.

Das kann aber auch mehrfach mitten in 2 Frames der Fall geschehen.
1
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_

Finde das Start- und das Stopbit. ;-)

Man müsste erstmal für alle 9 Kandidaten ein Flag setzen und diese bei 
der Analyse per Ausschluss-Verfahren zurücksetzen.

>  Danach den Start- bzw. Stoppbit zu finden und den Empfang im richtigen
>  Moment zu starten, sollte auch nicht mehr als 100ms dauern.

Kommt auf die Daten an. Wenn sie Dich ärgern (s.o.), musst Du verdammt 
lange warten, bis Du alle (un)möglichen Start-/Stoppbit-Konstellationen 
ausgeschlossen hast.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Karl Heinz schrieb:
> Wenn der Sender auf Dauernsenden ist, kannst du Start und Stop Bit nicht
> zuverlässig finden. Die heissen zwar so, unterscheiden sich aber in

 Nicht mit Hardware-UART, aber mit Software-UART sollte das ziemlich
 einfach sein (ausser bei 0x55, aber auch da kriegst du den richtigen
 Wert raus, selbst mit Empfang mitten im Byte).
 Angenommen, man hat die Baudrate nach 100 Bytes raus.
 Danach werden (in Software) weitere 100 Bytes empfangen. Wenn kein
 Fehler auftritt, nochmal (zur Sicherheit) weitere 100 Bytes empfangen.
 Wenn kein Fehler vorhanden, Stoppbit abwarten, UART aktivieren.
 Wenn Fehler vorhanden, alles um 1 bit verschieben, weitere 100
 Bytes empfangen. 16bit Timer läuft mit, dient zur Synchronisation,
 das Ganze in Assembler.
 Was man auch sendet bzw. empfängt, es sollte nicht mehr als 1-2
 Sekunden dauern.
 Es sei denn, es wird dauernd 0x55 gesendet, da hat man zwar alles
 falsch aber trotzdem wird der richtige Wert angezeigt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Frank M. schrieb:
> Finde das Start- und das Stopbit. ;-)

 LOL.
 Wo auch immer man den Empfang startet, Wert wird richtig angezeigt.

Peter Dannegger schrieb:
> Eine Autobaud-/Autostarterkennung braucht immer Hilfe vom Sender.
 Ja.
 Und dazu wird meistens 0x55 oder 0xAA benutzt (mit 2 Stoppbits).

von m.n. (Gast)


Lesenswert?

Karl Heinz schrieb:
> Du warst derjenige, der in den Raum gestellt hat, dass der TO
> möglicherweise einen STM schon verwendet hat oder bereits verwendet.

Ich weiß ja nicht, warum Du nicht lesen, sondern nur stänkern möchtest.

peter l. schrieb:
> Als uC für eine Implementierung stell ich mir einen stm32 vor.
>
> Hat jemand Ideen, oder einen Link wo das schon jemand gebaut hat?

Da ich ihn gerade zur Hand habe, würde ich einen STM32F407 nehmen. Mit 
dem oben erwähnten PWM-Meßmodus kann man die einzelenen Pulsweiten 
bestimmen und gnadenlos einen 100KB Puffer mit den Werten füllen; 
meinetwegen auch per DMA ;-)
Danach (oder schon sobald hinreichend Daten vorhanden sind) sucht man 
das Minimum und erhält damit die Bitrate (Baudrate).
Abschließend sucht man das 1. Minimum (mit Startbit-Pegel) im Puffer und 
hat es dann als Startbit 'enttarnt', wenn es sich, je nach zulässigem 
Datenformat, periodisch im Puffer wiederfinden läßt. Bei 8N1 wäre es 
jeder 10. Wert.

Sollten Parität und mehr als 1 Stoppbit zulässig sein, muß man die 
zugehörigen Muster dafür verifizieren.

Weiter oben hatte ich ja schon auf ein modifizierbares Programm nebst 
Hardware mit LC-Anzeige verwiesen. Es reicht schon ein 
STM32F407-Discovery-Board.

von Peter L. (localhost)


Lesenswert?

Ich habe hier irgendwo noch ein stm32vl discovery board rumfliegen, 
darauf werde ich am Wochenende mal experimentieren.

von m.n. (Gast)


Lesenswert?

peter l. schrieb:
> Ich habe hier irgendwo noch ein stm32vl discovery board rumfliegen,
> darauf werde ich am Wochenende mal experimentieren.

Der STM32F100 ist leider nicht so üppig mit RAM garniert, aber ein 
Versuch könnte es Wert sein.
Wenn man 16-Bit Timer-Werte speichert (mehr kann der xxF100 nicht) und 
zunächst 4KB RAM dafür reserviert, kommt man beim 8N1-Format auf >= 200 
Datenbytes (je 10 Bit), die man einlesen und untersuchen kann. Das 
könnte für eine 'stupide' Vorgehensweise u.U. schon reichen.

Suche im "RM0041 Reference manual" des µC nach "PWM input mode". Dort 
ist beschrieben, wie es geht.
Vielleicht probiere ich es noch selber mit dem xxF407. Frech wie Bolle 
würde ich einen 32-Bit Timer mit 84MHz Takt nehmen ;-)
Mal sehen.

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
Noch kein Account? Hier anmelden.