Guten abend ich habe Probleme mit meiner UART
Ich habe ein Programm auf einem Atmega8 mit 1000000Mhz laufen und einer
Baudrate von 4800.
Ich sende dann hex zahlen an den Atemga8 mit Hterm bzw realterm. Diese
zahlen empfange ich per Interrupt auif dem Atmega8 und verarbeite sie in
der ISR mit eienr Statemaschiene (die ich hier nicht öffentlich zeigen
will, ichmache dort allerdings nichts aufregendes ausser die Globale
Variable ProtocolStM_u8 zu setzen und das selbe mit den errorbits.)
Mit jedem empfangegen Byte schicke ich als response 3 byte zurueck .
Den aktuellen Zustand, ein leerzeichen (0x20) und die Errorbits.
Mein Problem ist wenn ich den ganzen hex string (10 Byte ) auf einmal
schicke, bekomme ich nur 7 responde also (21Byte) zurueck
Schicke ich aber zuerst die ersten 5 Byte des hex Strings und dann die
zweiten 5Byte bekomme ich 2 mal 5 Responde zurueck.
Im Incorrect Screenshot is nur die 2Hälfte des hexStrings zu sehen. Die
erste hatte ich aber auch geschickt!
ich tippe auf ein Timing Problem dass die ISR mit dem senden der reponse
Byte zulange braucht und deshalb ankommende Bytes verschluckt...habt ihr
eine Idee?
Du rufst aus deiner Empfangs-ISR die Funktion USART_Transmit auf, die
wartet(!), bis das Byte auch versendet wurde. Während einer ISR sind
Interrupts deaktiviert, darum gehen die anderen auch verloren.
Schalte den Sendeinterrupt ein und immer, wenn ein Byte fertig
übertragen wurde (der Interrupt feuert), startest du die Übertragung des
nächsten Bytes. Kann sein, dass du dir dafür einen kleinen Ringpuffer
o.ä. basteln musst.
>ich tippe auf ein Timing Problem dass die ISR mit dem senden der reponse>Byte zulange braucht und deshalb ankommende Bytes verschluckt...habt ihr>eine Idee?
Natürlich werden Bytes verschluckt wenn deine Response länger
dauert als ein Byte zu empfangen. Es ist also Schwachsinn was
du da machst. Denk dir was anderes aus.
Danke erstmal für die Antworten... aber das kuriose ist ja dass ich
überhaupt was empfange und raussende... und das immerhin zu 7
response.... müsste dann eig garnichts funktionieren?
Tobi88 schrieb:> Ich habe ein Programm auf einem Atmega8 mit 1000000Mhz laufen
Wo zum Teufel hast du einen derart schnellen AVR aufgetrieben? Meine
strecken allesamt allerspätestens bei 26..27MHz die Waffen...
> verarbeite sie in> der ISR mit eienr Statemaschiene (die ich hier nicht öffentlich zeigen> will
Dann ist sie wohl so Scheiße, daß es dir hinreichend peinlich ist. Also
verbessere sie soweit, bis du sie veröffentlichen kannst. Mit ein bissel
Glück ist eine Veröffentlichung dann garnicht mehr nötig, weil du den
Fehler bereits gefunden hast...
Tobi88 schrieb:> Danke erstmal für die Antworten... aber das kuriose ist ja dass ich> überhaupt was empfange und raussende... und das immerhin zu 7> response.... müsste dann eig garnichts funktionieren?
Dein AVR kann EIN Zeichen buffern.
D.h. während du das erste Zeichen verarbeitest, kann das 2.te Zeichen in
die UART reinkommen.
Aber: Auch dieses muss verarbeitet werden. Während das passiert, kann
das 2. Zeichen in die UART eingetaktet werden. Aber! Die Zeit, die dafür
zur Verfügung steht ist jetzt bereits kürzer als beim allerersten
Zeichen. Denn das allererste Zeichen wurde ja sofort nach seinem
Eintreffen bearbeitet. Das 2.te Zeichen musste schon ein wenig warten.
Das 3. Zeichen muss noch länger warten.
Und irgendwann reicht das dann eben nicht mehr und ein Zeichen wird in
der UART überscchrieben, weil der Bufferplatz von einem zeichen dann
eben nicht mehr ausreicht.
Hol dir vom Peter Fleury die UART Library. Die hat wenigstens eine
sinnvolle UART Interrupt-Steuerung samt Ringbuffer.
Also mir wurde beigebracht, dass die ISR immer so kurz und schnell wie
möglich sein sollen -> in deinem Fall das empfangene Byte in einen
Ring-buffer schreiben und im main dann auf einen Index abfragen ob ein
unverarbeitetes Byte vorhanden ist. Dann spielts auch keine Rolle, wenn
mehrere Bytes gepuffer werden.
Anhand der Baudrate kann man errechnen dass alle ~2ms ein neues Zeichen
ankommt, und da du deine Empfangs-ISR über die UART_Transmitt Funktion
ausbremst, wird das nie etwas. Obwohl die 2ms eigentlich locker reichen
sollten für eine riesige State-Machine (deren Sinn und Zweck mehr als
fragwürdig ist).
Da mir die 1000000Mhz ohne Stickstoffkühlung etwas zu hoch erscheinen,
könnte es sein, dass 1MHz bzw. 1000000Hz gemeint war?
Und wenn ja stellt sich mir allerdings die Frage: Warum fährst Du mit
angezogener Handbremse? Ein bissel (viel) was schneller kann der ATMega8
schon. Oder ist das auch geheim?
Als Nick "Amateur" verwenden und dann über einen Tippfehler lustig
machen.
Aber ich habe schon gemerkt, dass es hier im Forum einige Leute gibt die
sich über öffensichtliche Tippfehler amüsieren aber keinerlei
produktiven Beitrag leisten....
Lieber Amatuer jetzt auch für dich ja es waren 1Mhz gemeint!....und ja
ich könnte ihn auch mit 12Mhz oder mit16 Mhz betreiben. Allerdings
möchte ich den Atmega8 mit einem Akku betreiben und ggf auf den Atmega8L
bzw. Atmega8A ausweichen. GGF auch auf die entsprechenden Gegenstücke
vom Atmega88.
Dort ist der Stromverbrauch bzw. die minimale Versorgungsspannung
abhängig vom Takt.
P.S. über einen Attiny habe ich auch schon nachgedacht, allerdings
kommen diese derzeit nicht in Betracht da ich noch diverse Funktionen
implementieren möchte die verschiedene HW-Komponenten erfordern
Allerdings möchte ich mich herzlich bei Karl Heinz und bei Svenska
bedanken da ihre Antworten mir geholfen haben mein Problem zu lösen.
Hi
Nur mal kurz... Warum regst du dich über den hinweis von 1 THz auf? Es
ist nicht unerheblich, welche Taktfrequenz und welche Baudrate. Außerdem
läßt 1 MHz die Vermutung zu, das du mit dem internen Takt und ohne Quarz
arbeitest. Das wiederum ist arg Fehlerbehaftet, weil der interne Takt
nicht stabil ist. Es ist also immer anzuraten, mit einem ext. Quarz die
Schaltung zu bestücken, wenn an Datenkommunikation gedacht wird.
Da ich nicht in C programmiere, aber die Vorgehensweise in jeder Sprache
gleich sein sollte, ja, der Hinweis mit einem Ringpuffer ist richtig.
Dafür brauchst du 2 Adresszeiger. Einen für den Schreibvorgang, wenn ein
Empfangsinterrupt auftritt und einen zum Lesen in deiner
Programmschleife. Am Anfang sind beide Adresszeiger gleich. Kommt ein
Zeichen, dann wird idie adressierte Speicherzelle beschrieben und der
Schreibzeiger erhöht. Hat er die Grenze überschritten, wird er wieder
auf den Anfang gesetzt. In der Programmschleife vergleichst du einfach
Schreib- und Lesezeiger. Sind sie unterschiedlich, dann ist ein Zeichen
eingetroffen und du kopierst es entweder in einen Arbeitspuffer oder was
auch immer. Dann erhöhst du den Lesezeiger und so Gott will, sind Lese -
und Schreibzeiger wieder gleich. Wenn nicht, wird der Vorgang
entsprechend fortgesetzt. Beim Überschreiten der Ringpuffergrenze
natürlich wird auch der Lesezeiger zurückgesetzt. Dadurch bleibt die ISR
klein und es gehen keine Zeichen verloren.
Gruß oldmax
@oldmax ich rege mich einfach darueber auf weil er nichts produktiv dazu
beigetragen.
Danke fuer den hinweiss mit dem ringpuffer, aber.mit der lib (s.o) geht
es jetzt.
Was die sache mit dem internen takt angeht bin ich.mir bewusst dass
dieser ungenau is..allerdings betraegt bei einer Baudrate von 4800 und
einem 1Mhz takt der Fehler nur 0.2%.....ich haette nich erwaertet dass
die Ungenauigkeit des Taktes einen Fehler verursacht der groesser als
die akzeptablen 2% sind.
Tobi88 schrieb:> dieser ungenau is..allerdings betraegt bei einer Baudrate von 4800 und> einem 1Mhz takt der Fehler nur 0.2%.....
Das ist in diesem Zusammenhang die falsche Fragestellung.
Die richtige Fragestellung lautet: Habe ich überhaupt 1Mhz? Oder sind es
eher 0.9Mhz oder doch mehr oder weniger 1.1Mhz? Oder irgendwas
dazwischen. Oder mit noch mehr Abweichung? Oder wie oder was? Und wie
ist das, wenn es wärmer wird? Wenn es kälter wird?
Hi
>ich rege mich einfach darueber auf weil er nichts produktiv>dazu beigetragen.
So ist das nun mal in einem Forum. Hier sitzen keine bezahlten
Mitarbeiter einer Hotline, deren Auskünfte selbstverständlich auch
kostenpflichtig sind. Du befindest dich in einem Forum. Alles was hier
geschrieben wird, ob eine Antwort zur Frage oder aber nur "wertlose"
Hinweise hat mehr oder weniger eine Berechtigung. Darüber solltest du
dir im Klaren sein. Dies ist nicht ein Selbstbedienungsladen, wo man
Wissen abstauben kann und manchmal gibt es da etwas genervte
Forenteilnehmer, deren Ton dann nicht immer freundlich bleibt, wenn ein
Fragesteller glabt, alles muß ihm dienlich sein. Wir wollen auch ein
wenig Spaß dabei haben.
Ich hoffe, die Antwort von KHB hast du verstanden. Nimm einen externen
quarzgenauen Taktgeber von 1 MHz und deine Rechnung stimmt. Die interne
Frequenz ist aber nicht stabill und driftet etwas. Da hilft auch kein
Kalibrieren, da der interne Takt auch noch temperaturabhängig ist.
Also, nicht überall, wo 1 MHz draufsteht ist auch 1 MHz drin.
Gruß oldmax
@ oldmax
Ok oldmax entschuldigung das wusste ich wenn ich nicht hier was fuer das
Forum bezahle ich mir bloede Kommentare gefallen muss.....
Ja ich hab KHB verstanden aber wie gesagt nich erwartet dass der Takt
soweit wegdriftet, dass ich mit meiner 4800Baudrate ueber die 2 % Fehler
quote komme. Im mom funktioniert es ganz gut mit der lib von.peter
Fluery und meinen 4800. Trotzdem werde ich den Tipp annehmen und
sicherheitshalber einen 1Mhz bzw 2Mhz Quarz bzw. Ozillator anschliessen.
Wo finde ich Infos wie ich die entsprechenden Kondensatoren
dimensionieren muss? Bei 12 Mhz nehm ich 22p aber die kann ich ja bei
1Mhz bzw 2Mhz nich nehmen oder?