AVR,USART,C: String Empfangen und direkt wieder versenden

OP #1567116
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++;
  }
}
#1567133
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...
Gast #1567158
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.
Gast #1567167
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.
OP #1567194
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren