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).
Ein Mega8 @ 1THz, und Intel und co Krebsen noch bei der 5GHz Marke rum...
Mit der Peter Fleury Lib geht es dann is die Datei zwar 200byte größer aber mal schaun was ich von mir da noch weg optimieren kann
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?
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.