Forum: Mikrocontroller und Digitale Elektronik Reservierter Speicher auf Atmega8535


von Phillip H. (philharmony)


Lesenswert?

Moin, nächstes Problem.
Ich habe in einem Program mehrere arrays verwendet, Größe je 64 byte.
Im einen speichere ich das zwischen, was ich per USART schicke, das geht 
auch.
Jetzt lasse ich daraus verschiedene bytes bearbeiten (bit-operationen 
etc) und speichere diese ergebnisse im zweiten array.
Zum debuggen lasse ich mir jetzt den Speicherinhalt vom zweiten array 
zurückschicken sobald etwas daran verändert wird (also jedesmal wenn ich 
was geschickt habe).
Das lustige ist jetzt, daß zwar die Veränderungen aus den Bitoperationen 
korrekt ausgeführt und gespeichert werden, aber zusätzlich dazu die per 
USART gesendeten bytes, und zwar egal was ich schicke, die gesendeten 
Bytes stehen immer ab der selben stelle im array.
Diese ändert sich, wenn ich die Größe des zweiten arrays verändere, 
bleibt dann aber bei unterschiedlichen gesendeten strings wieder gleich.
Das einzige mal wo ich im Program auf das zweite array zugreife ist die 
stelle an der ich die Operations-Ergebnisse abspeichere und an anderer 
stelle wird es nochmal gelesen um auf einem Port ausgegeben zu werden.
Laut AVR-Studio ist noch gut speicher frei, zugewiesen werden die arrays 
bereits in der INIT-funktion vor der Mainschleife.
Hat da jemand ne Idee?
Ich wollte ungern den ganzen Text posten da er recht lange ist.

von holger (Gast)


Lesenswert?

>Hat da jemand ne Idee?

Ohne Code? Nö!

von Phillip H. (philharmony)


Lesenswert?

Ok klar.
Ich setze mal den Teil rein, in dem ich in das Array schreibe.
1
//empfangene Daten Auswerte
2
void use_rx_data(void)
3
{unsigned char i, bit_adress, bit_to_set, byte_to_set, state;
4
if (rx_buffer[0] == flag_data)          //wenn Empfangstyp = Daten
5
  {for (i=0; i < ((rx_count-3)/2); i++)      //für alle ab byte 3 (0.start, 1.adress, 2,type)
6
    {bit_adress = determine_rx_adress(rx_buffer[(i*2)+1],rx_buffer[(i*2)+2]); //1. und 2. Teil als Bytenummer
7
    state = get_bit(rx_buffer[(i*2)+2], 3);  //status per bit_ops aus der 4.stelle des low-parts ermitteln
8
    bit_to_set = mask_byte(bit_adress, 0b00000111);      //bitnummer aus bitadresse (niedrigsten 3)
9
    byte_to_set = byte_right_shift(bit_adress, 3);      //bytenummer aus bitadresse (höchsten 5)
10
    output_set[byte_to_set] = set_bit(output_set[byte_to_set], bit_to_set, state); //bit an richtiger stelle im ensprechenden byte setzen
11
    }
12
  int_flags_1.rx_data_ready = 0;
13
  rx_count = 0;
14
  for(i=0; i<64; i++) USART_Transmit(output_set[i]); //hier lasse ich zum debuggen senden
15
  }
16
else if (rx_buffer[0] == flag_control)
17
  {int_flags_1.rx_data_ready = 0;
18
  rx_count = 0;
19
    switch (rx_buffer[1])
20
    {case flag_command_reset: reset(adress); break;
21
    case flag_command_send_again: resend_all(); break;
22
    default : USART_send_status_message(adress, flag_rx_error); break;
23
    }
24
  }
25
else 
26
  {
27
  USART_send_status_message(adress, flag_rx_error);
28
  int_flags_1.rx_data_ready = 0;
29
  }
30
}

von Hans-jürgen H. (hjherbert) Benutzerseite


Lesenswert?

Das gefällt mir nicht:


1. : i < ((rx_count-3)/2)
weil: i ist unsigned, wird nie negativ, wenn rx_count < 3 dann wird 
(rx_count-3) negativ. z.B. 0xFF oder 0xFFFF
manche compiler geben dann eine Warnung aus (compare signed with 
unsigned)

Besser so:
if ( rx_count >= 3 )
   {
   if (rx_buffer[0] == flag_data)          //wenn Empfangstyp = Daten
      {for (i=0; i < ((rx_count-3)/2); i++)      // ...
   ...
   }



2. Du sendest immer 64 Bytes, solltest aber nur 32 bytes senden!
  for(i=0; i<64; i++) USART_Transmit(output_set[i]); //...

das geht wohl auch so:
  for(i=0; i<sizeof(output_set); i++) USART_Transmit(output_set[i]); 
//...


Ich hoffe doch, dass output_set 64 Bytes groß ist! Ist wohl statich 
angelegt, etwa durch:
unsigned char output_set[64] ;

Oder hast Du die Adresse von malloc ? (Das täte ich in einem 
Microcontroller nicht machen.
Und wieso 64? Du kannst doch nur 32 Bytes addressieren!. von den 8 Bits 
in bit_address werden 3 bits für die Bitnummer im Byte verwendet, aber 
nur 5 bits bleiben für byte_to_set. Damit ist der Index 0...31, also 32 
Bytes.


3. Du schreibst "zugewiesen werden die arrays ..."

arrays werden nicht zugewiesen, sondern angelegt.


4. byte_to_set = byte_right_shift(bit_adress, 3);

Das geht auch so: byte_to_set = bit_adress >> 3 ;


Anmerkung:
Der angegebene Code kann gewiß auch auf dem PC ausgeführt werden, 
Schritt für Schritt, mit einem C Entwickliungssystem (Borland, oder 
Microsoft verwende ich dafür).
Das erleichtert das Debuggen

von Sven P. (Gast)


Lesenswert?

Nur ein gut gemeinter Tip: DER CODE IST NE ZUMUTUNG, für dich und für 
alle anderen, die ihn lesen müssen :-)
1
//empfangene Daten Auswerte
2
void
3
use_rx_data (void)
4
{
5
  unsigned char i, bit_adress, bit_to_set, byte_to_set, state;
6
  if (rx_buffer[0] == flag_data)        //wenn Empfangstyp = Daten
7
    {
8
      for (i = 0; i < ((rx_count - 3) / 2); i++)        //für alle ab byte 3 (0.start, 1.adress, 2,type)
9
        {
10
          bit_adress = determine_rx_adress (rx_buffer[(i * 2) + 1], rx_buffer[(i * 2) + 2]);    //1. und 2. Teil als Bytenummer
11
          state = get_bit (rx_buffer[(i * 2) + 2], 3);  //status per bit_ops aus der 4.stelle des low-parts ermitteln
12
          bit_to_set = mask_byte (bit_adress, 0 b00000111);     //bitnummer aus bitadresse (niedrigsten 3)
13
          byte_to_set = byte_right_shift (bit_adress, 3);       //bytenummer aus bitadresse (höchsten 5)
14
          output_set[byte_to_set] = set_bit (output_set[byte_to_set], bit_to_set, state);       //bit an richtiger stelle im ensprechenden byte setzen
15
        }
16
      int_flags_1.rx_data_ready = 0;
17
      rx_count = 0;
18
      for (i = 0; i < 64; i++)
19
        USART_Transmit (output_set[i]); //hier lasse ich zum debuggen senden
20
    }
21
  else if (rx_buffer[0] == flag_control)
22
    {
23
      int_flags_1.rx_data_ready = 0;
24
      rx_count = 0;
25
      switch (rx_buffer[1])
26
        {
27
        case flag_command_reset:
28
          reset (adress);
29
          break;
30
        case flag_command_send_again:
31
          resend_all ();
32
          break;
33
        default:
34
          USART_send_status_message (adress, flag_rx_error);
35
          break;
36
        }
37
    }
38
  else
39
    {
40
      USART_send_status_message (adress, flag_rx_error);
41
      int_flags_1.rx_data_ready = 0;
42
    }
43
}

(Habs durch indent laufen lassen)

von Phillip H. (philharmony)


Lesenswert?

So, danke an alle, Fehler gefunden, hab schlichtweg über den 
speicherinhalt hinaus lesen wollen (vertippt bei der größe) und bin in 
den nächsten reingelaufen.
Jetzt funzt alles.
Merci!

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.