mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR,USART,C: String Empfangen und direkt wieder versenden


Autor: Scholly ... (scholly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey,
kann sich bitte Jemand meinen C-Code ansehen und mir sagen warum das 
nicht funktioniert ? Ich finde den Fehler einfach nicht....Im Grunde 
will ich nur einen String über die USART in einem Array speichern und 
ihn wieder zurückschicken:

#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>

#define USART_PRESCALE (((F_CPU / (115200 * 16UL))-1))
char Array[100];
int ToSend = 0; //ist ein kompletter String zum zurücksenden im Speicher 
?
int Counter = 0;

int main(void)  {
UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN ); //Sende und Empfangsmodus 
einschalten
UCSRC |= ( 1 << URSEL ) | ( 1 << UCSZ0 ) | ( 1 << UCSZ1 ); //Modus: 
Asynchron 8N1
UBRRL = USART_PRESCALE; //Baudrate setzen
UCSRB |= ( 1 << RXCIE); //USART Interrupts aktivieren
sei(); //Interrupts einschalten

for(;;)
{
  if (ToSend != 0)
  {
    for (int i = 0;i <= strlen(Array);i++)
    {
    UDR = Array[i];
    }
  ToSend = 0;
  }
}
}

ISR(USART_RXC_vect)
{
  Array[Counter] = UDR;
  if (Array[Counter] == '\0')
  {
    ToSend = 1;
    Counter = 0;
  }
  else
  {
  Counter++;
  }
}

Autor: Justus Skorps (jussa)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Scholly ... schrieb:
> Hey,
> kann sich bitte Jemand meinen C-Code ansehen und mir sagen warum das
> nicht funktioniert ? Ich finde den Fehler einfach nicht....

 auf jeden Fall fehlen da volatiles...

Autor: Scholly ... (scholly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Justus Skorps schrieb:
>  auf jeden Fall fehlen da volatiles...

Ich bin zwar neu in der C-Programmierung, aber wofür brauche ich denn 
die Volatiles?. Wenn ich es Richtig verstanden habe, dann sind die doch 
nur für einen Variablen Zugriff außerhalb des Programms, oder ?

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Scholly ... schrieb:
> Justus Skorps schrieb:
>>  auf jeden Fall fehlen da volatiles...
>
> Ich bin zwar neu in der C-Programmierung, aber wofür brauche ich denn
> die Volatiles?. Wenn ich es Richtig verstanden habe, dann sind die doch
> nur für einen Variablen Zugriff außerhalb des Programms, oder ?

und was ist deine ISR?

schau dir doch mal das Assembler-Listing deines Programms an, ob da 
überhaupt was pssiert...

Autor: Scholly ... (scholly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Justus Skorps schrieb:
> schau dir doch mal das Assembler-Listing deines Programms an, ob da
>
> überhaupt was pssiert...


Wie mache ich das ?

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Scholly ... schrieb:
> Justus Skorps schrieb:
>> schau dir doch mal das Assembler-Listing deines Programms an, ob da
>>
>> überhaupt was pssiert...
>
>
> Wie mache ich das ?

die lss-Datei...

Autor: Scholly ... (scholly)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Sehe die zum ersten mal und verstehe noch nicht ganz was ich da sehe...

Autor: AtmelFreak (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also als Erstes brauchst du die volatile damit die Vars auch in der ISR 
verändert werden können.
Einfach nur Daten ins UDR zu schreiben reicht nicht um die Übertragung
anzuschubsen. Entweder auch über ISR oder manuell.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst nicht einfach nach Belieben ein Zeichen nach dem Anderen in 
UDR rein stopfen. Du musst schon warten, bis da jeweils wieder Platz 
drin ist.

Außerdem: wie wird der String zum µC gesendet? Sicher, dass da eine 
terminierende Null mitkommt?

Autor: SinoTech (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Scholly ... schrieb:
> eu in der C-Programmierung, aber wofür brauche ich denn
> die Volatiles?. Wenn ich es Richtig verstanden habe, dann sind die doch
> nur für einen Variable

Scholly ... schrieb:
> Justus Skorps schrieb:
>>  auf jeden Fall fehlen da volatiles...
>
> Ich bin zwar neu in der C-Programmierung, aber wofür brauche ich denn
> die Volatiles?. Wenn ich es Richtig verstanden habe, dann sind die doch
> nur für einen Variablen Zugriff außerhalb des Programms, oder ?

Wenn du in einer Funktion oft auf eine Variable zugreifst, wird die oft 
irgendwo am Anfang in ein register geladen und später nur noch dort 
verändert. Ist erstmal kein Problem, denn der Compiler sieht ja an 
welchen Stellen in der Funktion auf die Variable zugegriffen und 
verändert wird. Zum Problem wird es erst, wenn die Variable von 
Ausserhalb geändert wird, zum Beispiel durch dein ISR. In dem Fall würde 
die ISR die Variable im Speicher verändern, innerhalb der Main-Funktion 
würde aber weiterhin mit dem alten Wert gearbeitet werden der im 
Register steht.
Das "volatile" gibt einfach nur an das die Variable auch von ausserhalb 
geändert werden kann (zum Beispiel in der ISR). Die Variable wird dann 
bei jedem Zugriff neu aus dem Speicher geladen und nicht im Register 
gecached.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und zerlege dein Programm erst mal in teilschritte:
also zuerst mal was definiertes senden und schauen ob es ankommt,
dann erst was empfangen und zurücksenden ...

Autor: Scholly ... (scholly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also es funktioniert jetzt. Wenn ich einen "Test"-String reinschicke, 
wird auch genau ein "Test" + \0 zurückgesendet, das kann ich auf der 
Gegenseite (PC) sehen. Hier der Code:

#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>

#define USART_PRESCALE (((F_CPU / (115200 * 16UL))-1))
volatile char Array[100];
volatile int ToSend = 0;
volatile int Counter = 0;

int main(void)
{
UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN );
UCSRC |= ( 1 << URSEL ) | ( 1 << UCSZ0 ) | ( 1 << UCSZ1 );
UBRRL = USART_PRESCALE;
UCSRB |= ( 1 << RXCIE);
sei();

for(;;)
{
  if (ToSend != 0)
  {
    for (int i = 0;i <= strlen(Array);i++)
    {
  while (!(UCSRA & (1<<UDRE)))
    {
    }
    UDR = Array[i];
    }
  ToSend = 0;
  }
}
}

ISR(USART_RXC_vect)
{
  Array[Counter] = UDR;
  if (Array[Counter] == '\0')
  {
    ToSend = 1;
    Counter = 0;
  }
  else
  {
  Counter++;
  }
}

Ich bekomme nur Warnmeldungen vom Compiler bezgl strlen:

main.c:21: warning: passing argument 1 of 'strlen' discards qualifiers 
from pointer target type

Vielen Dank an Alle

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.