Forum: Mikrocontroller und Digitale Elektronik Array Index ATMEGA


von Adam (Gast)


Lesenswert?

Hallo zusammen,

Vielleicht habe ich heute ein Brett vor
m Kopf, aber ich komme hier gerade nicht weiter.
Folgendes Beispiel:

-unsigned char command_value[] = {1,2,3,4};
-unsigned char idx = 0;
-
- idx++;
- if (idx > 3) { idx = 0; }
-idx=1;                          <<<< WIRD Überschreiben
-send_num(idx); uart_putc(58);
-send_num(command_value[idx]); uart_putc(58);
-uart_putc(13);uart_putc(10);

funktioniert einwandfrei und liefert:

000000:000004:
000000:000004:
..usw

Wenn ich das Überschreiben weglasse (idx wird nicht 1 gesetzt sondern 
gerechnet) kommt folgendes raus:

000000:000032:
000001:000032:
000002:000032:
... usw.


Die komplette Funktion auf dem ATMEGA168 schaut so aus:
1
int main (void) {
2
  unsigned char command_value[] = {4,7,8,9};
3
  unsigned char idx = 0;
4
5
  Init_UART(9600); // for DEBUG Purpose
6
  idx = 0;
7
  while (1) {
8
9
     
10
       send_num(idx); uart_putc(58);
11
    send_num(command_value[idx]); uart_putc(58);
12
    uart_putc(13);uart_putc(10);
13
14
15
    idx++;
16
    if (idx > 3) { idx = 0; }
17
  }
18
19
}
Der Index (IDX) verlässt NICHT den Wertebereich - wie auch in der Debug 
Anzeige zu sehen. Was übersehe ich gerade???


Danke und Gruß,
 Adam

: Bearbeitet durch User
von Adam (Gast)


Lesenswert?

Sorry,kleine Korrektur - der erste teil liefert
000001:000002

von annalyser (Gast)


Lesenswert?

Die Funktion send_num () wäre schon noch wichtig.

von Adam (Gast)


Lesenswert?

Hallo,

unten habe ich mal send_num() angefügt - allerdings sollte diese das 
Array nicht verändern. Es gibt immer nur Ärger sobald ich die 
Index-Variable ändere.

Folgendes Beispiel:
1
int main (void) {
2
3
  unsigned int n;
4
  unsigned int test;
5
  unsigned int command_value[4] = {4,7,8,9};
6
7
  Init_UART(9600); // for DEBUG Purpose
8
9
  n = 0;
10
11
  while (1) {
12
          test = (int)command_value[n];
13
14
       send_num(n);    uart_putc(58);
15
    send_num(test); uart_putc(58);
16
    send_num(test); uart_putc(58);
17
    uart_putc(13);  uart_putc(10);
18
19
    _delay_ms(500);
20
    n++;
21
22
    if ( n > 2 ) {  n = 0;  }
23
  }
24
}

Ausgabe:
1
000000:000004:000004:
2
000001:008224:008224:
3
000002:024672:024672:
4
000000:024672:024672:
Erster Index ( n=0; ) funktioniert, schon das erste n++ klappt aber 
nicht mehr...
1
// --------------------------------------------------------------------------------------
2
void send_num(uint16_t num) {
3
  int zahl;
4
  char str_zahl[5];
5
  unsigned char i;
6
7
  zahl = num;
8
9
  // Convert Number to Characters
10
  for (i=0; i<6; i++) {
11
    str_zahl[i] = zahl % 10;
12
    zahl /= 10;
13
  }
14
15
  // Send Characters in reverse order
16
  for (i=6; i>0; i--) {
17
    uart_putc(48+str_zahl[i-1]);
18
  }
19
20
}
21
// --------------------------------------------------------------------------------------

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

1
str_zahl[5];
2
3
for (i=0; i<6; i++) {
4
    str_zahl[i]

damit wird

str_zahl[5] geschrieben, was nicht sehr gut ist.

von Karl H. (kbuchegg)


Lesenswert?

Ein Array, welches du mit einer Länge von 5 definierst
1
void send_num(uint16_t num) {
2
  int zahl;
3
  char str_zahl[5];

hat als gültige Indizes
0, 1, 2, 3, 4

zähl nach. Sind 5 Stück.
Ein Array Element mit dem Index 5 existiert nicht

d.h. hier
1
  for (i=0; i<6; i++) {
2
    str_zahl[i] = zahl % 10;
hast du einen Array Overflow. i nimmt als letzten Wert den Wert 5 an. 
Ein str_zahl[5] existiert aber nicht.

: Bearbeitet durch User
von Adam (Gast)


Lesenswert?

Leute, Super!!!!

Man das war doof...
Erstaunlich das sich gerde die Variablen überschrieben haben.

Vielen Dank für das entfernen meiner Tomaten (vor den Augen) ;-)

von Karl H. (kbuchegg)


Lesenswert?

Jetzt weißt du auch, warum man bei solchen Sachen mit Makros arbeitet
1
#define NR_DIGITS  6   // darf nicht kleiner als 6 sein. Kann aber größer sein
2
3
void send_num(uint16_t num) {
4
  int zahl;
5
  char str_zahl[NR_DIGITS];
6
  unsigned char i;
7
8
  zahl = num;
9
10
  // Convert Number to Characters
11
  for (i=0; i<NR_DIGITS; i++) {
12
    str_zahl[i] = zahl % 10;
13
    zahl /= 10;
14
  }
15
16
  // Send Characters in reverse order
17
  for (i=NR_DIGITS; i>0; i--) {
18
    uart_putc('0' + str_zahl[i-1]);
19
  }
20
}

jetzt stimmt die Array Größe IMMER mit der Anzahl an auszugebenden 
Digits überein.

von Adam (Gast)


Lesenswert?

Ja, so ist's halt wenn das Kind schreit und Papa glaubt wie früher mal 
kurz eben was zu coden... und dann noch eine kleine Funktion zum 
debuggen, die ist ja eh egal ... argh.

Das Umkopieren dürfte sich jetzt auch erledigt haben, ist ja eine Werte 
und keine Referenzübergabe:

#define NR_DIGITS  6   // darf nicht kleiner als 6 sein. Kann aber 
größer sein
void send_num(uint16_t num) {
  char str_zahl[NR_DIGITS];
  unsigned char i;

  // Convert Number to Characters
  for (i=0; i<NR_DIGITS; i++) {
    str_zahl[i] = num % 10;
    num /= 10;
  }

  // Send Characters in reverse order
  for (i=NR_DIGITS; i>0; i--) {
    uart_putc('0' + str_zahl[i-1]);
  }
}

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.