Forum: Mikrocontroller und Digitale Elektronik Probelm mit array in einer Funktion


von Sebastian Z. (sz1985)


Lesenswert?

Hallo zusammen,

ich habe in meinem Programm eine Funktion, die nach verschiedenen 
Kriterien Daten in ein array schreibt, einen CRC errechnet und 
anschließend sendet. Ich habe aktuell das Problem, dass die Daten aus 
der ersten Switch Anweisung (Fall 0x03) richtig gesendet werden, aber 
die Daten aus der zweiten Anweisung (Fall 0x08 & 0x0E) nur teilweise 
richtig gesendet werden. Hier passen die Werte der ersten zwei und der 
letzten 2 Bytes nicht(send[0], send[1], und der Wert für den CRC, der in 
das array gespeichert wird). Wenn ich aber zum Schluss z.B. den Wert vom 
CRC direkt sende passen die Werte.

1
void send_response(unsigned short length, volatile unsigned char *data_ptr, volatile unsigned int *reg_ptr)
2
{
3
unsigned char send[length+2];
4
unsigned short CRC = 0;
5
unsigned char n = 0;
6
unsigned char i = 0;
7
unsigned int temp = 0;
8
unsigned int x = 0;
9
unsigned int y = 0;
10
11
12
send[0] = 0x11;
13
send[1] = *(data_ptr+1);
14
15
switch (*(data_ptr+1) )                        //Auswahl der Funktion zum Zusammenbau des Sendearrays abhängig vom FC
16
{
17
  case 0x03:  
18
          send[2] = length-3;
19
          n = *(data_ptr+5);
20
          temp = *(data_ptr+2) *256 + *(data_ptr+3);    //Startadresse der zu lesenden Registern  !!Änderung von reg_ptr auf data_ptr!!!      
21
22
          for(i=3; i<(n*2+3); i=i+2)
23
          {
24
          send[i] = *(reg_ptr+temp)>>8;
25
          send[(i+1)] = *(reg_ptr+temp);
26
          temp = temp + 1;
27
          }
28
          break;
29
30
  case 0x08:    switch (*(data_ptr+3))
31
          {
32
          i=6;
33
          
34
          case 0x0E:  
35
                //send[0] = 0x11; Problem trotzdem vorhanden
36
                //send[1] = 0x08;
37
                send[2] = 0x00,
38
                send[3] = 0x0E;
39
                send[4] = cpt_4 >> 8;
40
                send[5] = cpt_4;
41
                break;
42
43
          };
44
          break;           
45
46
};
47
//Berechnung der Checksumme für die response anhand der zu sendenden Daten und der Bootschaftslänge ohne CRC
48
CRC = CRC16 (send, length);                      
49
50
send[i] = CRC;
51
i= i +1;
52
send[i] = (CRC>>8);
53
54
55
//Senden der response
56
if(status_send == 1)
57
{
58
for(i=0; i<length+2; i++)
59
{
60
USART_Transmit(send[i]);
61
}
62
}

Hat einer von euch eine Idee, wo hier das Problem liegen könnte.


Vielen Dank.

Gruss

Sebi

von Karl H. (kbuchegg)


Lesenswert?

Sebastian Z. schrieb:

> Hat einer von euch eine Idee, wo hier das Problem liegen könnte.

Dein Hauptproblem ist deine scheusliche Codeformatierung

Wenn ich das mal etwas umformatiere
1
  case 0x08:
2
    switch (*(data_ptr+3))
3
    {
4
      i=6;
5
          
6
      case 0x0E:  
7
        //send[0] = 0x11; Problem trotzdem vorhanden
8
        //send[1] = 0x08;
9
        send[2] = 0x00,
10
        send[3] = 0x0E;
11
        send[4] = cpt_4 >> 8;
12
        send[5] = cpt_4;
13
        break;
14
    };
15
    break;           
16
17
};

dann sieht man, dass das i=6 an einer Stelle steht, an der es nie 
ausgeführt wird.

Der Wert von i ist aber kritisch, weil er danach noch gebraucht wird. Er 
sollte eigentlich 6 sein, ist aber tatsächlich noch 0. Zu allem 
Überfluss überprüfst du auch nicht ob i einen vernünftigen Wert (!=0) 
hat, ehe du dann mit der CRC weitermachst, ob also überhaupt einer der 
switch-cases genommen wurde oder ob die Funktion ungültige Daten 
bekommen hat. Mit einer derartigen Prüfung wäre es dir eventuell sogar 
aufgefallen, dass im Falle 0x08 0x0E überhaupt nichts gesendet wird, 
weil i immer noch 0 ist.
Und durch deine Codeformatierung hast du das alles so angeordnet, dass 
es nicht auf den ersten Blick auffällt. Ich habs auch erst gemerkt, 
nachdem ich den Code in Gedanken umformatiert habe, weil ich es hasse, 2 
Anweisungen in einer Zeile zu haben.

PS: Hinter deinen ganzen } brauchst du keinen ;
Der verwirrt mehr als er nützt. Und an bestimmten STellen würde dieser ; 
sogar für Ärger sorgen. ALso gewöhn ihn dir besser gleich wieder ab.

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.