ATmega, automatische Baudratenanpassung

Hallo,

vieleicht erinnert sich ja jemand an den alten 8052AH Basic. Bei dem Ding wurde nach dem Start die Baudrate des angeschlossenen Terminals automatisch erkannt und der Prozessor antwortete entsprechend.

Dazu musste man als erstes Zeichen soweit ich mich erinnere ein , d.h. char 32, bzw. #20H senden und der Timer für die Baudrate wurde dann passend eingestellt.

Hat jemand ein Codeschnipsel für eine ähnliche Lösung mit dem ATmega8? Möglichst GCC, also WINAVR.

Hintergrund: Ich möchte mit einem ATmega8 ohne Quarz, also mit internem

8MHz Oszillator über die serielle Schnittstelle kommunizieren. Um Baudratenfehler auszugleichen, soll sich der ATmega8 an den PC anpassen.

Gruß

Stefan DF9BI

Reply to
Stefan Brröring
Loading thread data ...

Du könntest zu avrfreaks.net gehen und dort Cliff Lawson (der Mega-Poster in diesem Forum schlechthin) fragen, er hat mal irgendwann geschrieben, dass er ein Autobauding auf der Basis eines initial gesendeten implementiert hat.

Aber:

*Das* wird dir mit einem einzelnen Zeichen als Referenz schlecht gelingen. Cliffs Autobauding war wohl eher in dem Sinne, wie ein klassisches Modem arbeitet, also dass man 9600 Bd von 19200 Bd unterscheidet. Du müsstest ja bei dir live den RC-Oszillator nachkalibrieren.

Das wäre, wenn ich das recht überschaue, höchstens machbar, indem du eine (exemplarabhängige) Kalibriertabelle in den EEPROM legst, aus der die relative Änderung der Frequenz in Abhängigkeit von den OSCCAL- Werten hervorgeht. Diese könntest du dann benutzen, um aus der beim initialen Zeichen gemessenen Bitzeit abzuleiten, welchen neuen Wert von OSCCAL man jetzt programmieren müsste, damit die Taktfrequenz den Sollwert erreicht.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Stefan Brröring schrieb:

Ich kenne diese Funktion vom PIC, wo allerdings 0x55 gesendet wird:

Start-Bit ist 0, die Bits vom LSB zum MSB abwechselnd 1 und 0 und das Stop-Bit wieder 1.

Somit gibt es (idelerweise äquidistante) Bitbreiten, die gemessen werden und in eine Baud-Rate (bzw. einen Timingfakrot) umgerechnet werden.

Das ist allerdings eine interne PIC-Funktion; um die zu aktivieren ist WIMRE einfach nur ein Bit zu setzen und das erste ankommende Zeichen wird genutzt.

Thomas

Reply to
Thomas Rachel

=?ISO-8859-15?Q?Stefan_Brr=F6ring?= :

In meiner uralten Codesammlung ist auch ne Autobaud für den 8051 dabei:

formatting link

Suchbegriffe wären autobaud oder "auto baud" ATMEGA source

Wobei die meisten Autobaudratenerkenner auf einen Quarz zurückgreifen und in groben Schritten zwischen den einzelnen Raten unterscheiden. Deine Spezialfunktion müsste die Abstände zwischen den Flanke ausmessen. Die kürzeste gemessene Zeit wäre die Zeit für die korrekte Baudrate (das serielle Signal muss also an einen capture timer dran). Um Störmessungen ( u.a. beim Anstöpseln) auszuschliessen, sollte man dann auch mehrmals messen und zu kleine Werte rausschmeissen. Inweiweit (und wie schnell) dein Takt wegdriftet wäre auch noch ne Frage...

M.

Reply to
Matthias Weingart

Stefan Brröring schrieb:

Das Application Note AVR054 beschreibt sowas, dort ist auch passender Code dabei.

Du musst allerdings beachten, das der interne RC Oszillator nicht bloss einen konstanten Fehler aufweisst, sondern auch ziemlich stark jittert, hohe Baudrate werden ohne Quarz schwierig.

Jan

Reply to
Jan Lucas

Viele uC schaffen mit dem internen Oszillator beinahe 1%. Wenn Drift doch zu hoch ist, koennte man die Messung nicht weiter mitlaufen und ab und zu am Ventil drehen lassen? Poor-Man's PLL sozusagen.

--
Gruesse, Joerg

http://www.analogconsultants.com/

"gmail" domain blocked because of excessive spam.
Use another domain or send PM.
Reply to
Joerg

Wäre auch nicht schlimm, sollte aber mit einem einzelnen Byte machbar sein. Jedes Zeichen, bei dem Bit 0 = 0 ist, fängt mit einem Startbit an, dass man dann ausmessen kann. Daraus sollte man dann den Timerwert ermitteln können. In Assembler eventuell einfacher als in C.

Ich stelle mir das so vor:

Lese den RXD-Pin, wenn der Pegel = 0 ist, springe auf weiter loop: incrementiere eine Zähler Teste den Pegel des RXD-Pins Ist der Pegel = 0 springe nach Loop: Multipliziere den Zähler mit einem Faktor und berechne damit den UBBR-Wert, setze UBBRL und UBBRH

Daten einlesen

weiter: // Baudrate nicht einstellen ...

Reply to
Stefan

Das klingt gut, werde ich mir ansehen, danke

Reply to
Stefan

Stefan schrieb:

Nö, das ist es nicht. Ich will nicht den Prozessortakt anpassen, nur das Baudratenregister. Beim 8052 wurde einfach in einer Schleife ein Zähler incrementiert, der ohne große Umrechnungen direkt in ein 16 Bit Timer Reload Register geschrieben wurde. Müsste mal den Quellcode raussuchen...

Reply to
Stefan

Sowas ist naturgemäß nicht sehr zuverlässig, und das beschriebene Testpattern ist dann auch noch alles andere als ideal...

Beim Atmel kann man ja auf die Empfangsleitung direkt zugreifen. D.h.: anders als z.B. beim PC muß man keine "Verhaltensanalyse" eines Controllers durchführen, um zu irgendwelchen Schlüssen zu kommen, sondern man kann schlicht und einfach direkt das Eingangssignal vermessen.

Messen ist eine Sache, wo es auf Genauigkeit ankommt. Da ist dieser aufgeblasene Makroassembler C nur ein Störfaktor (Naja, mich stört er eigentlich immer, aber das ist Geschmackssache). Fakt ist jedenfalls: Sowas macht man mit ein paar Zeilen Assembler viel leichter.

Auch mit Einmessen wirst du wirklich "hohe" Raten (z.B. 115200) nicht zuverlässig hinbekommen. Das liegt nicht etwa daran, daß man nicht genau genug messen könnte und auch nicht daran, das der interne Oszillator eine zu hohe Kurzzeitdrift hätte, sondern einzig daran, daß der Bitratenteiler nur ganzzahlig teilen kann und sein Muttertakt nicht allzu hoch ist.

Hier hilft nur eins wirklich: Den internen Osziallator entsprechend der Meßergebnisse verstimmen. Leider ist auch der nur in relativ groben Schritten durchstimmbar. Aber um 115200 zumindest im Kurzzeitrahmen zuverlässig hinzubekommen, reicht es sicher aus, jedenfalls bei den ATMegas.

Reply to
Heiko Nocon

Stefan schrieb:

Worin liegt der praktische Unterschied? Mit OCCAL kann man meiner Erinnerung nach etwa in 0,5-%-Schritten einstellen, mit UBRR in

1-%-Schritten, wenn du von UBRR=103 (8 MHz, U2X gesetzt, 9600 Bd) ausgehst.
--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Jan Lucas schrieb:

Die Höhe der Baudrate spielt keinerlei Rolle. Eine RS-232 ist ca. 2 % fehlertolerant, unabhängig davon, ob du das mit 115200 Bd oder 2400 Bd machst. Der Jitter ist auch nur ein relativer Fehler (aber so groß ist er nicht, eigentlich stört nur die Vcc- und Temperaturabhängigkeit in der Langzeitkonstanz).

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Darüber solltest du nochmal nachgrübeln. Insbesondere unter dem Aspekt, daß die Baudrate nicht in linearen Schritten einstellbar ist, sondern nur durch Teilung eines (nicht allzu hohen) Muttertaktes.

Reply to
Heiko Nocon

Heiko Nocon schrieb:

Darum ging es doch gar nicht. Du hast behauptet, dass der Jitter des Master-Taktes keine hohen Baudraten gestatten würde. Meine Behauptung ist, dass der Jitter entweder gar keine stabile Kommunikation gestattet oder aber bei allen Baudraten das gleiche Fehlverhalten erzeugt.

Natürlich setzt das voraus, dass man den Master-Takt selbst so weit genau eingestellt hat, dass der sich ergebende Takt (einigermaßen) in der Mitte des Fehlerfensters ist, also einen ,,baudratenfreundlichen'' Takt im Zweifelsfalle gewählt hat (der RC-Oszillator lässt sich ja garantiert auf 7,3728 MHz einstellen). Wenn man sowieso schon am Anschlag des 2-%-Fensters ist, dann kann natürlich der Jitter eine Rolle spielen. Aber selbst dann würde die absolute Höhe der Baudrate keine Rolle spielen. Beispiel: besagter ATmega8 wird mit 8 MHz getaktet, dann wäre der Grundfehler für 57600 Bd 2,1 % (also grenzwertig), aber 76800 Bd würden mit 0,2 % Grundfehler erreicht.

Im Übrigen habe ich mir fCPU/2 des besagten 8-MHz-RC-Oszillators eines ATmega8 eben mal auf dem Spekki angesehen (Timer im CTC-Modus auf toggle OC1A on compare match): der jittert maximal 1 kHz, also 2.5E-4.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Nein. Wo soll ich das behauptet haben?

Das ist der Punkt, den ich meinte und über den geredet habe. Von Jitter habe ich überhaupt nix erwähnt. Nichtmal das Wort ist in irgendeinem meiner Postings in diesem Thread zu finden.

Irgendwie hast du ein Leseproblem, kann das sein?

Reply to
Heiko Nocon

Heiko Nocon schrieb:

'tschuldigung, es war Jan Lucas, der das behauptet hat, und auf den ich geantwortet hatte.

Du hast auf mein Posting geantwortet, in dem ich mich auf Jans Bemerkung mit dem Jitter bezogen habe. Da habe ich vergessen nachzugucken, dass du im falschen Subthread gelandet warst. Dass du nur einen Satz von mir aus dem Kontext gerissen hast und den dann unter deinen Gesichtspunkten reinterpretiert hast, war mir dann natürlich entgangen.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Heiko Nocon schrieb:

Schon klar, man kann ja ein paar Assember Zeilen in das C-Programm einbauen, da hab ich grundsätzlich kein Problem damit

Das ist schon klar, aber beim ATmega läuft der Baudratengenerator wie beim 8052 mit nem 16 Bit Teiler, insofern sollte man bei geringen Baudraten, d.h. 9k6 und kleiner das ganze genau genug einstellen können.

Genau genommen geht es auch nur darum, dass sich der Prozessor auf eine halbwegs bekannte Baudrate anpassen soll, d.h. ein PC sendet mit 9K6, der Prozessortakt des ATmega ist ungenau, und er soll das automatisch korrigieren. Es reicht auch, wenn das in 99% der Fälle funktioniert.

Hintergrund ist, ich will eine möglichst billige Schaltung mit einem ATmega8 aufbauen, die jedoch einmal konfiguriert werden muss. Die Konfiguratin wird ins EEProm geschrieben und das wars dann bis zum Lebensende des Gerätes.

Ich habe dazu einen einfachen Adapter gebaut, mit dem das TXD* Signal des PCs auf TTL umgesetzt wird. Das geht auf eine Koaxbuchse und mit einem 1:1 Tastkopf wird dann einfach die Tastspitze auf die RXD Leitung des ATmega gedrückt. Der PC sendet im abstand von 0,5 sec. dauernd ein Telegramm mit den Konfigurationsdaten und eine Checksumme. Wenn der ATmega die Konfiguration einmal fehlerfrei gelesen hat, speichert er das Ergebnis ab und fertig. Ob das Telegramm wirklich fehlerfrei war, kann man dann am Verhalten des Controllers erkennen.

Aus Kostengründen gibt es keinen Quarz am ATmega. Jetzt hatte ich gedacht, dass der bei 3,3V (CR2032) und 8 MHz auch ungefähr mit 8 MHz läuft. Aber momentan sieht es nach einem Fehler von ca. 10% aus.

Die Taktfrequenz des Prozessors könnte man natürlich auch anpassen, aber normalerweise sollte sich der benötigte Reloadwert für den Timer exakt aus der Breite eines Bits bestimmen lassen.

Stefan DF9BI

Reply to
Stefan

Welchen ATMega benutzt du? Z.b. der Mega8 hat jeweils ein eigenes Calibrier- byte pro Frequenz wobei immer nur das für 1 MHZ automatisch gesetzt wird. Die anderen muß man im Programmer auslesen und irgendwie dem Programm übergeben. Ausserdem ist im Datenblatt der Frequenzgang der Oszilatorfrequenz pro Spannungswert dokumentiert so dass du den Teilungsfaltor im voraus richtig berechnen kannst. (bei 3V 7.3 statt 8 MHZ)

Natürlich kannst du einen Timer verwenden um die Baudrate zu bestimmen. Wenn du Zeitweise einen Timer, den Capturepin oder einen Interruptpin übrig hast ist das ganz problemlos.

--
MFG Gernot
Reply to
Gernot Fink

Hallo!

"Stefan" wrote

Haste noch 18 Cent übrig?

formatting link

alsdenn, Jens

Reply to
Jens Frohberg

Ja. Atmel garantiert für den internen Oszillator meist nur, daß bei

25°C, 5V der Solltakt +-10% eingehalten wird. Bei Verwendung der mitgelieferten Defaultwerte für OSCCAL garantieren sie zwar sogar +-3%, aber das ist auch immer noch zuviel für eine zuverlässige RS232-Kommunikation.

Apropos, da fällt mir doch gerade noch was ein: Nicht für jeden Solltakt wird automatisch das OSCAL-Register mit dem korrekten Defaultwert initialisiert, daß klappt immer nur bei einem bestimmten Solltakt und welcher das ist, ist deviceabhängig. Bei anderen Solltakten muß die Anwendung selber das OSCCAL-Register initialisieren. Hast du daran gedacht?

Ich finde das übrigens völlig bescheuert, denn die Anwendung kann die Defaultwerte nichtmal selber auslesen. Man muß sie mit dem Programmer auslesen und dann im Flash oder EEPROM der Anwendung zur Verfügung stellen. Das Verfahren hätten sich Schildbürger wohl nicht besser ausdenken können.

Das ist besser und obendrein auch noch einfacher, jedenfalls, wenn die die Sollbitrate eigentlich bekannt ist und es nur darum geht, den Taktfehler des Oszillators zu kompensieren. Und es braucht nichtmal was abgespeichert zu werden, weil die Meßroutine ständig parallel zum Datenempfang laufen und den Oszillator ständig nachregeln kann. Dann spielen nämlich auch Spannungsschwankungen und Temperaturwechsel keine Rolle mehr, es funktioniert einfach immer.

Naja, aus der Breite eines einzelnen Bits geht's leider nicht wirklich. Und es geht natürlich umso schlechter, je höher die Bitrate ist. Das liegt wieder daran, daß du nur ganzzahlig messen kannst und das nicht mal sonderlich genau, es sei denn, man opfert einen Timer und den Capture-Pin für diese Messung. Dazu kommen noch die Unwägbarkeiten einer Einzelmessung. Z.B. wenn sie bloß das Kontaktkratzen beim Einstöpseln des RS232-Steckers mißt, was dann? Nö, wenn das einigermaßen zuverlässig funktionieren soll, muß es in der Art einer ständig laufenden oder zumindest in bestimmten Abständen wiederholten Form geschehen. Alles andere macht nur Ärger.

Reply to
Heiko Nocon

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.