Forum: Mikrocontroller und Digitale Elektronik Uart, Empfangener String ist leer


von Susan (Gast)


Lesenswert?

Hallo,

Ich versuche mit einem AtMega über Usart mit einer bereits bestehenden 
SPS zu kommunizieren. Die SPS soll mir einen String mit einem Namen 
schicken, den ich weiterverarbeite.

Es kommt auch ein String (6 Zeichen) beim µC an, lassen ich ihn mir aber 
über ein Terminalprogramm ausgeben wird nichts angezeigt.

Ich habe an den Usart-Pins einen Mux angeschlossen, da ich mit der SPS 
und dem PC kommuniziere. Teste ich das Programm statt mit der SPS mit 
dem PC, also sende den String über ein Terminalprogramm funktioniert es.
1
UART_USB;  //Mux wird auf USB eingestellt
2
  
3
char filename[33];      //vollständiger Dateiname
4
char dateiname_c[16];    //Empfangener Name von der SPS
5
6
uart_puts("Uuund...");    //Debuggen
7
8
UART_SPS;      //Mux auf SPS einstellen        
9
uart_gets(dateiname_c, 7);  //String empfangen
10
  
11
strcpy(filename, dateiname_c);  // Erstellung des Filenames
12
strcat(filename, ".TXT");
13
  
14
UART_USB;  //Mux auf USB einstellen
15
  
16
uart_puts(dateiname_c);    //Kontrolle
17
uart_puts(filename);
1
void uart_gets( char* Buffer, uint8_t MaxLen )
2
{
3
  uint8_t NextChar;
4
  uint8_t StringLen = 0;
5
 
6
  NextChar = uart_getc();         // 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' && StringLen < MaxLen - 1 )
12
  {
13
    *Buffer++ = NextChar;
14
    StringLen++;
15
    NextChar = uart_getc();
16
  }
17
 
18
                                  // Noch ein '\0' anhängen um einen Standard
19
                                  // C-String daraus zu machen
20
  *Buffer = '\0';
21
}

Auf meinem Terminal ist folgendes zu sehen:
Uuund....TXT
Der Auszug des Prgramms wird komplett abgearbeitet, aber dateiname_c 
wird leer angezeigt.

Ich arbeite mit 8N1, das auch auf die SPS passen sollte. Diese wurde vor 
längerer Zeit programmiert und es wurde mir von dem Programmierer mit 
einem Terminalprogramm demonstriert, dass dieses Format passt. Selbst 
kann ich das nicht überprüfen, da kein Laptop mit einer 
RS232-Schnittstelle vorhanden ist.

Ich weiß nicht genau woran das Problem liegen kann und erhoffe mir hier 
ein paar Tipps. Das Usart an sich funktioniert, nur mit der SPS nicht. 
Könnte es den sein, dass das Format 8N1 doch nicht passt? Bevor ich den 
Programmierer nochmal kommen lasse, möchte ich erst sicherstellen, dass 
ich keinen fehler gemacht habe.

Vielen Dank,
Susan

von Daniel V. (danvet)


Lesenswert?

Wie so oft liegt das Problem in dem Codeteil, den du nicht zeigst :-(

Was macht uart_getc(), wenn nichts ankommt? Schreibt es lauter Nullen?
UART richtig initialsiert?
Was sagt der Debugger über den String "Buffer" an der Stelle *Buffer = 
'\0' , was steht drin?

von Susan (Gast)


Lesenswert?

Sorry :).
1
uint8_t uart_getc(void)
2
{
3
     while(!(UCSRA0A & (1<<RXC0)))    //Warten bis Zeichen verfügbar
4
        ;
5
     return UDR0;       //Zeichen aus UDR zurückgeben
6
}
1
void uart_init()
2
{
3
   //set Baud-Rate
4
   UBRR0H = UBRRVAL >> 8;
5
   UBRR0L = UBRRVAL & 0xff;
6
   //set frame format: 8bit, no Parity, 1 stopbit
7
   UCSR0C = (1 << UCSZ01) | (1 << UCSZ00));
8
   //enable serial receiver and transmitter
9
   UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXIE0);
10
11
}

uart_getc wartet bis ein Zeichen kommt. Ich hatte zu Beginn RXD und 
TXD-Leitungen vertauscht und das Programm ist dann auch nicht 
weitergelaufen. Ich hatte auch ein Oszi dran hängen und es kommt was an.
Wenn ich statt mit der SPS mit einem Terminalprogramm kommuniziere 
funktioniert es, deswegen nehme ich an, dass mein UART korrekt 
initialisiert wurde. Sollte dem nicht so sein ist Aufklärung natürlich 
herzlich willkommen :).

Der String buffer ist dateiname_c.

Ich habe jetzt noch mit strlen die Länge von dateiname_c  bestimmt. Die 
ist 0 also sthet dort definitiv nichts drin. Ich verstehte nur noch 
nicht so ganz warum :).

Gruß
Susan

von Karl H. (kbuchegg)


Lesenswert?

> 1 << RXIE0

Das passt nicht.
Man gibt keinen Interrupt frei, für den man keinen Handler hat.
Sowas wird mit Prozessorreset beim Empfang eines Zeichens geahndet.

von Susan (Gast)


Lesenswert?

Das soll mal mit Interrupts laufen deswegen habe ich ihn schon 
freigegeben, werde es aber nochmal raus nehmen.

von Karl H. (kbuchegg)


Lesenswert?

Solange du keinen sei() im Programm hast, gehts noch. Trotzdem ist das 
kein guter Stil. Vor allen Dingen dann nicht, wenn du nur Ausschnitte 
aus deinem Programm zeigst.

von Stefan E. (sternst)


Lesenswert?

Die für mich interessantesten Fragen in diesem Thread sind:

1) Wie konnte das Programm mit dem frei geschalteten RXC-Interrupt 
überhaupt je über das uart_getc hinweg kommen?

2) Und wie ist dann das hier überhaupt möglich?
> Wenn ich statt mit der SPS mit einem Terminalprogramm kommuniziere
> funktioniert es

3) Last but not least, wie hast du die Funktion uart_getc überhaupt 
durch den Compiler bekommen?

von Susan (Gast)


Lesenswert?

Danke für die vielen Antworten. Ich werde versuchen alle Fragen zu 
beantworten.
Das gesamte Programm ist mehre kByte groß, deswegen dachte ich, ich 
beschränke mich auf den wichtigen Teil.

1. Die Interrupts waren nicht eingeschalten

2.Je nachdem ob der Mux auf SPS Oder PC(USB) geschalten wird, kann ich 
mit der SPS oder eben mit dem Terminalprogramm kommunizieren, wobei auch 
hier die Interrupts nicht eingeschalten waren.

3. Ich habe den Tippfehler in der uart_getc gefunden und entschuldige 
mich dafür. Der Laptop mit dem Programm hat in der Halle kein WLan und 
ich habe die beiden Funktionen abgetippt.

Gruß
Susan

von Susan (Gast)


Lesenswert?

Achja. Tippfehler verbessert
1
uint8_t uart_getc(void)
2
{
3
     while(!(UCSR0A & (1<<RXC0)))    //Warten bis Zeichen verfügbar
4
        ;
5
     return UDR0;       //Zeichen aus UDR zurückgeben
6
}

von Karl H. (kbuchegg)


Lesenswert?

Susan schrieb:
> Danke für die vielen Antworten. Ich werde versuchen alle Fragen zu
> beantworten.
> Das gesamte Programm ist mehre kByte groß, deswegen dachte ich, ich
> beschränke mich auf den wichtigen Teil.

Und du merkst erst jetzt, dass deine Basis, auf der alles andere 
basiert, nicht funktioniert?

Sauber.

Dann speck ab! Testprogramm, welches nur mit der SPS kommunizert und 
sonst nichts.
Wenn irgend geht, bau dir einen Splitter ein oder sonst eine 
Ausgabemöglichkeit, so dass du sowohl mit der SPS als auch mit dem PC 
kommunizieren kannst. Anstatt PC geht auch ein LCD oder sonst irgendwas, 
Hauptsache du kannst dir ansehen, was du von der SPS kriegst.
Jedes Zeichen, welches von der SPS kommt, wird sofort auf deiner 
Ausgabefläche ausgegeben!
Wenn du nicht nachvollziehen kannst, was in deinem Programm los ist, 
dann musst du dir eben Möglichekeiten dafür schaffen. Und bei einer UART 
bedeutet das dann eben: du musst direkt und unmittelbar und unverfälscht 
mitlesen können, was dein µC von der UART kriegt.

von Uwe (Gast)


Lesenswert?

Die beiden Aussagen widersprechen sich :
>Teste ich das Programm statt mit der SPS mit dem PC, also sende den
>String über ein Terminalprogramm funktioniert es.
und
> Selbst kann ich das nicht überprüfen, da kein Laptop mit einer
> RS232-Schnittstelle vorhanden ist.
Versuch erst mal die richtige Baudrate herauszufinden mit der die SPS 
arbeitet. Diese stellst du dann am µC und auch am PC ein.
Danach überprüfst du mal ob für die SPS 8N1 wirklich stimmt.

von Susan (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und du merkst erst jetzt, dass deine Basis, auf der alles andere
> basiert, nicht funktioniert?

Der wichtige Teil für das Problem. Der Datenlogger drumherum 
funktioniert, das PC-Programm zur Auswertung auch nur kann ich bisher 
den Daten noch keinen genauen Typ zuordnen.

Uwe schrieb:
> Die beiden Aussagen widersprechen sich :
>>Teste ich das Programm statt mit der SPS mit dem PC, also sende den
>>String über ein Terminalprogramm funktioniert es.
> und
>> Selbst kann ich das nicht überprüfen, da kein Laptop mit einer
>> RS232-Schnittstelle vorhanden ist.

Meine Platine hat deswegen einen USB-Anschluss, die SPS nur eine RS232.

...Und wenn ich die beiden miteinander verbinde, funktionieren ja beide 
über UART, bekomme ich die SPS-daten auf den PC. Manchmal sieht man des 
Wald vor lauter Bäumen nicht :).
Dann werde ich das jetzt erstmal tun.

Vielen Dank an alle.

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.