Ich suche seit zwei Tagen im Forum nach einem Hinweis wie man den Empfang mittels des UART richtig programiert. Leider kann ich nix finden und stelle meine Frage hier: Ich habe einen Atmega8, Hard und Softwaremäßig funktioniert der Empfang mittels den Tutorial Testprogrammen einwandfrei. Jetzt kann ich den Empfang ja mittels Pollen oder per Interrupt programieren. Das Pollen sehe ich selber nicht als guten Weg an, da das System dann hängenbleibt und es geht nix mehr. Das mit dem Interrupt ist schon der bessere Weg. Ich stelle mir das so vor: Zeichen wird empfangen, Interrupt geht an, Zeichen wird auf bestimmtes hin überprüft (Startzeichen) bei mißerfolg Ende des Interruptes, bei Erfolg setzen einer Globalen-Variable/Bits und verlassen des Interruptes. Im Hauptprogramm wird die/das Variable/Bits abgefragt und bei Positivem Bescheid verzweigt das Programm in die Empfangsroutine und wartet alle Zeichen ab bis letztes Zeichen empfangen wurde. Dann geht das Hauptprogramm weiter. Zusatzfrage1 hier: Kann das warten mittels Timer oder ähnlichem abgebrochen werden? Falls senden doch nicht erfolgt? Zusatzfrage2: Wie kann aus dem String der Empfangen wurde, eine Float Variable generiert werden? Gibt es eine Funktion ASCII to Float? Danke
@ Tino Kühn (blumengiesser) >Ich suche seit zwei Tagen im Forum nach einem Hinweis wie man den >Empfang mittels des UART richtig programiert. Leider kann ich nix finden >und stelle meine Frage hier: Dann bist du entweder strunzdumm oder ebenso faul oder ein schlichter Lügner! http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART http://www.mikrocontroller.net/articles/Interrupt#UART_mit_Interrupts
Tino Kühn schrieb: > Das Pollen > sehe ich selber nicht als guten Weg an, da das System dann hängenbleibt > und es geht nix mehr. Man kann auch pollen ohne zu warten: Dazu fragt man einfach nur zyklisch ab ob das Receive-Flag gesetzt ist, und holt dann falls das der Fall ist, das Zeichen aus dem Daten-register. Damit bin ich immer gut gefahren.
1 | while(1) // Hauptschleife |
2 | {
|
3 | if (Receive-Flag) |
4 | {
|
5 | //Mache was mit den Daten
|
6 | }
|
7 | }
|
> Wie kann aus dem String der Empfangen wurde, eine Float > Variable generiert werden? (1) Du kannst die Gleitkommazahl binär in 8-Bit-Brocken (Beispielsweise) übertragen und dann auf dem µC zusammensetzen. (2) Ansonsten fällt mir da noch sscanf ein.
Tino Kühn schrieb: > .... Im Hauptprogramm wird die/das Variable/Bits > abgefragt und bei Positivem Bescheid verzweigt das Programm in die > Empfangsroutine und wartet alle Zeichen ab bis letztes Zeichen empfangen > wurde. Dann geht das Hauptprogramm weiter. Hallo, das ist barer Unsinn - Polling mit Auslösung per Interrupt. Die Interruptroutine speichert eintreffende Zeichen (für jedes Zeichen ein Interrupt!!!) in einem Puffer ab und benachrichtigt das Hauptprogramm erst, wenn die ganze Nachricht oder eine ganze Zeile empfangen wurde. Das Hauptprogramm darf niemalsnienicht auf etwas warten, sonst ist das System falsch geplant. Gruss Reinhard
ja danke erstmal. den 3. link, interupt im tutorial, hatte ich noch nicht gefunden. sorry, wenn ich trotzdem gefragt habe. jetzt ist mir die sache wirklich klar und ich werde sie demnächst gleich mal ausprobieren. @falk: beim programieren kann man eine dreifachaufzählung mit 2 ODER verknüpfen, in der deutschen rechtschreibung nimmt man zwischen der ersten und zweiten ein komma und erst zwischen der zweiten und dritten das ODER. Ich kann alle drei sachen für mich übrigens ausschließen. ich würde eher sagen, advanced beginner...
Hi @Falk Erwarte doch nicht immer, das ein Anfänger hier erst mal alle Texte liest und dann fragt. Es ist sicherlich nervig, immer die gleichen Fragen beantworten zu müssen, aber so ist das nun mal im Leben. ( meine Frau fragt auch oft dieselben Dinge ab.....) Also, ein Hinweis auf die Tutorials oder die Suche hätten genügt. @all Seriellen Empfang löse ich immer per Interrupt. Ein Zeichen kommt an und wird in der ISR in einen Ringpuffer geschrieben. Im Programm wird der Schreibzeiger und der Lesezeiger vom Puffer auf Ungleichheit geprüft und entsprechend reagiert. So kann ich den Puffer klein halten und bin trotzdem sicher, alle Zeichen zu erfassen. Ein Ringpuffer ist gar nicht so schwer. Register x,y oder z auf die Pufferadresse, Schreibzeiger dazu addieren und Zeichen eintragen. Anschließend Schreibzeiger erhöhen und prüfen, ob größer Pufferbereich-1. Wenn ja, Schreibzeiger wieder auf 0. Im Programm prüfen Schreibzeiger ungleich Lesezeiger. Wenn ja, zu Adressregister addieren, Zeichen lesen und danach mit Lesezeiger wie mit Schreibzeiger verfahren. Gruß oldmax
Zur Übertragungssicherheit: Bei UART gibt es natürlich die Probleme: - falsches Zeichen empfangen - Ein/Aus stecken während Betrieb - Damit könnte sich das ganze "aufhängen" Zur Lösung mache ich folgendes: - Checksumme in den Nutzdaten angehängt. - Daten (0x00..0xFF) werden UU-Codiert. Aus 3 Byte Nutzdaten werden 4 Byte. - STX, ETX und ACK/NACK steuern die Verbindung. Kommt ein STX Zeichen, so wird der Empfangsbuffer auf 0 gesetzt. Kommt ein ETX Zeichen, so wird der Buffer von UU-Daten in Bytes gewandelt und aus gewertet. Kommt ein NACK wird das Telegramm nochmals verschickt. Kommt ein ACK war alles OK. Vorteil: - Die Übertragung synchronisiert sich garantiert bei jedem STX, ETX, ACK, NACK. - Und man braucht keine "Timeouts". - Normale Text-Befehle/Meldungen lassen sich sogar mit benutzen, denn die haben ja kein STX Start und werden somit von der gegenstelle ignoriert. - Man kann auch Kurz-Befehle mit z.B. ESC xxx ETX realisieren. Nachteil: - Etwas mehr Zeichen werden für die Nutzdaten benötigt.
@ oldmax (Gast) >Erwarte doch nicht immer, das ein Anfänger hier erst mal alle Texte >liest und dann fragt. DOCH! Erst recht wenn er behauptet "Ich suche seit zwei Tagen im Forum". Natürlich sind Fragen im Forum erlaubt, aber erst dann, wennn WIRKLICH was unklar ist um man sich INTENSIV selber um eine Lösung bemüht hat. MFG Falk
eine google suche nach "avr uart interrupt" ergibt nur 60k Treffer. Die koennen ja nicht alle nichts gewesen sein.
Falk Brunner schrieb: > Natürlich sind Fragen im Forum erlaubt, aber erst dann, wennn WIRKLICH > was unklar ist um man sich INTENSIV selber um eine Lösung bemüht hat. Und du entscheidest, wer was fragen darf? Wohin kann man sich denn wenden, um das vorab zu klären und wüste Beschimpfungen so zu vermeiden? Gruss Reinhard
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.