UART String empfangen

Gast #3783814
Lesenswert?
• ▲
▼
Hi,

der Democode hier aus dem Dorum funktioniert nicht?

1
/* Zeichen empfangen */
2
uint8_t uart_getc(void)
3
{
4
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
5
        ;
6
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
7
}
8
 
9
void uart_gets( char* Buffer, uint8_t MaxLen )
10
{
11
  uint8_t NextChar;
12
  uint8_t StringLen = 0;
13
 
14
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
15
 
16
                                  // Sammle solange Zeichen, bis:
17
                                  // * entweder das String Ende Zeichen kam
18
                                  // * oder das aufnehmende Array voll ist
19
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
20
    *Buffer++ = NextChar;
21
    StringLen++;
22
    NextChar = uart_getc();
23
  }
24
 
25
                                  // Noch ein '\0' anhängen um einen Standard
26
                                  // C-String daraus zu machen
27
  *Buffer = '\0';
28
}


Das liegt glaube ich daran, dass hier ein fehler ist.
1
NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
2
 
3
                                  // Sammle solange Zeichen, bis:
4
                                  // * entweder das String Ende Zeichen kam
5
                                  // * oder das aufnehmende Array voll ist
6
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
7
    *Buffer++ = NextChar;
8
    StringLen++;
9
    NextChar = uart_getc();
10
  }
11
 
12
                                  // Noch ein '\0' anhängen um einen Standard
13
                                  // C-String daraus zu machen
14
  *Buffer = '\0';

Denn so wird Buffer[0] nie beschrieben, da das Array buffer schon 
inkrementiert wird, bevor NextChar hereingeschriebwn wurde.
Genauso überrschreibt '\0' das letzte zeichen. Weil nichtmehr 
inkrementiert wird..

Jetzt gibt es aber ein Problem dieser Code funktioniert auch 
nicht(mehr).
1
 while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
2
    *Buffer= NextChar;
3
Buffer++;
4
    StringLen++;
5
    NextChar = uart_getc();
6
  }

Warum funktioniert das nichtmehr? Warum hat das Beispiel aus dem AVR-GCC 
Tutorial einmal funktioniert? Wuerde früher wenn man den Befeh,
 *Buffer++ = NextChar; genommen hat das inkrement der Adresse erst im 
nächten Programmdurchlauf ünernommen. Sodass die Speicherstelle 0 i. 
Array doch genutzt wurde? Warum funktioniert meine Version nichtmehr. 
hat es bis jetzt immer.. Ich bin ein wenig verwirrt... Vielleicht weiß 
ja jemand weiter...
#3784618
Lesenswert?
• ▲
▼
Kurze Zwischenfrage:

Was heißt "funktioniert nicht".

Bleibt das Programm irgendwo in einer Funktion hängen?
Gibt "uart_gets" einen String zurück der nahe an dem Erwarteten ist?
Gibt "uart_getc" überhaupt etwas zurück?
Wurde die UART richtig initialisiert?

Ein bisschen mehr input wäre hilfreich, denn auf den ersten Blick hab 
ich spontan keinen Fehler gefunden...
Gast #3784947
Lesenswert?
• ▲
▼
Jan R. schrieb:
> Bei einem 16Mhz Quarz, bekomme ich ja nicht genau die Richtige Baudrate
> hin.

Wozu willst du die unbedingt genau hin bekommen. Es reicht doch, wenn 
der Empfänger bei nomineller Baudrate halbwegs die Mitte abtastet, wobei 
du dir anhand deiner Signalverzerrungen auf der Strecke jetzt überlegen 
kannst, was "halbwegs" in Prozent der Baudrate bedeutet.
Gast #3784955
Lesenswert?
• ▲
▼
Jan R. schrieb:
> Kann man an einen AVR einen extra Baudratenquarz anschließen

Das kommt sicher drauf an, welchen AVR du meinst. Das sollte aber aus 
der Pinbelegung im Datenblatt deines Controllers hervorgehen und im 
Abschnitt USART unter "Clock Generation" beschrieben sein.
Ich kenne alelrdings keinen.
#3784976
Lesenswert?
• ▲
▼
O.K. jetzt mal bitte etwas konkreter:

welcher AVR ?

welche Baudrate?

Und als Bild nochmal die Tabelle aus dem Datenblatt...
Quelle: 
http://www.atmel.com/Images/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf

Gerade bei den "niedrigeren" Baudraten sind die Abweichungen gering...
Aus meiner Sicht ist es den Aufwand nicht Wert.

Ich habe eine ganze Weile aufgrund einer suboptimalen Berechnung meinen 
AVR eine ganze Weile bei 16 MHZ und 28800 Baud mit dem Wert 33 statt 34 
betrieben (Abweichung von über 1%), und die UART hat wunderbar 
funktioniert.
Angehängte Dateien:
Gast #3784989
Lesenswert?
• ▲
▼
Bernhard F. schrieb:
> 16 MHZ und 28800 Baud mit dem Wert 33 statt 34 betrieben (Abweichung
> von über 1%), und die UART hat wunderbar funktioniert.

So erstaunlich ist das nicht. Bei einem Fehler des Clock Generators von 
1% ist der Abtastzeitpunkt auf dem letzen Bit gerade mal 10% der 
Bitlänge aus der Mitte verschoben. Wenn die Übertragungsstrecke nicht 
ganz übel die Flanken verschleift und dann noch am Empfänger mit 
ungünstiger Schwelle ausgewertet wird, macht das überhaupt nichts.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.