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


von Scholly .. (scholly)


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++;
  }
}

von Justus S. (jussa)


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

von Scholly .. (scholly)


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 ?

von Justus S. (jussa)


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

von Scholly .. (scholly)


Lesenswert?

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


Wie mache ich das ?

von Justus S. (jussa)


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

von Scholly .. (scholly)


Angehängte Dateien:

Lesenswert?

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

von AtmelFreak (Gast)


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.

von Stefan E. (sternst)


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?

von SinoTech (Gast)


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.

von Walter (Gast)


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

von Scholly .. (scholly)


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

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.