Forum: Mikrocontroller und Digitale Elektronik ATMEGA168 vs ATMEGA328 RC Oscillator


von Wolfgang (Gast)


Lesenswert?

Hallo zusammen,

ich habe in einem Projekt, bei dem eine asynchrone Datenübertragung in 
Software implementiert wurde, bislang den MEGA168-20MU mit dem internen 
RC - Oscillator verwendet. Dass dies nicht die beste Kombination ist, 
ist mir bewusst: Der Oscillator wurde aber beim Hochfahren der Software 
kalibriert und die Ergebnisse waren passabel: ca. 4% der Datenpakete 
waren beschädigt.

Jetzt wurde der MEGA168 durch den MEGA328 - MU ersetzt und plötzlich hat 
sich die Fehlerrate ca. verfünffacht. Bis zu 20% der Datenpakete gehen 
verloren. Ich habe auch den Kalibrierungscode modifiziert, um andere 
OSCCAL Werte zu erhalten und das Ergebnis wurde noch schlechter.

Es handelt sich auch nicht um einen Einzelfall, sondern zu einer 
massiven Tendenz.

Hat jemand Ideen?

P.S.:

"warum nimmste keinen Quartz?" -> "Ist aus Platzgründen nicht möglich! 
War außerdem bislang auch nicht notwendig"

"Bemüh mal die Suchfunktion!" -> "Habe ich: Kein vergleichbares Problem 
gefunden"

"RTFM" -> "Habe ich auch, inkl. Migration Note: Hier gibt es 
Unterschiede in den Quartzpin - Kapazitäten; sollte beim internen RC - 
Osci nicht relevant sein.

von Wolfgang (Gast)


Lesenswert?

Um genau zu sein, war es vorher der ATMEGA168A

von Frank K. (fchk)


Lesenswert?

Ist es ein 328 oder ein 328p? Wenn es ein 328 ist, probiere mal einen 
328p (neuerer Fertigungsprozess) aus.

Welche Betriebsspannung?

PS: Dass für einen 3mm*2.5mm SMD Quarz plus zwei 0402 Kondensatoren 
nicht noch irgendwo Platz ist, kann mir niemand erzählen.

fchk

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Frank K. schrieb:
> Welche Betriebsspannung?

Da würde ich auch das Problem vermuten.

Für die Spannung, für die die Kalibrierungsdaten ab Werk vorgesehen
sind, lässt sich eine asynchrone serielle Übertragung (die ja schon
garantiert mit 2 % Fehler klarkommt) normalerweise brauchbar
benutzen.

Wenn man aber von den 5 V abweicht, dann ist es halt Zufall, inwiefern
die Daten noch passen.  Das Minimum wäre dann wohl das Hinterlegen
eigener Kalibrierdaten im EEPROM, die man während der Board-Tests
ermittelt.  Besser noch wäre eine Kalibrierung zur Laufzeit.  Kann
man beispielsweise beim ersten einlaufenden Zeichen von der
Gegenseite machen (so ähnlich, wie die Modems ihre Baudrate auf das
"AT" angepasst haben, das vom Computer kam).

von Frank K. (fchk)


Lesenswert?

Im Datenblatt steht:

Factory Calibration: 8.0MHz 3V 25°C ±10%

3V als Referenz ist ja auch sinnvoll, da der Spannungsbereich ja von 
1.8V bis 5.5V geht und 3V dabei einigermaßen in der Mitte des Bereiches 
liegt.

fchk

von Wolfgang (Gast)


Lesenswert?

Hallo zusammen,

ich verwende 5V und kalibriere zur Laufzeit!

Erstaunlich ist, dass wenn ich die Kalibrierungszeit erhöhe, immer 
wieder Ausreißer sehe, die es eigentlich nicht geben dürfte.

Ich werde mal die Versorgungsspannung prüfen, ob die sauber ist.

von Wolfgang (Gast)


Lesenswert?

Versorgungsspannung ist sauber, 5V...

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Tritt den das gleiche Problem auf, wenn ein anderer Mega168 eingesetzt 
wird?

von Thomas E. (thomase)


Lesenswert?

Wolfgang schrieb:
> Hallo zusammen,
>
> ich verwende 5V und kalibriere zur Laufzeit!
>
> Erstaunlich ist, dass wenn ich die Kalibrierungszeit erhöhe, immer
> wieder Ausreißer sehe, die es eigentlich nicht geben dürfte.
>
> Ich werde mal die Versorgungsspannung prüfen, ob die sauber ist.

Gegen welche Zeitbasis kalibrierst du denn?

Gute Erfahrungen mit <1% habe ich mit Laufzeitkalibibrierung gegen 400€ 
bei 1200 Bit/s auf 7,3728MHz. Nicht ganz zufällig eine 
Baudratenfrequenz.
'€' = 0x80. Ergibt 8 aufeinanderfolgende Nullen, die man mit Pinchange 
am Tx-Pin und Timer1 sehr schön ausmessen kann. Vor allem bekommt man 
eine hohe Auflösung des Messwertes. Danach kann man auf jede beliebige 
Baudrate hochgehen.

> Ist es ein 328 oder ein 328p? Wenn es ein 328 ist, probiere mal einen
> 328p (neuerer Fertigungsprozess) aus.
Die sind auf gleichem Niveau. Eigentlich müsste der 328 328A und der 
328P 328PA heissen.


mfg.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Hallo zusammen,

ich kalibriere gegen das Startbit meines Protokolls. (ungefähr 5us lange 
Low Phase)

Die 168A sind die "Guten". Hier habe ich bauteilabhängig zwischen 0 und 
5% Ausfälle. Beides reproduzierbar. Es gibt 168er, die nie Datenpakete 
verlieren und dann gibt es wieder welche, die immer so bei 5% liegen.

Die 328er liegen bedauerlicherweise immer bei ca. 20%
Erstaunlich ist aber, dass wenn ich OSCCAL händisch setze (JTAG ICE 
mkII), ich das kalibrierte Ergebnis nur schlechter machen kann, was ja 
eigentlich bedeuten würde, dass mein Code schon den optimalen OSSCAL 
Wert findet!

von Thomas E. (thomase)


Lesenswert?

Wolfgang schrieb:
> Hallo zusammen,
>
> ich kalibriere gegen das Startbit meines Protokolls. (ungefähr 5us lange
> Low Phase)
Viel zu kurz.

> Die 168A sind die "Guten". Hier habe ich bauteilabhängig zwischen 0 und
> 5% Ausfälle. Beides reproduzierbar. Es gibt 168er, die nie Datenpakete
> verlieren und dann gibt es wieder welche, die immer so bei 5% liegen.
>
> Die 328er liegen bedauerlicherweise immer bei ca. 20%
> Erstaunlich ist aber, dass wenn ich OSCCAL händisch setze (JTAG ICE
> mkII), ich das kalibrierte Ergebnis nur schlechter machen kann, was ja
> eigentlich bedeuten würde, dass mein Code schon den optimalen OSSCAL
> Wert findet!

Bei den 328P, die ich hier habe, liegt der Factory-Wert um und bei 0x8A. 
Damit driftet man bei der Kalibrierung leicht in den Bereich <0x80. Das 
Bit7 des OSCCAL bestimmt die Auflösung der Kalibrierwertes. Bei den 
anderen Conrollern 168A/PA dito 88er liegt der Factory-Wert zw. 0xB0 und 
0xCF. Damit "trifft" er dann im Bereich >0x80 und die Fehlerrate ist 
geringer. Aber ich messe das auch in der Initialisierung des Controllers 
ein. Da nehme ich mir dann auch die Zeit, das mit einer längeren 0 bzw. 
gegen Timer2 mit Uhrenquarz einzumessen. Dann  kann man auch den OSCCAl 
einfach auf 0xFF setzen und ihn "runtertakten" lassen. Dann trifft er 
immer bei OSCCAL > 0x80.

Der Wert der dabei unter gleichen Spannungsbedingungen ermittelt wird, 
ergibt sich aber zuverlässig immer wieder. Die Temperatureinwirkung ist 
geringer als die der Spannung. Zumindest zwischen ca. -18° und 22°.
Einer festen Kalibrierung steht eigentlich nichts entgegen. Gerade wenn 
man auf Baudrate einstellt, ist der Fehler der grundsätzlich falschen 
Baudrate schon mal raus.

mfg.

: Bearbeitet durch User
von Jasch (Gast)


Lesenswert?

Also nachdem was das Datenblatt sagt ist das nicht ganz einfach, wobei 
ich glaube dass es zwischen einem 168 und einem 328 keinen prinzipiellen 
Unterschied geben sollte.

Punkt 1: der Frequenzbereich ist 7.3 - 8.1 MHz, d.h. nominell ist die 
Mittenfrequenz (was man sicher hinkriegen können sollte) nicht 8 sondern 
7.7 MHz

Punkt 2: siehe Doku zum Register OSCCAL, der Wert darin ist 
"zweigeteilt" und stellt zwei überlappende Frequenzbereiche dar, wobei 
Bit 7=0 den niedrigeren, Bit 7=1 den höheren Bereich angibt, aber 0x7F 
eine höhere Frequenz gibt als 0x80 - aber 0xFF eine noch höhere...

D.h. man kann den Registerwert nicht als Integer mit Vorzeichen 
behandeln und muss die Überlappung beachten.

Das ist der Punkt auf den ich als Ursache tippen würde.

von Peter D. (peda)


Lesenswert?

Nimmst Du eine echte RS232?

Bei USB-RS232 Umsetzern ist mir aufgefallen, daß die Bitzeiten schon 
einen sehr hohen Jitter haben. Vermutlich, weil sie kein Baudratenquarz 
als Zeitbasis benutzen.

von m.n. (Gast)


Lesenswert?

Nur als Beispiel für einen ext. Schwinger.
Die gibt es noch kleiner und günstiger, wenn man sich ein wenig 
umschaut.
http://www.reichelt.de/Filter/CSTCC-8-00/3/index.html?&ACTION=3&LA=446&ARTICLE=42491&GROUPID=3175&artnr=CSTCC+8%2C00

Vergiss den internen RCO für eine genaue+stabile Taktung.

von der alte Hanns (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Wolfgang schrieb:
>> Hallo zusammen,
>>
>> ich kalibriere gegen das Startbit meines Protokolls. (ungefähr 5us lange
>> Low Phase)
> Viel zu kurz.


Das sehe ich auch so: 5 us / 125 ns = 2.5 %.

von der alte Hanns (Gast)


Lesenswert?

reziprok (meinte ich)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jasch schrieb:
> Punkt 1: der Frequenzbereich ist 7.3 - 8.1 MHz, d.h. nominell ist die
> Mittenfrequenz (was man sicher hinkriegen können sollte) nicht 8 sondern
> 7.7 MHz

Falsche Annahme.

Der Wert wird nur deshalb so angegeben, weil damit der garantierte
Bereich sowohl die Einstellbarkeit von 8,0 MHz als auch der
„Baudratenfrequenz“ 7,3728 MHz gewährleistet.  Weitergehende Zusagen
will man einfach nicht machen.

Der typische Abstimmbereich des Oszillators steht im Datenblatt, aber
er ist halt nicht garantiert.  Er umfasst etwa 4 bis 12 MHz.
Interessanterweise geht der Bereich beim ATmega168 offenbar höher
(etwa 14 MHz) als bei den anderen Familienmitgliedern.

Da Wolfgang den Oszillator ja selbst kalibriert, würde ich auch ein
Problem mit dem ‚Sprungverhalten‘ um den OSCCAL-Wert 0x80 herum
vermuten.  Es ist nicht ganz einfach, für diese nicht-eineindeutige
Abbildung einen Algorithmus zu entwickeln, der unter allen Umständen
stabil ist (been there, done that).

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Es gäbe da noch eine Notlösung:

Teile jedes zu versendende Byte in zwei Halbbytes und versende diese. 
Beim Empfang ignorierst du immer die höherwertigen 4 Bits und baust aus 
jeweils zwei Halbbytes wieder ein Byte zusammen.

Das Verfahren ist auch robust auch bei größeren Taktschwankungen.

Wenn du willst, kannst du Bit 4 (das 5. von rechts) als Kennzeichen 
nutzen, ob das betreffende Halbbyte ein Low- oder ein High-Halbbyte ist.

von der alte Hanns (Gast)


Lesenswert?

Nochmal: bei 5 us und 8 MHz kann die Genauigkeit doch bestenfalls bei 
2.5 % liegen, je nach Algorithmus wohl eher 5.0 oder gar 7.5 %.
Oder irre ich mich?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

der alte Hanns schrieb:
> bei 5 us und 8 MHz kann die Genauigkeit doch bestenfalls bei 2.5 %
> liegen

Wenn man oft genug misst (mit verschiedenen Werten von OSCCAL), sollte
sich auch die Mitte des möglichen Bereichs finden lassen (und damit
eine bessere Genauigkeit als 2,5 %), aber es stimmt schon, das ist
ziemlich knapp alles.

von der alte Hanns (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Wenn man oft genug misst

Damit wird dann aber das Messintervall ein Mehrfaches von 5 us.


Was heißt eigentlich 'Laufzeitkalibrierung' genau? Wird da ein 
gleitender Mittelwert über mehrere Datenpakete gebildet? Oder immer nur 
einmalig für das nachfolgende Datenpaket - dann stellt sich mir die 
Frage, wie lange der Oszillator zum Einschwingen braucht.

von Frank K. (fchk)


Lesenswert?

Ich weiß nicht, ob es hier hilft, aber nur mal so als Idee:

LIN (www.lin-subbus.org) ist mit dem Ziel entworfen worden, dass die 
Slaves keinen Quarz benötigen. LIN-Frames starten mit einem BREAK, d.h. 
einem Low-Signal von mindestens 13 Bitlängen gefolgt von einem 
Synchronbyte 0x55. Dieses Synchronbyte ist für die Bitratenermittlung 
der Slaves gedacht.

Schau Dir das mal an, vielleicht findest Du ja einen LIN-Stack, wo Du 
das abschauen kannst.

fchk

von Falk B. (falk)


Lesenswert?

Ich würde auch sagen, der Fehler liegt bei der Autobauderkennung.
Kann man leicht prüfen.

Man generiert einen festen Ausgangstakt über die Output-Compare 
Funktion. Damit kann man direkt und sehr einfach den CPU-Takt messen. 
Oder über die Clock Out Fuse, wenn der AVR diese hat. Damit sieht man 
das Ergebnis der Autobauderkennung und RD-Oszillatorkalibrierung.

Nun lässt man das Programm laufen und erzwingt definiert die Autobaud 
Funktion. Wahrscheinlich sind die Ergebnisse der Frequenzmessung stark 
fehlerbehaftet.

Als Gegenbeweis, dass der RC-Oszillator es besser kann, verstellt man 
dessen Kalibrierung manuell. Damit kann man ihn auf <1% Fehler 
abgleichen und der UART läuft stabil und fehlerfrei.

Ich hatte mal ein Projekt, wo nur ein 32k Uhrenquarz am Controller hing, 
aber dennoch 115k2 per UART genutzt worden. Eine automatische 
Kalibrierung per Timer war spielend leicht und immer exakt. Die 
Kalibrierung lief dauerhaft, damit konnte man auch Temperaturdriften 
kompensieren (hab ich aber nicht getestet).

Autobaud mit nur EINEM Zeichen sollte man mit möglichst geringer 
Baudrate machen, um den systematischen Fehler zu senken. Das Ganze per 
ICP macht es noch deutlich genauer, wenn gleich Polling per CPU zur Not 
auch geht.

von PeterL (Gast)


Lesenswert?

Wir hatten schon ziemlich alle Osccalwerte von h43 bis h95 (beim 
Atmega164).
Als Übergangslösung bis alles auf Quarz umgestellt war haben wir die 
Controller per Hand selektiert.Die bösen mit Oscalwerten unter h50 
wurdenfür andere Projekte verwendet.

von Falk B. (falk)


Lesenswert?

@ PeterL (Gast)

>Wir hatten schon ziemlich alle Osccalwerte von h43 bis h95 (beim
>Atmega164).
>Als Übergangslösung bis alles auf Quarz umgestellt war haben wir die
>Controller per Hand selektiert.Die bösen mit Oscalwerten unter h50
>wurdenfür andere Projekte verwendet.

Was ist an einem Wert unterhalb 0x50 böse? Eben WEIL kalibriert wird, 
spielt der Fehler des RC-Oszillators keine Rolle!

von Wolfgang (Gast)


Lesenswert?

Hallo zusammen,

vielen Dank für die vielen Gedanken und Vorschläge!

Was ich ausschließen kann, ist das "Rutschen" des OSCCAL Wertes unter 
0x80. Ich habe mehrere 328er die dasselbe Verhalten zeigen. Einen davon 
habe ich dann mit DebugWire konfiguriert und konnte sehen, dass OSCCAL 
nach dem Reset 0x9C war. Der kalibrierte Wert lag dann immer bei 0x92 - 
0x93.

Das mein Kalibrierungssignal mit 5us sehr kurz ist, ist mir bewusst, 
jedoch musste die Kalibrierung in ein bestehendes System integriert 
werden, ohne die Möglichkeit den Sender anzupassen. Es handelt sich 
nicht um die UART, sondern um ein in Software abgebildetes Busprotokoll, 
welches ca. 300kB macht. Das Referenzsignal wird von einem 328er mit 
16MHz Quarz erzeugt. Das Protokoll hat eigentlich den Takt in die Daten 
integriert, sprich es werden immer High Pulse variabler Länge, gefolgt 
von einer Low Phase mit definierter Länge erzeugt. Die Länge des High 
Pulses definiert ob eine "1" oder "0" übertragen wurde. Lediglich das 
Startbit ist etwas länger, so dass alle Controller die Empfangsroutine 
erreichen können und dieses wurde zum kalibrieren missbraucht.

Wie es scheint, liegt das Problem nicht an meinem Kalibrierungscode, 
weil ich auch nicht fähig war manuell bessere Werte zu setzen.

Kann es sein, dass der Oscillator nicht stabil läuft?

Ich habe in Erinnerung, dass beim Verändern des OSCCAL Registers man 
immer zwei Schritte vor und einen zurück machen soll, sonst kann es 
passieren, dass der Controller, den einen Schritt nicht übernimmt. 
(Steht in ner AppNote) Kann es sein, dass beim 328 hier noch etwas zu 
beachten ist?

Ich werde heute noch verschiedene Typen von 168 und 328 bestellen und am 
Wochenende testen. (habe mir Gott sei Dank letzte Woche einen Nullkraft 
Sockel geleistet :-) )

von holger (Gast)


Lesenswert?

>Ich werde heute noch verschiedene Typen von 168 und 328 bestellen und am
>Wochenende testen.

Bestell gleich nochn paar Quarze mit. Für den ganzen Aufwand den du bis
jetzt betrieben hast hättest du vermutlich locker schon 1000Stück
kaufen können.

von Wolfgang (Gast)


Lesenswert?

Bitte die Anforderung, dass keine Quarze in Frage kommen, zu 
akzeptieren.

von holger (Gast)


Lesenswert?

>Bitte die Anforderung, dass keine Quarze in Frage kommen, zu
>akzeptieren.

Wenn es nicht geht, geht es nicht.
Bitte akzeptieren das eine Fehlentwicklung stattgefunden hat.
Wie viel Kohle willst du da noch reinstecken?

von Thomas E. (thomase)


Lesenswert?

Wolfgang schrieb:

> Das mein Kalibrierungssignal mit 5us sehr kurz ist, ist mir bewusst,
> jedoch musste die Kalibrierung in ein bestehendes System integriert
> werden, ohne die Möglichkeit den Sender anzupassen. Es handelt sich
> nicht um die UART, sondern um ein in Software abgebildetes Busprotokoll,
> welches ca. 300kB macht. Das Referenzsignal wird von einem 328er mit
> 16MHz Quarz erzeugt. Das Protokoll hat eigentlich den Takt in die Daten
> integriert, sprich es werden immer High Pulse variabler Länge, gefolgt
> von einer Low Phase mit definierter Länge erzeugt. Die Länge des High
> Pulses definiert ob eine "1" oder "0" übertragen wurde. Lediglich das
> Startbit ist etwas länger, so dass alle Controller die Empfangsroutine
> erreichen können und dieses wurde zum kalibrieren missbraucht.

Was heisst denn jetzt variable Länge? Von-bis und alles dazwischen?
Doch wohl jeweils definierte Länge für 0 und 1?
Dann verstehe ich allerdings nicht, warum du überhaupt kalibrierst. Den 
Unterschied zwischen kurz und lang kann der Empfänger doch auch so 
erkennen. Denn der oszillator läuft sehr stabil. Solange sich Spannung 
und Temperatur nicht ständig drastisch ändern. Also nicht von heute auf 
morgen sondern von jetzt auf gleich.
Es sei denn der Unterschied ist einfach zu gering. Aber dann hat man an 
der PWM grundsätzlich was falsch gemacht. Oder dein Controller läuft mit 
8MHz einfach zu langsam, sodaß der Unterschied zwischen 0 und 1 einfach 
nicht signifikant genug ist. Daran würde ein 8MHz-Quarz dann aber auch 
nichts ändern. Ein 20MHz-Quarz aber schon. Auch wenn es keine Option 
ist. Aber wenn dem so ist, kann man nur Holgers letzter Aussage 
zustimmen.

mfg.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Genau, es handelt sich um definierte Längen!
Der ursprüngliche Plan war natürlich, dass man keine Kalibrierung 
benötigt. Da man mit 8MHz und 300kB/s in Software (gerade bei einem 
Signal mit doppelter Bandbreite) schon recht am Limit ist, ist mir 
bewusst.
Leider gab es ja immer wieder Probleme, die mit kalibrierten 
Oszillatoren aber minimiert werden konnten. Mit dem 168er funktionierte 
es ja wirklich gut! Einzig der 328er macht jetzt Probleme.

Das man mit ausreichender Hardware viele Probleme erschlagen kann, ist 
klar. Ich hätte auch einen eigenen uC nur für die Kommunikation nehmen 
können, dann hätte ich mir auch viele Probleme mit der 
Interruptpriorisierung, Fehlererkennung und -korrektur sparen können, 
aber die Anforderung war eben eine Singlechip Lösung aus genannten 
Gründen. Ich muss diese Controller auf Platinen verbauen, die teilweise 
unwesentlich größer sind als der Controller! Daran kann ich nichts 
ändern! Ich musste bei einer Platine sogar die TVS Diode im SOT23-3 
weglassen, weil ich meine Leiterbahnen nicht mehr unterbringen könnte. 
Das ist nun mal eine harte Anforderung!

Die ursprüngliche Frage war ja: gibt es bekannte Unterschiede in den 
Oszillatoren? Hat jemand ähnliche Erfahrungen und/oder Lösungen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wolfgang schrieb:
> Die ursprüngliche Frage war ja: gibt es bekannte Unterschiede in den
> Oszillatoren?

Offensichtlich, siehe die typischen Daten im Datenblatt.  Der
Oszillator des '168 lässt sich typisch bis 14 MHz ziehen, die anderen
nur bis 12 MHz.  Warum dieses Detail aber gerade in deinem Falle
entscheidend sein sollte, nun, das wirst du nur selbst messen können.
Falk hat ja schon Vorschläge gemacht (CKOUT abgreifen und messen).

Wolfgang schrieb:
> Kann es sein, dass der Oscillator nicht stabil läuft?

Auch das solltest du messen können.  Sicher, es ist ein RC-Oszillator,
insofern ist er zwangsläufig instabiler als ein Quarzoszillator.
Inwiefern nun seine Kurzzeitstabilität anders ist als bei den anderen
AVRs, das musst du ggf. einfach mal nachmessen.  Oszilloskope sind
ja schon eine Weile erfunden, und seit sie digital sind, beherrschen
sie auch Features wie Persistenz.

von Jasch (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Jasch schrieb:
>> Punkt 1: der Frequenzbereich ist 7.3 - 8.1 MHz, d.h. nominell ist die
>> Mittenfrequenz (was man sicher hinkriegen können sollte) nicht 8 sondern
>> 7.7 MHz
>
> Falsche Annahme.
>
> Der Wert wird nur deshalb so angegeben, weil damit der /garantierte/
> Bereich sowohl die Einstellbarkeit von 8,0 MHz als auch der
> „Baudratenfrequenz“ 7,3728 MHz gewährleistet.  Weitergehende Zusagen
> will man einfach nicht machen.

Naja, "garantiert" hat schon einen netten Klang...

> Der typische Abstimmbereich des Oszillators steht im Datenblatt, aber
> er ist halt nicht garantiert.  Er umfasst etwa 4 bis 12 MHz.
> Interessanterweise geht der Bereich beim ATmega168 offenbar höher
> (etwa 14 MHz) als bei den anderen Familienmitgliedern.

Interessant, das hatte ich garnicht gesehen, ist ja ein hübsch grosser 
Bereich.

Vielleicht sind ja die 328 aus einer Charge die halt nicht so hoch 
hinaus kommt wie "typisch" sein sollte?

von spess53 (Gast)


Lesenswert?

Hi

> Der typische Abstimmbereich des Oszillators steht im Datenblatt, aber
> er ist halt nicht garantiert.  Er umfasst etwa 4 bis 12 MHz.
> Interessanterweise geht der Bereich beim ATmega168 offenbar höher
> (etwa 14 MHz) als bei den anderen Familienmitgliedern.

Hier werden teilweise Äpfel mit Birnen verglichen. Das Diagramm vom 
ATMega328 stammt von einem P-Typ, das vom ATMega168 von einem PA-Typ. 
Und das geht bis 14 MHz. Bei einem ATMega168P geht der Einstellbereich, 
genau wie beim ATMega328P, auch nur bis 13 MHz.

MfG Spess

von Oliver (Gast)


Lesenswert?

Wolfgang schrieb:
> Das Protokoll hat eigentlich den Takt in die Daten
> integriert, sprich es werden immer High Pulse variabler Länge, gefolgt
> von einer Low Phase mit definierter Länge erzeugt. Die Länge des High
> Pulses definiert ob eine "1" oder "0" übertragen wurde. Lediglich das
> Startbit ist etwas länger, so dass alle Controller die Empfangsroutine
> erreichen können und dieses wurde zum kalibrieren missbraucht.

Hm...

300kB mit Bitwert im high, und festem "low-Takt" ergibt bei 8MHz CPUtakt 
im Mittel 13,3 Takte jedes high bzw. low. Also z.B 13 Takte low, 6,5 
Takte für high_0, und 19,5 Takte für high_1. Ist das in etwa so?

Das per Software-Sampiling abzutasten, ist m.E. sportlich (ih bin aber 
auch nur Diletant in dem Geschäft...). Ob der Oszillator dabei etwas 
schneller oder langsamer läuft, spielt aber nur eine Rolle, wenn die 
Unterschiede zwischen high_0 und high_1 entweder sehr klein gewählt 
worden wären, oder man nicht zwischendurch mal auf eine der low-Flanken 
synchronisiert.

Wie funktioniert denn die Dekodierung?
Wenn du mit festen Zyklen ohne Zwischensynchronisation abstatestest, ab 
welcher Bitzahl bekommst du Bitfehler alleine aus der begrenzten 
Genauigkeit der 5us-Kalibrierung?

Oliver

von der alte Hanns (Gast)


Lesenswert?

Oliver schrieb:
> Ob der Oszillator dabei etwas
> schneller oder langsamer läuft, spielt aber nur eine Rolle, wenn die
> Unterschiede zwischen high_0 und high_1 entweder sehr klein gewählt
> worden wären, oder man nicht zwischendurch mal auf eine der low-Flanken
> synchronisiert.


Volle Zustimmung.

Man kann doch bei jedem einzelnen Bit auf die steigende Flanke 
synchronisieren. Und dann sollten die wenigen Prozent einer Kalibrierung 
keine Rolle spielen, der Werkswert für OSCCAL muss reichen.
Ich sehe das Problem in der Decodierung und in der Nachbearbeitung, da 
ist bei insgesamt rund 27 Takten nicht viel Spielraum.
Prinzipiell aber ist das machbar, auch ohne die genannte Fehlerquote von 
5 %.

von Wolfgang (Gast)


Lesenswert?

Hallo zusammen,

ich habe nun verschiedene uC getestet und bin mittlerweile ziemlich 
sicher, dass es nicht am Oscillator liegt! CKOUT zeigt recht genaue 8MHz 
Werte.

Mittlerweile habe ich auch schon überlegt, ob der Code für die 32k 
Variante buggy sein könnte, aber jetzt kommts: Mein Code mag auch auf 
anderen 168er Variante (A,P,V) nicht so recht...

Unterschiedliche H/L Schwellwerte kann man ausschließen, da das Signal < 
50ns Rise- und Falltime hat.

Bin mittlerweile echt ratlos...

Edit: Problem höchstwahrscheinlich gefunden: Der Oszillator beim 
168-20MU scheint stabiler zu sein, als bei den anderen Varianten...

von der alte Hanns (Gast)


Lesenswert?

Ich bin fest überzeugt, dass Ihr Programm fehlerhaft ist, was auch die 
für mich unerklärbare Fehlerquote bei den 168ern zeigt.

Ich hatte einen Probeaufbau zusammengesteckt, in Ermangelung von 
ATmega328 nahm ich 2 ATmega644, wie von Ihnen vorgegeben der Sender mit 
16 MHz Quarz, der Empfänger mit den internen 8 MHz. Statt Ihrer 
variablen Bitlänge arbeitete ich mit einer festen:

'0': 500 ns high, 1125 ns low
'1': 1125 ns low, 500 ns high

Das ergibt eine reine bit-Rate von 615 kbit/s, mit einer 
Byte-Aufbereitung kam ich auf 70 kByte/s.

Die Übertragung lief absolut fehlerfrei, und das, wohlgemerkt, bei einer 
Frequenztoleranz von +/- 10 %, also im Bereich 7.2 - 8.8 MHz.

Fazit: nehmen Sie die unnötige Justierung ('Kalibrierung') von OSCCAL 
heraus und triggern Sie bei jedem einzelnen bit auf die Startflanke.

von der alte Hanns (Gast)


Lesenswert?

Sorry, trotz Korrekturlesen:

'1': 1125 ns high, 500 ns low

muss es heißen!

von Wolfgang (Gast)


Lesenswert?

Hallo Herr Hanns,

jetzt bin ich gerade beeindruckt, dass Sie wegen mir eine 
Versuchsanordnung aufgebaut haben.

Ich triggere natürlich auf die steigende Flanke! Ich kann aber natürlich 
auch nicht ausschließen, dass es noch irgendwo einen Fehler und einen 
Störeinfluss gibt!

Was ich mich aber frage, wie Sie in 500ns einen Bitwert verarbeiten bzw. 
das fertige Byte wegschreiben? Das sind immerhin nur mehr 4 cycles!

Ich werde mich kommendes Wochenende mit dem Code auseinandersetzen!

VG, Wolfgang

von der alte Hanns (Gast)


Lesenswert?

Nur als Denkanstoss, ohne weiteren Kommentar, vielleicht hilft es Ihnen 
ja.

.def tmp3 = r14
.def tmp0 = r16
.def count = r24

.equ PIN_serialin =PIND
.equ serialin = 6

.macro bit
    sbic PIN_serialin,serialin
   rjmp pc-1
    sbis PIN_serialin,serialin
   rjmp pc-1
   sbrc tmp0,serialin
    inc tmp3
   lsl tmp3
   in tmp0,PIN_serialin
.endmacro

in_loop:
   clr tmp3
   bit
   bit
   bit
   bit
   bit
   bit
   bit
   bit
   sbrc tmp0,serialin
    inc tmp3
   st z+,tmp3
   inc count
   breq pc+2
 rjmp in_loop

von der alte Hanns (Gast)


Lesenswert?

Wolfgang schrieb:
> Was ich mich aber frage, wie Sie in 500ns einen Bitwert verarbeiten bzw.
> das fertige Byte wegschreiben? Das sind immerhin nur mehr 4 cycles!


Für das Byte muss der Sender natürlich eine kurze Sendepause einlegen, 
deshalb komme ich auch nur auf 70 kByte/s und nicht auf 76.9 = 615/8.

von Wolfgang (Gast)


Lesenswert?

Aja, dann kann ich es nachvollziehen ... Und Sie haben 0% Fehler??

Dann muss ich da wohl nochmal ran!

Vielen Dank für Ihre Mühe!

von der alte Hanns (Gast)


Lesenswert?

Wolfgang schrieb:
> Aja, dann kann ich es nachvollziehen ... Und Sie haben 0% Fehler??


Es lief fehlerfrei mit etwas unter 7.2 und etwas über 8.8 MHz jeweils 
eine Kaffeepause lang.


Ich wünsche Ihnen gutes Gelingen.

von Wolfgang (Gast)


Lesenswert?

Hallo zusammen,

alter Hanns, dein Tipp war schon richtig!

Ich habe einen Fehler in Software gefunden! Zwar war mein Protokoll 
sauber, es wurde richtig auf die Flanken getriggert und zum richtigen 
Zeitpunkt abgetastet, ABER eine Konstellation aus verschiedenen 
Altlasten hat mir einen Fehler erzeugt:

Ich schalte nach dem Empfangen den Empfänger über den Interrupt ab und 
arbeite das Datenpaket ab. Sollte die Ausführungszeit mal nicht reichen, 
zerstört mir ein neu hereinkommendes Datenpaket zumindest nicht das 
aktuelle und die Daten bleiben (bis auf das verloren gegangene 
Datenpaket) konsistent.

Die Funktion zum Einschalten des Empfängers löscht zuerst das Interrupt 
Flag, um nicht fälschlicherweise (das Empfangen in Software setzt ja 
auch das IF) den Empfänger zu starten und aktiviert danach den 
Interrupt.

Da ein fehlerhaftes Datenpaket aber auch den Empfänger deaktiviert, aber 
in weiterer Folge nicht abgearbeitet wird, habe ich in einer Quick & 
Dirty Lösung damals meine "EnableReceiver" Funktion in einer Schleife 
gebaut.

Was nun passiert ist, dass in einer Schleife >>dauernd das IF Flag 
gelöscht<<, der Interrupt konfiguriert und aktiviert wird.

Meiner Interpretation nach kann das den Interrupt, wenn er zu einem 
ungünstigen Zeitpunkt ausgelöst wird, unterdrücken.

Warum sich das auf verschiedenen Chip Typen anders verhält, weiß wohl 
nur ATMEL, wundert mich jetzt aber auch nicht weiter...

Auf alle Fälle läuft mein Protokoll nun stabil (keine Fehler bei über 
200k Datenpaketen)!!

Zum einen vielen Dank an "der alte Hanns", der mich zur richtigen Stelle 
geführt und mich mittels eines eigens aufgebauten Testszenarios 
überzeugt hat, das richtige zu tun.

Auch den anderen einen herzlichen Dank!

@Holger: es freut mich im Nachhinein, dass du nicht recht hattest...

von Axel R. (Gast)


Lesenswert?

ich finde das mit dem "Sie" sehr gut. Es verleiht der Unterhaltung ein 
gewissen Niveau und zeugt von gegeseitigem Respekt. Ich werde das in 
Zukunft ebenso "hannshaben".

Daumenhoch, viele Grüße
Axelr.

von Falk B. (falk)


Lesenswert?

@ Axel R. (axelr)

>ich finde das mit dem "Sie" sehr gut. Es verleiht der Unterhaltung ein
>gewissen Niveau und zeugt von gegeseitigem Respekt.

Biedermeierzeit reloaded?

von Oliver S. (oliverso)


Lesenswert?

Wolfgang schrieb:
> Ich habe einen Fehler in Software gefunden!

Wer hätte das gedacht...

Oliver

von c-hater (Gast)


Lesenswert?

Wolfgang schrieb:

> Das Protokoll hat eigentlich den Takt in die Daten
> integriert, sprich es werden immer High Pulse variabler Länge, gefolgt
> von einer Low Phase mit definierter Länge erzeugt. Die Länge des High
> Pulses definiert ob eine "1" oder "0" übertragen wurde.

Da ist tatsächlich der Takt redundant in den Daten enthalten. Warum zum 
Teufel wird diese Eigenschaft dann nicht genutzt?

Täte man das, wäre die Taktrate komplett irrelevant, eine Kalibrierung 
(zumindest für den Empfang) völlig überflüssig und damit dein ganzes 
Problem überhaupt nicht existent.

von Wolfgang (Gast)


Lesenswert?

Also die letzten beiden Kommentare wieder...

@Oliver? Wie erklärt sich nun der Unterschied zwischen den Chiptypen?

@c-hater: Hättest du den Thread gelesen, würdest du wissen, das dies 
getan wird. Gab aber eben trotzdem Probleme, da die ganze Sache (steht 
ebenfalls auch im Thread) schon recht sportlich ist!

von Falk B. (falk)


Lesenswert?

@ c-hater (Gast)

>Da ist tatsächlich der Takt redundant in den Daten enthalten.

Das ist bei JEDER asynchronen Datenübertragung so . . .

von c-hater (Gast)


Lesenswert?

Falk Brunner schrieb:

> Das ist bei JEDER asynchronen Datenübertragung so . . .

Nein. Es gibt sehr viele asynchrone Verfahren, bei denen nur Teile des 
Taktes im Signal stecken. Typisches Beispiel: RS232.

Und genau nur bei denen ergibt eine lokale Taktgenerierung und damit 
verbundene Sachen wie eine Kalibrierung und Synchronisierung dieses 
lokalen Taktes einen Sinn.

Bei Verfahren mit vollständigem Taktsignal hingegen nicht. Und das 
beschriebene Protokoll ist ja geradezu ein Paradebeispiel für ein 
solches Verfahren. Es gibt Verfahren, da ist das nicht ganz so 
offensichtlich.

von Falk B. (falk)


Lesenswert?

@c-hater (Gast)

>> Das ist bei JEDER asynchronen Datenübertragung so . . .

>Nein. Es gibt sehr viele asynchrone Verfahren, bei denen nur Teile des
>Taktes im Signal stecken. Typisches Beispiel: RS232.

Krümelkacker. Dass der Empfänger IMMER eine Taktrückgewinnung machen 
muss, ist doch wohl klar. Ob er auf jedes Bit oder nur jedes Byte oder 
noch größere Datenpakete synchronisieren kann, ist eine andere Frage.

>Und genau nur bei denen ergibt eine lokale Taktgenerierung

Nö, die gibt es immer, nur halt in verschiedenen Ausprägungen.

>Bei Verfahren mit vollständigem Taktsignal hingegen nicht.

Doch. Auch wenn es scheinbar schon da ist.

von Oliver S. (oliverso)


Lesenswert?

Wolfgang schrieb:
> @Oliver? Wie erklärt sich nun der Unterschied zwischen den Chiptypen?

Keine Ahnung. Aber mit an Sicherheit grenzender Wahrscheinlichkeit ist 
auch das ein Progarmmierfehler.

Oliver

von c-hater (Gast)


Lesenswert?

Falk Brunner schrieb:

> Doch. Auch wenn es scheinbar schon da ist.

Naja, irgendwie ist tatsächlich immer der Vergleich mit einem 
"Referenztakt" erforderlich, auch wenn der Takt vollständig geliefert 
wird, da hast du eindeutig Recht.

Ich korrigiere mich also dahingehend, daß die beschriebene Kalibrierung 
unsinnig ist. DAS ergibt nur dann einen Sinn, wenn das Taktsignal der 
Quelle nicht vollständig verfügbar ist und deshalb eine sozusagen 
"freilaufende" Referenz benötigt wird.

Können wir uns darauf einigen?

von Falk B. (falk)


Lesenswert?

@ c-hater (Gast)

>Naja, irgendwie ist tatsächlich immer der Vergleich mit einem
>"Referenztakt" erforderlich, auch wenn der Takt vollständig geliefert
>wird, da hast du eindeutig Recht.

AKA CDR, clock and data recovery.

>Ich korrigiere mich also dahingehend, daß die beschriebene Kalibrierung
>unsinnig ist. DAS ergibt nur dann einen Sinn, wenn das Taktsignal der
>Quelle nicht vollständig verfügbar ist und deshalb eine sozusagen
>"freilaufende" Referenz benötigt wird.

Die wird immer benötigt, alles nur eine Frage der Kurzzeitstabilität. 
Beim Manchestercode hat man nach jedem Bit eine Synchronmarke, bei UART 
muss man 10 Bit kurzzeitstabil sein, beim good ole PAL muss es eine 
Zeile a 64us stabil sein.

>Können wir uns darauf einigen?

OK.

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.