Forum: Mikrocontroller und Digitale Elektronik UART Datenempfang richtig programieren


von Tino K. (blumengiesser)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@  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

von Oliver J. (skriptkiddy)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

(3) atof ist auch noch eine Möglichkeit

von Reinhard Kern (Gast)


Lesenswert?

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

von Tino K. (blumengiesser)


Lesenswert?

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...

von oldmax (Gast)


Lesenswert?

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

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

@  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

von Tretet den Trog (Gast)


Lesenswert?

eine google suche nach "avr uart interrupt" ergibt nur 60k Treffer. Die 
koennen ja nicht alle nichts gewesen sein.

von Reinhard Kern (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.