www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Reservierter Speicher auf Atmega8535


Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hat da jemand ne Idee?

Ohne Code? Nö!

Autor: Phillip Hommel (philharmony)
Datum:

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

Autor: Hans-jürgen Herbert (hjherbert) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur ein gut gemeinter Tip: DER CODE IST NE ZUMUTUNG, für dich und für 
alle anderen, die ihn lesen müssen :-)
//empfangene Daten Auswerte
void
use_rx_data (void)
{
  unsigned char i, bit_adress, bit_to_set, byte_to_set, state;
  if (rx_buffer[0] == flag_data)        //wenn Empfangstyp = Daten
    {
      for (i = 0; i < ((rx_count - 3) / 2); i++)        //für alle ab byte 3 (0.start, 1.adress, 2,type)
        {
          bit_adress = determine_rx_adress (rx_buffer[(i * 2) + 1], rx_buffer[(i * 2) + 2]);    //1. und 2. Teil als Bytenummer
          state = get_bit (rx_buffer[(i * 2) + 2], 3);  //status per bit_ops aus der 4.stelle des low-parts ermitteln
          bit_to_set = mask_byte (bit_adress, 0 b00000111);     //bitnummer aus bitadresse (niedrigsten 3)
          byte_to_set = byte_right_shift (bit_adress, 3);       //bytenummer aus bitadresse (höchsten 5)
          output_set[byte_to_set] = set_bit (output_set[byte_to_set], bit_to_set, state);       //bit an richtiger stelle im ensprechenden byte setzen
        }
      int_flags_1.rx_data_ready = 0;
      rx_count = 0;
      for (i = 0; i < 64; i++)
        USART_Transmit (output_set[i]); //hier lasse ich zum debuggen senden
    }
  else if (rx_buffer[0] == flag_control)
    {
      int_flags_1.rx_data_ready = 0;
      rx_count = 0;
      switch (rx_buffer[1])
        {
        case flag_command_reset:
          reset (adress);
          break;
        case flag_command_send_again:
          resend_all ();
          break;
        default:
          USART_send_status_message (adress, flag_rx_error);
          break;
        }
    }
  else
    {
      USART_send_status_message (adress, flag_rx_error);
      int_flags_1.rx_data_ready = 0;
    }
}

(Habs durch indent laufen lassen)

Autor: Phillip Hommel (philharmony)
Datum:

Bewertung
0 lesenswert
nicht 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!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.