www.mikrocontroller.net

Forum: PC-Programmierung [C] Array-übergabe an Funktion


Autor: Joris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

will ein Array beim Funktionsaufruf übergeben und dann 
weiterverarbeiten:
static char test[5] = { 0x48, 0x41, 0x48, 0x41, 0x48, };

int USART_TX(char *TX_B, unsigned int TX_B_L) {
  
  while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich
  
    for(int i=0; TX_B_L > i; i++)
  
  UDR0 = TX_B[i];
  
    return 0;
}

// main:

USART_TX (test, sizeof(test));

Eigentlich sollte man vor jedem Senden überprüfen ob gesendet werden 
kann. Aber so müsste ja schonmal ein 0x48 drüberrutschen.

Wenn ich jetzt im AVR Studio nen Watch auf test und TX_B lege dann ist 
der Inhalt von test richtig und beim Funktionsaufruf wenn er test 
übergeben will steht bei TX_B: "Location not falid"

Ich dachte eigentlich, dass es so funktionieren müsste...wie gesagt 
dachte ich.... ;)

Danke!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joris wrote:

> Ich dachte eigentlich, dass es so funktionieren müsste...wie gesagt
> dachte ich.... ;)

Dein Code ist soweit (fast) in Ordnung. Ich weiss jetzt nicht,
wo und wann du genau den Watch gesetzt hast. TX_B existiert
nur innerhalb der Funktion USART_TX, d.h. du musst schon
innerhalb der Funktion sein, damit der Debugger TX_B auswerten
kann.

'Fast' deswegen:
Du musst schon vor jedem Zeichen warten, bis die UART bereit ist.
int USART_TX(char *TX_B, unsigned int TX_B_L) {
  
  for(int i=0; TX_B_L > i; i++) {
    while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich
    UDR0 = TX_B[i];
  }

  return 0;
}

Autor: Joris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

jo das ist schon klar, dass vorher überprüft werden sollte. Hab ich ja 
oben schon geschrieben. Den Watch auf TX_B setze ich gleich am Anfang. 
Wird aber logischerweise erst aktiv wenn das Programm in die Funktion 
springt, das stimmt schon. Und wenn er dann test an TX_B übergeben will 
steht nicht das test Array drin sondern als Fehlermeldung "Location not 
falid"

Joris

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>jo das ist schon klar, dass vorher überprüft werden sollte.

Deine Funktion überprüft einmalig beim Aufruf, ob der Sendespeicher 
voll ist.
Es muß aber vor jedem UDR0 = TX_B[i]; überprüft werden, ob UDRE 
gesetzt ist.

>Den Watch auf TX_B setze ich gleich am Anfang.
Ah, die simulierst den Spaß...

>Fehlermeldung "Location not falid"

"falid" oder "valid"?

Poste ein compilierbares Programm, uns man kann dir besser helfen...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast nicht zufällig den Optimizer eingeschaltet.
Die Funktion ist kurz genug, dass ich mir vorstellen könnte,
dass der Compiler sie ge-inlined hat. Dadurch könnte
dann TX_B rausgefallen sein.

Autor: Joris (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

im Anhang mal das was im Watch angezeigt wird.

> Du hast nicht zufällig den Optimizer eingeschaltet.

Ich denke nicht. Hab da noch nie was verstellt. Wie kann ich das in 
AVR-Studio überprüfen?

Und hier mal der aktuelle Code:
static char test[5] = { 0x48, 0x41, 0x48, 0x41, 0x48, };

int USART_TX(char *TX_B, unsigned int TX_B_L) {
  
  for(int i=0; TX_B_L > i; i++) {
    
    while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich
      
    UDR0 = TX_B[i];
  }

  return 0;
}

// main

int main( void ) {

     USART_TX (test, sizeof(test));

  return(0);
}

Für jede Hilfe dankbar!

Autor: Joris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok hab die Option gefunden und gleich mal -Os entfernt. Der Programmcode 
hat sich vergrößert. Im Watch steht jetzt folgendes:

NAME    VALUE               TYPE
TX_B    0x3400              char*
  ->    Invalid location    char

test[5] passt wieder, TX_B_l wird auch richtig übergeben

Autor: Joris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne ganz blöde Frage: Wenn ich in der Main einfach 2 mal 
hintereinander senden will funktioniert das auch nicht, es kommt nichts 
an im Terminal:

[c]
while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich

       UDR0 = 'X';

while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich

       UDR0 = 'Y';
[c]

Wieso funktioniert das nicht? Wenn ich allerdings nur einen block in nen 
timer packe der jede sekunde ausgefüht wird kommt jede sekunde ein 
zeichen rüber. Durch die Bedingung in while wird doch geprüft ob er 
senden kann oder nicht?
Irgendwie werde ich daraus nicht schlau.

Joris

Autor: Joris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann denn keiner dazu was sagen :-/

Kann ja nicht sooo schwer sein so nen Array über USART rauszukloppen :-|

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.