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?
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.
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.
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.
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.
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
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.
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.
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.
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.
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...
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.
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.
Ich nehme einfach meinen saleae und benutze die Autobaud Funktion MfG Klaus
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.
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.
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.
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.
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.
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.
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.
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).
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.
Ich habe hier irgendwo noch ein stm32vl discovery board rumfliegen, darauf werde ich am Wochenende mal experimentieren.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.