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.
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
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).
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
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.
Tritt den das gleiche Problem auf, wenn ein anderer Mega168 eingesetzt wird?
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
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!
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
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.
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.
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.
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 %.
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).
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.
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?
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.
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.
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
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.
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.
@ 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!
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 :-) )
>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.
Bitte die Anforderung, dass keine Quarze in Frage kommen, zu akzeptieren.
>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?
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
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.
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.
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?
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
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
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 %.
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...
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.
Sorry, trotz Korrekturlesen: '1': 1125 ns high, 500 ns low muss es heißen!
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
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
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.
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!
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.
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...
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.
@ 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?
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.
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!
@ c-hater (Gast)
>Da ist tatsächlich der Takt redundant in den Daten enthalten.
Das ist bei JEDER asynchronen Datenübertragung so . . .
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.
@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.
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
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?
@ 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.