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


von Joris (Gast)


Lesenswert?

Moin,

will ein Array beim Funktionsaufruf übergeben und dann 
weiterverarbeiten:
1
static char test[5] = { 0x48, 0x41, 0x48, 0x41, 0x48, };
2
3
int USART_TX(char *TX_B, unsigned int TX_B_L) {
4
  
5
  while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich
6
  
7
    for(int i=0; TX_B_L > i; i++)
8
  
9
  UDR0 = TX_B[i];
10
  
11
    return 0;
12
}
13
14
// main:
15
16
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!

von Karl H. (kbuchegg)


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.
1
int USART_TX(char *TX_B, unsigned int TX_B_L) {
2
  
3
  for(int i=0; TX_B_L > i; i++) {
4
    while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich
5
    UDR0 = TX_B[i];
6
  }
7
8
  return 0;
9
}

von Joris (Gast)


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

von STK500-Besitzer (Gast)


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

von Karl H. (kbuchegg)


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.

von Joris (Gast)


Angehängte Dateien:

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:
1
static char test[5] = { 0x48, 0x41, 0x48, 0x41, 0x48, };
2
3
int USART_TX(char *TX_B, unsigned int TX_B_L) {
4
  
5
  for(int i=0; TX_B_L > i; i++) {
6
    
7
    while (!(UCSR0A & (1<<UDRE0))) { } // Warten bis Senden möglich
8
      
9
    UDR0 = TX_B[i];
10
  }
11
12
  return 0;
13
}
14
15
// main
16
17
int main( void ) {
18
19
     USART_TX (test, sizeof(test));
20
21
  return(0);
22
}

Für jede Hilfe dankbar!

von Joris (Gast)


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

von Joris (Gast)


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

von Joris (Gast)


Lesenswert?

Kann denn keiner dazu was sagen :-/

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

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.