Forum: Mikrocontroller und Digitale Elektronik Uart übertragung Buffern


von Andieh (Gast)


Lesenswert?

Hallo Leute!

Erst mal ein fettes Lob zu dieser Seite und zu diesem Forum. Hat mir 
schon viel geholfen!

Doch jetzt bin ich am verzweifeln. Seit längerem schon versuche ich mit 
meinem Atmega8 einen Buffer zu realisieren, der mir die Chars, die über 
UART ankommen zwischenspeichert. Die Verbindung steht, ich kann Zeichen 
senden und empfangen. Auch Strings selber können übertragen werden.

Aber der Buffer bereitet mir sorgen. Leider muss ich gestehen, das meine 
Kenntnisse in C sehr ungenügend sind. Ich bin dann doch sehr Python 
verwöhnt :D

Zurück zum Problem: Ich möchte Zeichen, die über UART am Mega8 ankommen 
in einem String zwischenspeichern und zwar, bis ein Stoppzeichen ankommt 
(erst mal ein newline). Aber irgendwie kommt immer nur Salat bei rum. 
Hier mein Code, den Teil mit dem UART Init usw. habe ich mal 
weggelassen, der dürfte ja hinreichend bekannt sein. Ziel ist es, die 
Daten auf einem LCD anzeigen zu lassen, eben als Debug.

void uart_putc (uint8_t c) {
        while (!(UCSRA & (1<<UDRE))) {}
        UDR = c;
}

void uart_puts (char *s)
{
   while (*s)
   {
      uart_putc(*s);
      s++;
   }
}

int main(void) {
    unsigned char buffer;
    char str[40] = "a\0";
    char *ptr;
    ptr = (char*) &str[0];

    uart_init();

    while (1) {
        /* Warten bis Daten empfangen wurden */
        while ( !(UCSRA & (1<<RXC)) )
          ;
        /* Empfangsregister auslesen */
        buffer = UDR;

        if ( buffer == '\r' ) {
                uart_puts ( "absatz mit r" );
                uart_putc ( '\r' );
                // fertiger String sollte hier dann verarbeitet werden
                // ein printf("%s", ptr); wurde das machen :D
                // String leeren und Pointer umschieben
                ptr = (char*) &str[0];
                *ptr = '\0';
        } else {
                // Neues Zeichen an den Buffer anhängen
                *ptr = buffer;
                // Pointer erhöhen
                ptr++;
                // Schlusszeichen besser reinschreiben
                *ptr = '\0';
                // das macht er brav
                uart_puts ( "empfangenes Zeichen: " );
                uart_putc ( buffer );
                uart_putc ( '\r' );
        }
    }
}

Wie gesagt, habe die Pointersachen und String operationen bei mir mit C 
am PC getestet und da hats funktioniert. Nur weiss ich eben nicht mehr 
weiter, wieso ich über UART nur wirre Zeichen übertragen bekomme. Das 
liegt aber nicht am fehlenden Quarz, putc funktioniert ja einwandfrei. 
Nur eben meinen Buffer kann ich nicht mit uart_puts übertragen.

Wäre super, wenn mir jemand helfen könnte oder einen Tipp für mich 
hätte!

Tausend Dank
Andieh

von Karl (Gast)


Lesenswert?

Dein Pointer (ptr) zeigt auf das Ende vom String !?


uart_puts( str );

sollte funktionieren ...

von Andieh (Gast)


Lesenswert?

ja klar, da sollen doch später das neue zeichen gespeichert werden! oder 
versteh ich dich falsch?

von Karl H. (kbuchegg)


Lesenswert?

Es würde mal helfen, wenn du den fehlerhaften Code einbauen
würdest. Wo und wie genau, versuchst du die Ausgabe welche nicht
klappt.

von Andieh (Gast)


Lesenswert?

Hallo,
habe jetzt mal alles eingebaut und mich dazu entschlossen, einfach einen 
eigenen Zähler für die Stringlänge mitlaufen zu lassen. Damit siehts 
schon mal ganz gut aus. Hier der Code:

void uart_putc (uint8_t c) {
        while (!(UCSRA & (1<<UDRE))) {}
        UDR = c;
}

void uart_put_array (char *s, uint8_t count) {
        uint8_t a = 0;
        for (a=0;a<count;a++) {
                uart_putc(s[a]);
        }
}
void uart_puts (char *s) {
   while (*s)
   {
      uart_putc(*s);
      s++;
   }
}

int main(void)
{
    unsigned char buffer;
    char str[40] = "a";
    char *ptr;
    uint8_t zaehler = 0;
    ptr = (char*) &str[0];

    uart_init();

    while (1) {
        /* Warten bis Daten empfangen wurden */
        while ( !(UCSRA & (1<<RXC)) )
          ;
        /* Empfangsregister auslesen */
        buffer = UDR;

        if ( buffer == '\r' ) {
                uart_puts ( "Buffer: " );
                uart_put_array ( str, zaehler );
                zaehler = 0;
                ptr = (char*) &str[0];
                uart_putc ( '\r' );
        } else {
                *ptr = buffer;
                ptr++;
                zaehler++;
                uart_puts ( "empfangenes Zeichen: " );
                uart_putc ( buffer );
                uart_putc ( '\r' );
        }
    }
}

Klappt sogar, nur anstatt Buffer wird suffer übertragen :D

Werde aber wohl noch ein Start und Endzeichen einbauen müssen, damit die 
Übertragung gut funktioniert.

Sieht noch jemand gravierende Fehler in dem Code? Wie gesagt, ich bin 
ein Anfänger in C!

Grüße
Andieh

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.