www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Pointer Problem bei Uart Zeichenkette


Autor: Martin Ramm (martinramm)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Moin,
habe einen Mega 32 und lese Zeichenketten ein über den UART. Das 
Funktioniert auch soweit. Problem nur, das der Pointer, hat zumindest 
den Anschein, nicht immer wieder an der Stelle "0" des Array's anfäng. 
(bei der Funktion void uart_gets( char* Buffer, uint8_t MaxLen )).

Wie erreiche ich es, dass er wieder bei "0" anfängt?

Um Missverständnissen vorzubeugen ich bin Anfänger und er größte Teil 
des Quellcode ist aus dem Tutorial.

Gruß Martin

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sizeof(4) ist beim AVR-GCC gleich 2, nämlich die Größer eines Integers.
Ich habe deinen Code nicht komplett angeschaut, aber ersetze erst mal
alle

  sizeof(4)

durch

  sizeof Line

und schau, was sich ändert.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Code kenn ich doch irgendwoher?

>char Line[4];      // String mit maximal 4 zeichen

Falsch. maximal 3 Zeichen. Das letzte Byte muß für
die abschliessende 0 reserviert bleiben.

>uart_gets(Line, sizeof(4));

sizeof(4) dürfte 2 ergeben.

Autor: atat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll der Doppelpost überhaupt? Mit sowas machst du dir echt Freunde 
in einem Forum...

Autor: Martin Ramm (martinramm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
atat wrote:
> Was soll der Doppelpost überhaupt? Mit sowas machst du dir echt Freunde
> in einem Forum...

Sorry, hätte den anderen Thread gelöscht, geht bloß leider nicht. Habe 
einen neun aufgemacht, da ich dachte das der Betreff vielleicht zu 
Verwirrung führen würde.

habe jetzt sizeof(4)

durch sizeof Line (habe auch sizeof (Line) probiert kenne die Syntax 
leider nicht) und mitlerweile springt er nach 8 eingaben (also Zeichen) 
in den default Teil. Ein Ansteuern der 2. Case Anweisung ist leider auch 
nicht mehr möglich. Das ging jedoch vorher. Was genau macht diese 
"sizeof" Anweisung überhaupt?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bist du sicher, dass dein Terminal nicht noch ab und an mal ein '\r' 
schickt?
Lies doch mal vor dem Einlesen einer Zahl das UDR aus, evtl. ist da noch 
was drin...

Die Empfangsroutine geht noch kompakter:
void uart_gets( char* Buffer, uint8_t MaxLen )
{
  uint8_t NextChar;
 
  while (!(UCSRA & (1<<RXC)));
  NextChar = UDR;         // Warte auf und empfange das nächste Zeichen
 
                                  // Sammle solange Zeichen, bis:
                                  // * entweder das String Ende Zeichen kam
                                  // * oder das aufnehmende Array voll ist
  while( NextChar!='\n' && --MaxLen) {
    *Buffer++ = NextChar;
    while (!(UCSRA & (1<<RXC)));
    NextChar = UDR;
  }
  *Buffer = '\0';
}

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was soll der Doppelpost überhaupt? Mit sowas machst du dir echt
> Freunde in einem Forum...

Du meinst sicher diesen Thread hier:

  Beitrag "Was ist mit diesen Warnhinweisen gemeint?"

Naja, das Problem mit dem falsch eingelesenen Array war im ersten
Thread, wo es um die memset-Funktion ging, etwas offtopic, weswegen ein
neuer Thread schon seine Berechtigung hat.

@Martin Ramm:

Du hättest für das neue Problem entweder gleich einen neuen Thread
aufmachen oder, nachdem du es im alten Thread schon gepostet hattest, im
alten Thread einen Verweis auf den neuen machen können, um zu
verhindern, dass die Leute an zwei Stellen unabhängig voneinander über
dein (neues) Problem grübeln.

Autor: atat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Sorry, hätte den anderen Thread gelöscht, geht bloß leider nicht. Habe
> einen neun aufgemacht, da ich dachte das der Betreff vielleicht zu
> Verwirrung führen würde.
>
Nö, löschen geht nicht, beim nächsten mal erklär es einfach oder mach es 
nicht. ;-)
Das müsste passen, ansonsten können wir ohne Fehlermeldung auch nichts 
machen.
memset(Line,0,sizeof(Line));

> durch sizeof Line (habe auch sizeof (Line) probiert kenne die Syntax
> leider nicht) ...
> Was genau macht diese "sizeof" Anweisung überhaupt?
>
Jetzt mal Butter bei die Fische, nimm dir erstmal ein C-Buch zur Brust, 
am besten eines mit Übungen.
> und mitlerweile springt er nach 8 eingaben (also Zeichen)
> in den default Teil. Ein Ansteuern der 2. Case Anweisung ist leider auch
> nicht mehr möglich. Das ging jedoch vorher.
>
Wie oft lief es sonst?

Hier gibt es C-Grundlagen:
http://www.mikrocontroller.net/articles/C
http://www.mikrocontroller.net/articles/Kategorie:C

Autor: Martin Ramm (martinramm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
yalu wrote:
..., im
> alten Thread einen Verweis auf den neuen machen können, ...

guter Hinweis so eben passiert

wie kann ich denn den UDR auslesen und mir das anzeigen lassen, was da 
drin steht? hatte das gerade schon probiert aber irgendwie hats nicht 
geklappt, bzw. es steht nichts drin. mir wurde also nichts angezeigt.

Gruß Martin

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bist du sicher, dass dein Terminal nicht noch ab und an mal ein '\r'
> schickt?

Evtl. sogar nur ein '\r', denn das ist das normale Verhalten von
Terminals und Terminal-Programmen. Das würde bedeuten, dass
NextChar!='\n' immer wahr ist und die Schleife erst bei vollem Array
abgebrochen wird, was zu seltsamen Effekten fürhren kann.

Sendet das Terminal tatsächlich nur ein '\r', musst du in deinem
Programm einfach nur das '\n' durch ein '\r' ersetzen. Welches
Terminal-Programm verwendest du?

Wie lang sind denn die eingelesenen Zeilen maximal? Die Größe von Line
sollte mindestens diese Länge plus 1 (für das Stringende-'\0') sein,
sonst können in der Routine einzelne Zeichen verschluckt werden. Da du
offensichtlich Prozentwerte für die PWM eingibst, sollte das zwar
prinzipiell passen.

Im case '2', wo das Tastverhältnis wahlweise auf 50% ('1') oder 90%
('0') eingestellt wird, darfst du nach der Eingabe von '1' bzw. '0'
nicht die Enter-Taste drücken, da diese sonst als erstes Zeichen im
nächsten Hauptschleifendurchlauf verarbeitet wird und dort zu einem
Sprung in den default-Zweig führt.

Autor: Martin (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Was wäre denn ein \r? also \n ist doch einfach die Eingabetaste oder?

Also ich hab bei Dateiversion geguckt und da steht 3.10.0.61 oder sagt 
dir das nichts?
ich hab die Datei sonst einfach einmal angehängt. Werde das probieren 
und mich morgen mit dem \r noch einmal melden.

gruß Martin

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso bei Case '2' drücke ich natürlich kein Enter. Aber trotzdem danke.

Autor: Martin Ramm (martinramm)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
SO also habe das \n durch ein \r ersetzt und jetzt läuft der Case - 
Block 1 einwandfrei. Leider kann ich in Case 2 nur reinspringen, wenn 
ich dann eine Eingabe tätige kommt der default Teil und bei Case 3 
springt er sofort in den default Teil. Wobei er das auch erst tut 
nachdem ich Enter gredrückt habe.

Woran könnte das denn liegen?

Grüße Martin


Quellcode im Anhang

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void uart_gets( char* Buffer, uint8_t MaxLen )
  ...
  while (!(UCSRA & (1<<UDRE))){}
  //while (!(UCSRA & (1<<RXC)));
  ...
    while (!(UCSRA & (1<<UDRE))){}
    //while (!(UCSRA & (1<<RXC)));

Wieso hast du RXC in UDRE geändert? UDRE gibt den Zustand des
Sendepuffers wieder, RXC denjenigen des Empfangspuffers. RXC war also
schon richtig. Ohne die richtige Bedingung in der Warteschleife müsste
eigentlich das Line-Array innerhalb kürzeseter Zeit überlaufen und der
ganze Speicher zugemüllt werden.

> SO also habe das \n durch ein \r ersetzt und jetzt läuft der Case -
> Block 1 einwandfrei.

Heißt das, dass du beliebig oft eine 1 und eine bis zu dreistellige
PWM-Prozentzahl eingeben kannst und der Wert als richtiges
Tastverhältnis über den PWM-Ausgang ausgegeben wird? Oder funktioniert
das nur einmal?

Die anderen Cases sind ja bis auf die unterschiedlichen OC-Register
gleich. Dann müssten eigentlich bei allen drei die gleichen Symptome
auftreten.

Autor: Martin Ramm (martinramm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh.. ja jetzt geht auch alles wieder. Weiß ich auch nicht mehr welchen 
Gedanken ich da hatte. ;-)
Ja ich kann unbegrenzt drauf zugreifen

Gruß Martin

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.