Forum: Mikrocontroller und Digitale Elektronik Variable lässt sich nicht beschreiben


von Lukas W. (lukas_we)


Lesenswert?

Hallo,

Ich habe ein Problem damit eine Variable du beschreiben.
Ich versuche einen String über die Serielle Schnittstelle über einen 
Recieve Interrupt einzulesen, was soweit funktioniert. Danach versuche 
ich den String mit hilfe der atoi() Funktion in einen Int Wert 
umzuwandeln welcher dann auch gleich in eine Global deklarierte Variable 
geschrieben werden soll. Doch wenn ich dann in der Main-Loop versuche 
diesen Wert abzurufen hat die Variable immer noch ihren initialen Wert. 
Woran könnte das liegen?

Mit Freundlichen Grüßen.
Lukas W.

Hier noch ein paar Infos was ich dazu verwende:
Mikrocontroller: Atmega328P
Programmierumgebung: Atmel Studio 7
Programmieradapter: AVR Dragon


Code für die Umwandlung in den String.
1
ISR(USART0_RX_vect)
2
{
3
  
4
  static int counter = 0;
5
  char income = UDR0;
6
  
7
  if(income != '\r')
8
  {
9
    if(((income >= '0') & (income <= '9')) || income == ',')
10
    {
11
      recv_string[counter] = income;
12
      counter++;
13
    }
14
    else
15
    {
16
      printf("Wrong character (only numbers and commas)");
17
    }
18
  }
19
  else
20
  {
21
    recv_string[counter] = '\r';
22
    conv_cmd_string();
23
  }
24
}

Code für die Umwandlung des Strings und Speichern in die Globale 
Variable.
cmd_value und val_value sind die global deklarierten Variablen.
1
void conv_cmd_string(void)
2
{
3
  int cmd_val = 0;
4
  int counter = 0;
5
  int cmd_counter = 0;
6
  int val_counter = 0;
7
  int x = 0;
8
  int y = 0;
9
  
10
  if(cmd_val == 0)
11
  {
12
    for(cmd_counter = 0;recv_string[counter] != ',';counter++)
13
    {
14
      cmd_buffer[cmd_counter] = recv_string[counter];
15
      cmd_counter++;
16
    }
17
    counter++;
18
    cmd_val = 1;
19
  }
20
  
21
  if(cmd_val == 1)
22
  {
23
    for(val_counter = 0;recv_string[counter] != '\r';counter++)
24
    {
25
      val_buffer[val_counter] = recv_string[counter];
26
      val_counter++;
27
    }
28
  }
29
   cmd_value = atoi(cmd_buffer);
30
   val_value = atoi(val_buffer);
31
}

von Einer (Gast)


Lesenswert?

atoi erwartet einen nullterminierten String

Du solltest die Umwandlung nicht in der ISR machen.
Sondern in der ISR ein Flag setzen und die Auswertung in der mainloop.

von M. Н. (Gast)


Lesenswert?

Wie ist die globale Variable deklariert?

Ist sie volatile?

also so:
1
volatile int val_value;

von Ralf (Gast)


Lesenswert?

Sind cmd_value und val_value als volatile deklariert?

von Axel S. (a-za-z0-9)


Lesenswert?

Lukas W. schrieb:
> Ich habe ein Problem damit eine Variable du beschreiben.
> Ich versuche einen String über die Serielle Schnittstelle über einen
> Recieve Interrupt einzulesen

Scheint so, als würde da ein volatile in deinem Quelltext fehlen.

https://de.wikipedia.org/wiki/Volatile_(Informatik)

von Lukas W. (lukas_we)


Lesenswert?

Danke für die schnellen Antworten.

Der Fehler ist behoben oder besser gesagt beide Fehler sind behoben es 
war eine Kombination aus dem fehlenden volatile und das ich die 
Konvertierung im Interrupt aufgerufen habe.

von Dirk B. (dirkb2)


Lesenswert?

Einer schrieb:
> atoi erwartet einen nullterminierten String

atoi hört aber beim ersten Zeichen, das nicht zum int passt auf. Das 
wäre hier das '\r' (das man aber besser durch die 0 ersetzt)

Lukas W. schrieb:
> Der Fehler ... das ich die
> Konvertierung im Interrupt aufgerufen habe.

Das war schlechtes Design, hat mit dem Fehler hier aber nichts zu tun.

von Andreas B. (bitverdreher)


Lesenswert?

Einer schrieb:
> Du solltest die Umwandlung nicht in der ISR machen.

Genausowenig wie printf.

von Dirk B. (dirkb2)


Lesenswert?

Der counter in der ISR sollte auch mal wieder auf 0 gesetzt werden.

von Walter S. (avatar)


Lesenswert?

Lukas W. schrieb:
> int cmd_val = 0;
> ....
>   if(cmd_val == 0)

das ist auch etwas seltsam, wenn du das wirklich so willst kannst du dir 
auch das if sparen

von Andreas B. (bitverdreher)


Lesenswert?

Walter S. schrieb:
> Lukas W. schrieb:
>> int cmd_val = 0;
>> ....
>>   if(cmd_val == 0)
>
> das ist auch etwas seltsam, wenn du das wirklich so willst kannst du dir
> auch das if sparen

Mit Verlaub, aber verwechselst DU da nicht etwas?

von Nop (Gast)


Lesenswert?

Andreas B. schrieb:

> Mit Verlaub, aber verwechselst DU da nicht etwas?

Wenn man eine lokale Variable mit 0 initialisiert, dann hat sie auch den 
Wert 0 - da braucht man keine if-Abfrage mehr drauf zu machen. Die ist 
nämlich immer erfüllt.

von Oliver S. (oliverso)


Lesenswert?

Nop schrieb:
> Wenn man eine lokale Variable mit 0 initialisiert, dann hat sie auch den
> Wert 0 - da braucht man keine if-Abfrage mehr drauf zu machen. Die ist
> nämlich immer erfüllt.

Ein static an passender Stelle würde da Wunder wqirken.

Oliver

von Einer K. (Gast)


Lesenswert?

Oliver S. schrieb:
> Ein static an passender Stelle würde da Wunder wqirken.

Ein überflüssiges static ist ein böses static.
static ist gegen Wiedereintrittsfähigkeit.

Funktionen sollten bei identischen Parametern immer das gleiche tun.
So fordert es das "Prinzip der geringsten Verwunderung" ein.
static macht da einen Strich durch.

In der Not frisst der Teufel Fliegen und der Programmierer baut 
stattdessen lokale static Variablen in Funktionen rein.

von Andreas B. (bitverdreher)


Lesenswert?

Nop schrieb:
> Andreas B. schrieb:
>
>> Mit Verlaub, aber verwechselst DU da nicht etwas?
>
> Wenn man eine lokale Variable mit 0 initialisiert, dann hat sie auch den
> Wert 0 - da braucht man keine if-Abfrage mehr drauf zu machen. Die ist
> nämlich immer erfüllt.

Gerade gesehen, alles zurück. Da ist ja in der Prozedur.

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.