Forum: Mikrocontroller und Digitale Elektronik atmega übersprint Anweisung an bestimmter Stelle


von Chris T. (chris0086)


Lesenswert?

Moin Community,
ich habe ein Problem und erkenne den Fehler nicht.
Das Problem ist das nach dem Ausführen einer Funktion der anschließnde 
Teil nicht richtig abgearbeitet wird. Hier erst mal der Code:
1
while(1)
2
{
3
4
  if(wert_anfordern == 1)
5
  {
6
7
    RX_start = 0;
8
    //USART_Transmit('|');
9
    wert_anfordern = 0;
10
    //Force_enable();
11
    SF_length = Build_String(count,requested_value,frame_send,werte);
12
    frame_send[SF_length]= CRC_Get(frame_send,SF_length);
13
14
    Frame_Change(SF_length,frame_send); //<--wahrscheinlich auslösende Funktion 
15
    //USART_SendS(frame_send,SF_length);
16
    //USART_Transmit('B'); //O
17
    receive_complete = 1;
18
  }
19
  if(receive_complete == 1) // Es wurden Daten empfangen
20
  {
21
    receive_complete = 0;
22
    USART_Transmit('|'); //O
23
    
24
25
  }
26
}

Inhalt der Funktion Frame_Change
1
void Frame_Change(uint8_t length,uint8_t *frame_send)
2
{
3
  uint8_t i,change,j;
4
  uint8_t frame_copy[16];
5
  j= 5;
6
  change = 0;
7
  LED_PORT ^= (1<<LED2);
8
  for(i=0;i<5;i++)
9
  {
10
    frame_copy[i] = frame_send[i];
11
  }
12
  for(i=5; i<=length;i++)
13
  {
14
    if((frame_send[i] == 0x02) || (frame_send[i] == 0x2B) || (frame_send[i] == 0xFE))
15
    {
16
      frame_copy[j] = frame_send[i];
17
      frame_copy[j+1] = 0x00;
18
      j+=1;
19
      change = 1;
20
    }
21
    else
22
    {
23
      if((frame_send[i] == 0x11))
24
      {
25
        frame_copy[j] = 0xFE;
26
        frame_copy[j+1] = 0x12;
27
        j+=1;
28
        change = 1;
29
      }
30
      else
31
      {
32
        if((frame_send[i] == 0x13))
33
        {
34
          frame_copy[j] = 0xFE;
35
          frame_copy[j+1] = 0x14;
36
          j+=1;
37
          change = 1;
38
        }
39
        else
40
        {
41
          frame_copy[j] = frame_send[i];
42
        }
43
      }
44
    }
45
    j+=1;
46
  }
47
  for(i=0;i<j;i++)
48
  {
49
    USART_Transmit(frame_copy[i]);
50
  }
51
  //return j;
52
}

Der Funktionsinhalt wird soweit richtig durchlaufen d.h. es wird am ende 
alles auf richtig auf die serielle Schnittstelle gesendet.

Danach müsste die Variable receive_complete auf 1 gesetzt werden und die 
If Bedingung durchlaufen werden und ich müsste ein '|' Zeichen an der 
seriellen Schnittstelle empfangen.
Tu ich aber nicht.
Kommentiere ich den Funktionsaufruf aus so wird die If Anweisung 
durchlaufen und ich erhalte mein '|' Zeichen an der seriellen.

Wo kann denn da der Fehler liegen?

Grüße Christian

von Max D. (max_d)


Lesenswert?

Ist reveive_complete als volatile deklariert?

von Chris T. (chris0086)


Lesenswert?

Max D. schrieb:
> Ist reveive_complete als volatile deklariert?

Ja ist es.

von Karl H. (kbuchegg)


Lesenswert?

Wie gross ist frame_send definiert?
Welcher Wert ergibt sich hier
1
    SF_length = Build_String(count,requested_value,frame_send,werte);
für SF_length?

Wahrscheinlich hast du ein Array überlaufen. Es könnte entweder 
SF_length oder frame_copy in der zweiten Funktion sein.

frame_copy braucht in Wirklichkeit auch keiner. Anstatt die zeichen erst 
mal mühsam in einem Array zu sammeln um sie dann doch wieder nur einzeln 
auszugeben, könntest du auch gleich die Zeichen ausgeben, so wie du auf 
sie stösst. Hätte den angenehmen Nebeneffekt, dass du kein Array 
brauchst, das du somit auch nicht überlaufen kannst.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Chris tian schrieb:
> Wo kann denn da der Fehler liegen?

 Dass du nicht den Teil mit Variablen und Deklarationen mitgesendet
 hast. Wahrscheinlich hast du die 'receive_complete ' totgerechnet.

 Zum 1000-sten Mal:
 Immer das ganze Programm mit Deklarationen, header etc. mitschicken.
 Wenn es zu lang ist, als besondere Datei uploaden.

von Thomas H. (Firma: CIA) (apostel13)


Lesenswert?

Es gibt do so was wie einen Debugger...

von Karl H. (kbuchegg)


Lesenswert?

Das hier
1
  for(i=5; i<=length;i++)
ist auch dubios.

In einem Vektor der Länge 5, ist der größte sinnvolle Index 4.
1
  0, 1, 2, 3, 4
zähl nach: sind genau 5 Stück.

Wenn du daher einen String mit der Länge length hast (vorausgesetzt die 
Längenangabe ist korrekt), dann ist der größte Index length-1, oder eben
1
  for( i = 5; i < length; i++ )
so wie das eben bei Arrays deren Länge man kennt der Normalfall in einer 
for-Schleife ist: 'kleiner' und nicht 'kleiner gleich'.


Ausgeglichen wird der Fehler dadurch, dass du in der aufrufenden 
Funktion die Länge um 1 zu niedrig zählst. Denn hier
1
    frame_send[SF_length]= CRC_Get(frame_send,SF_length);
wird der Frame um 1 länger, was du allerdings nicht in SF_length 
berücksichtigst.

Jetzt könnte man natürlich sagen: was solls. Beim Aufrufer ist die Länge 
um 1 zu gering, in der Funktion gehts dafür um 1 zu weit - kommt doch am 
Ende wieder alles richtig raus.

Ist trotzdem keine gute Idee. Denn irgendwann rufst du die Funktion von 
einer anderen Stelle aus auf, und dann übergibst du die tatsächlich 
richtige Länge und dann baut die Funktion grossartigen Mist.
Mach die Dinge gleich richtig, so dass jede Funktion genau das tut was 
sie zu tun hat und keine Querverbindungen dergestalt bestehen, dass die 
eine Funktion fehlerhaft ist und quasi als Ausgleich eine andere 
Funktion den gegenteiligen Fehler macht, so dass sich die Fehler 
gegenseitig aufheben.

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.