Forum: Mikrocontroller und Digitale Elektronik Übertragungsproblem+Aufhängen Atmega


von Rafi D. (alexanderw)


Angehängte Dateien:

Lesenswert?

Hallo,

sende per UART an einen Empfänger Zeichen bzw. Zeichensätze mittels 
Taster. Klappt auch alles wunderbar, solange ich das ein bis paar mal 
mache, dann bricht der µC zusammen oder er sendet dann komische 
Zeichensätze. z.B. sendet er bei Tastendruck PC0 einmal 0x00 0x00, beim 
nächsten betätigen 0x0A 0x3F usw. wobei er mir ja das 0x4E 0x0A senden 
sollte.
Was sind die typischen software-Anfänger fehler die gemacht werden das 
der µC sich aufhängt?

Anbei noch die dateien. Entprellen von PeDa und uart von Fleury.

von Karl H. (kbuchegg)


Lesenswert?

1
// Einen String per USART 0 empfangen
2
void empfangeString0(char*puffer)
3
{
4
  puffer = NULL;
5
  
6
  while (empfangeZeichen0() != '\n')  // Solange Zeichen in den Puffer schreiben bis Line Feed erreicht ist
7
  {
8
    *puffer++ = empfangeZeichen0(); // Empfangenes Zeichen in Puffer schreiben und Puffer um 1 erhöhen
9
  }
10
...

die typischen Anfängerfehler sind: zu glauben das man nur fertige Libs 
verwenden muss, und alles wird gut ohne das man wissen muss, was man 
tut.

Kauf dir ein C-Buch und arbeite es durch! Du kannst doch in dieser 
Funktion nicht einfach puffer auf NULL setzen! Der FOlgecode bügelt dir 
dann wunderbar den Speicher nieder. Auch hat die Fleury-Lib ein Schema 
für den Rückgabewert, das du einhalten und korrekt auswerten musst.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Funktion nicht einfach puffer auf NULL setzen! Der FOlgecode bügelt dir
> dann wunderbar den Speicher nieder.

Nicht nur das: Weder wird auf einen Buffer-Overflow gechecked (puffer[] 
aus main() kann nur 31 Zeichen + '\0' aufnehmen), noch wird der String 
durch '\0' terminiert.

Ominös ist auch die Variable c0 in main(), die niemals gesetzt, aber 
dauernd abgefragt wird.

von Georg G. (df2au)


Lesenswert?

Moin,
versuch es mal so:

unsigned char mein_puffer[32]; // Ziel der Zeichen
unsigned char c;               // empfangenes Zeichen

// Einen String per USART 0 empfangen
void empfangeString0(char*puffer)
{
  puffer = &mein_puffer[0];

  while ((c = empfangeZeichen0()) != '\n')  // Solange Zeichen in den 
Puffer schreiben bis Line Feed erreicht ist
  {
    *puffer++ = c; // Empfangenes Zeichen in Puffer schreiben und Puffer 
um 1 erhöhen
  }

puffer = NULL -> was ist bei NULL?
zweimal empfangeZeichen() -> jedes zweite Zeichen geht verloren

Zum Thema "Umgang mit fertigen Libs" hat dir KBuchegg schon was 
geschrieben.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Georg G. schrieb:

> unsigned char mein_puffer[32]; // Ziel der Zeichen
> unsigned char c;               // empfangenes Zeichen
>
> // Einen String per USART 0 empfangen
> void empfangeString0(char*puffer)
> {
>   puffer = &mein_puffer[0];

Das ist kompletter Unsinn. Du lenkst hier den per Argument übergebenen 
Buffer namens "puffer" auf einen neuen Buffer um und schreibst dann in 
diesen. Der von main() übergebene Buffer ist dann für die Katz.

Die Zeile

  puffer = NULL;

muss einfach raus, dafür am Ende der Funktion noch ein

  *puffer = '\0';

um den Buffer zu terminieren. Dann läuft es... solange nicht mehr als 31 
Zeichen pro Zeile übertragen werden. Da fehlt also noch eine 
Buffer-Overflow-Prüfung.

von Rafi D. (alexanderw)


Lesenswert?

hallo,
danke für die Tips.

Frank M. schrieb:
> Ominös ist auch die Variable c0 in main(), die niemals gesetzt, aber
> dauernd abgefragt wird.
while (1)
{
 c0 = empfangeZeichen0();
.
.

hab ich vergessen einzubauen.

Eine Buffer-Overflow-Prüfung hab ich nicht eingebaut da nie mehr als 31 
zeichen empfangen werden.

zur zeit lese ich Kernighan/Ritchie... hoffe das mich das auf andere 
Vorgehensweisen bringt und alles dann aufklart.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Alex W. schrieb:

> Eine Buffer-Overflow-Prüfung hab ich nicht eingebaut da nie mehr als 31
> zeichen empfangen werden.

Es reicht, wenn ein '\n' verschluckt wird. Und schon macht Dein µC 
Dinge, die Du niemals gewollt hättest. Sag niemals nie ;-)

> zur zeit lese ich Kernighan/Ritchie... hoffe das mich das auf andere
> Vorgehensweisen bringt und alles dann aufklart.

Schon mal nicht verkehrt. Dann schau Dir mal die Funktion fgets() an und 
überlege, warum hier die Größe des Buffers mit übergeben wird.

von Karl H. (kbuchegg)


Lesenswert?

Das alles rettet ihn immer noch nicht davor, dass die Fleury LIb mit dem 
Returncode auch zurückgibt: Ich hab nichts mehr.

Und solange das nicht korrekt ausgewertet wird, ist diese Aussage
> Eine Buffer-Overflow-Prüfung hab ich nicht eingebaut da nie mehr
> als 31 zeichen empfangen werden.
Aussage für die Katz!

Peter liefert zu seiner Lib ein schönes Beispiel mit, WIE SEINE 
Funktionen zu benutzen sind. Solange du dich darüber hinwegsetzt, hat 
das alles keinen Sinn.

von Karl H. (kbuchegg)


Lesenswert?

Georg G. schrieb:

> versuch es mal so:
>
> unsigned char mein_puffer[32]; // Ziel der Zeichen
> unsigned char c;               // empfangenes Zeichen
>
> // Einen String per USART 0 empfangen
> void empfangeString0(char*puffer)
> {
>   puffer = &mein_puffer[0];
>
>   while ((c = empfangeZeichen0()) != '\n')  // Solange Zeichen in den
> Puffer schreiben bis Line Feed erreicht ist

Vorsicht:
emnpfangeZeichen0()
liefert einen unsigned int (!). Und das aus gutem Grund!.
1
unsigned int empfangeZeichen0(void)
2
{
3
  unsigned char tmpende;
4
  unsigned char zeichen;
5
6
  if (RxStart0 == RxEnde0)  // Wenn keine Daten zum Empfangen vorhanden sind
7
  {
8
    return UsartNd;
9
  }
10
  ....

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.