Forum: Mikrocontroller und Digitale Elektronik Pointer Problem bei Uart Zeichenkette


von Martin R. (martinramm)


Angehängte Dateien:

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

von yalu (Gast)


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.

von holger (Gast)


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.

von atat (Gast)


Lesenswert?

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

von Martin R. (martinramm)


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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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:
1
void uart_gets( char* Buffer, uint8_t MaxLen )
2
{
3
  uint8_t NextChar;
4
 
5
  while (!(UCSRA & (1<<RXC)));
6
  NextChar = UDR;         // Warte auf und empfange das nächste Zeichen
7
 
8
                                  // Sammle solange Zeichen, bis:
9
                                  // * entweder das String Ende Zeichen kam
10
                                  // * oder das aufnehmende Array voll ist
11
  while( NextChar!='\n' && --MaxLen) {
12
    *Buffer++ = NextChar;
13
    while (!(UCSRA & (1<<RXC)));
14
    NextChar = UDR;
15
  }
16
  *Buffer = '\0';
17
}

von yalu (Gast)


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.

von atat (Gast)


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

von Martin R. (martinramm)


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

von yalu (Gast)


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.

von Martin (Gast)


Angehängte Dateien:

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

von Martin (Gast)


Lesenswert?

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

von Martin R. (martinramm)


Angehängte Dateien:

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

von yalu (Gast)


Lesenswert?

1
void uart_gets( char* Buffer, uint8_t MaxLen )
2
  ...
3
  while (!(UCSRA & (1<<UDRE))){}
4
  //while (!(UCSRA & (1<<RXC)));
5
  ...
6
    while (!(UCSRA & (1<<UDRE))){}
7
    //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.

von Martin R. (martinramm)


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

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.