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.
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 | }
|
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
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)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.