PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rechenproblem beim Feldpointer



oberallgeier
27.09.2012, 14:37
Bitte um Hilfe oder Aufklärung.

Für eine I2C-Kommunikation teste ich meinen Code auf saubere Funktion und exakte Positionierung der verschiedenen Daten. Derzeit zwei Platinen (RNContrl - mega1284/20MHz, RNMotoContrl - m328/20MHz, I2C 100 kHz).

Ein Test besteht darin, drei Ausschnitte des übermittelten Feldes vom Slave per UART wiederholt auszugeben. Der letzte Ausschnitt sollen die letzten zehn Bytes des I2C-Puffers sein. Leider macht mein Feldpointer nicht das was ich will: die Berechnung (egal ob uint8_t oder ~16~) in der for..Schleife ist fehlerhaft.

I2C-Definition (Ausschnitt) (danke uwegw für den Slave-Code) :

//%%%%%%%% von Benutzer konfigurierbare Einstellungen %%%%%%%%
/**@brief Groesse des Buffers in Byte (2..254) */
#define i2c_buffer_size 127 // I2C_REG_ANZAHL 254 Hier kann eingestellt werden
// wieviele Register ausgegeben werden
//##### ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ #####

... und die Ausgaberoutine im Slave (Ausschnitt) :

// - - - - - - - - - - - - - - -
uart_puts("\t\t\t"); // Einrücken
for (uint8_t i=10; i<20; i++)
{
uart_puti(i2cdata[i]);uart_puts(" "); //uart_puts("\r\n");
} // === Ende for (uint8_t i=0; i<i2c_buffer_size...
uart_puts("\r\n"); // Neue Zeile und Leerzeile
_delay_ms( 1000);
// - - - - - - - - - - - - - - -
uart_puts("\t\t\t"); // Einrücken
for (uint8_t i=(i2c_buffer_size-10); i<i2c_buffer_size; i++)
{
uart_puti(i2cdata[i]);uart_puts(" "); //uart_puts("\r\n");
} // === Ende for (uint8_t i=0; i<i2c_buffer_size...
uart_puts("\r\n"); // Neue Zeile und Leerzeile
_delay_ms( 1000);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Dabei wird für die letzte Ausgabe immer am Ende des Buffers begonnen, nicht wie ich möchte, zehn Felder davor.



C501 R5MoCo_x01-x10 m328/20MHz 26Sep2012 2335
Aufbau R5MoCo, I2C-Slave ist Adresse : 130 I2C-WRITE = 0
Test I2C

I2C-Test - I2C-Slave R5MoCo_i2c10.c
Teste I2C-Slave mit Adresse : 130 Buffersize : 252

Nr. 1 i2cdata: 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
252 253 254 255 0 1 2 3 4 5
Nr. 2 i2cdata: 10 99 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
252 253 254 255 0 1 2 3 4 5
Nr. 3 i2cdata: 10 99 12 13 14 15 16 17 18 19
<0>
C501 R5MoCo_x01-x10 m328/20MHz 26Sep2012 2335
Aufbau R5MoCo, I2C-Slave ist Adresse : 130 I2C-WRITE = 0
Test I2C

I2C-Test - I2C-Slave R5MoCo_i2c10.c
Teste I2C-Slave mit Adresse : 130 Buffersize : 252

Nr. 1 i2cdata: 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
252 253 254 255 0 1 2 3 4 5
Nr. 2 i2cdata: 10 99 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
252 253 254 255 0 1 2 3 4 5
Nr. 3 i2cdata: 10 99 12 13 14 15 16 17 18 19
<0>
C501 R5MoCo_x01-x10 m328/20MHz 26Sep2012 2335
Aufbau R5MoCo, I2C-Slave ist Adresse : 130 I2C-WRITE = 0
Test I2C

I2C-Test - I2C-Slave R5MoCo_i2c10.c
Teste I2C-Slave mit Adresse : 130 Buffersize : 127

Nr. 1 i2cdata: 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
127 128 129 130 131 132 133 134 135 136
Nr. 2 i2cdata: 10 99 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
127 128 129 130 131 132 133 134 135 136
Nr. 3 i2cdata: 10 99 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
127 128 129 130 131 132 133 134 135 136
Nr. 4 i2cdata: 10 99 12 13 14 15 16 17 18 19
<0>
C501 R5MoCo_x01-x10 m328/20MHz 26Sep2012 2335
Aufbau R5MoCo, I2C-Slave ist Adresse : 130 I2C-WRITE = 0
Test I2C

I2C-Test - I2C-Slave R5MoCo_i2c10.c
Teste I2C-Slave mit Adresse : 130 Buffersize : 99

Nr. 1 i2cdata: 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
99 100 101 102 103 104 105 106 107 108
Nr. 2 i2cdata: 10 99 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
<0>
C501 R5MoCo_x01-x10 m328/20MHz 26Sep2012 2335
Aufbau R5MoCo, I2C-Slave ist Adresse : 130 I2C-WRITE = 0
Test I2C

I2C-Test - I2C-Slave R5MoCo_i2c10.c
Teste I2C-Slave mit Adresse : 130 Buffersize : 99

Nr. 1 i2cdata: 10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
99 100 101 102 103 104 105 106 107 108
Nr. 2 i2cdata: 10 99 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
99 100 101 102 103 104 105 106 107 108


... und das sollte eben nicht stimmen. Nur - wieso? Wo ist der Fehler?

Problem: die Berechnung
i2c_buffer_size-10
macht offenbar nicht das, was sie soll. Anm.: ich habe die for..Laufvariable mit 8bit und mit 16 getestet.

Danke im Voraus für Eure Hilfe und Aufmerksamkeit.

sternst
27.09.2012, 18:37
Dabei wird für die letzte Ausgabe immer am Ende des Buffers begonnen, nicht wie ich möchte, zehn Felder davor.Ich sehe gar nicht, wie du überhaupt zu dieser Schlussfolgerung kommst.

Offenbar ist doch die Ausgabe von diesem Teil
... und die Ausgaberoutine im Slave (Ausschnitt) :diese beiden Zeilen:
20 21 22 23 24 25 26 27 28 29
252 253 254 255 0 1 2 3 4 5Also ist doch schon bei der ersten Schleife ein "Offset" von 10 vorhanden.
Das sieht für mich eher so aus, als ob entweder das Array nicht den erwarteten Inhalt hat, oder die Funktion uart_puti() nicht korrekt funktioniert.

Außerdem: Wenn deine Schlussfolgerung zutreffen würde, wieso ist der Output dann so "regelmäßig"? Die zehn Bytes hinter dem Buffer müssten doch eher wie "Müll" aussehen.

oberallgeier
27.09.2012, 19:28
Ich sehe gar nicht, wie du überhaupt zu dieser Schlussfolgerung kommst ...Au Stefan, das kommt von meiner schlampigen und zu knappen Fallbeschreibung.



... Also ist doch schon bei der ersten Schleife ein "Offset" von 10 vorhanden ...
a) Vor der I2C-Routine - bei der in einer while(1)-Schleife die Datenänderung lesbar wird, beschreibe ich den Buffer mit Zahlen - angefangen mit 10.


...
//i2cdata mit Werten füllen, die der Master auslesen und ändern kann
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
for(uint8_t i=0;i<i2c_buffer_size;i++)
{ //
i2cdata[i]=10+i; // Dummywerte aufwärtszählen ab 10 ...
} //
// - - - - - - - - - - - - - - -
//in einer Endlosschleife den Inhalt der Buffer ausgeben
while(1) // === Beginn while (1)
...Daher ist diese Belegung ab dem Zahlenwert 10 noch im Sinne des Programmierers.

b) Bei den ersten Tests war i2c_buffer_size gleich 252 (also knapp unterm Limit). Auch der wurde beschrieben wie oben vorgestellt. Und auch nach der Programmierung mit den geringfügigen Änderungen war das Feld wohl am gleichen Platz geblieben - deshalb geht die "monoton ganzzahlige" Feldbeschreibung über die spätere Verkleinerung des Buffers hinaus. Dass über dem I2C-Buffer sonst nicht benötigter/benutzter Speicherplatz sein müsste - wegen dieser Darstellung - war mir auch aufgefallen. Und ich weiß nicht warum. Allerdings wurden bei den Änderungen keine Datenspeicher-relevanten Änderungen durchgeführt - keine neuen Datenplätze eingebracht.

Ist dies eine plausible Erklärung für den Nicht-Müll?

sternst
27.09.2012, 19:41
...
//i2cdata mit Werten füllen, die der Master auslesen und ändern kann
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
for(uint8_t i=0;i<i2c_buffer_size;i++)
{ //
i2cdata[i]=10+i; // Dummywerte aufwärtszählen ab 10 ...
} //
// - - - - - - - - - - - - - - -Daher ist diese Belegung ab dem Zahlenwert 10 noch im Sinne des Programmierers.Dann verstehe ich erst recht nicht, was denn nun das Problem ist. Du schreibst in die letzten 10 Bytes des Buffers (Index 242 - 251) die Werte 252 bis 5, und du bekommst genau das als Ausgabe.

Und wenn das hier
#define i2c_buffer_size 127die aktuelle Größe sein soll, wieso steht dann in der Ausgabe "Buffersize : 252"? Und wenn der Buffer 127 Bytes groß sein soll, und die Schleife fälschlicherweise die 10 Bytes hinter dem aktuellen Buffer ausgeben soll (mit dem Inhalt eines ehemals größeren Buffers), warum besteht die "falsche" Ausgabe dann nicht aus den Zahlen 137 bis 146?

oberallgeier
27.09.2012, 22:43
Dann verstehe ich erst recht nicht, was denn nun das Problem ist ...Danke Stefan. Mein Problem heißt wohl so in der Art "sich selbst ein Bein stellen" oder . . . das will ich nu nicht schreiben.

Beim Nachdenken ist mir jetzt klar geworden was passiert. Ich schreibe (beispielsweise, siehe erstes Posting, drittes Codefenster mit "Buffersize : 252") 252 uint8_t-Zahlen, die ab dem Werte 10 hochgezählt werden, in den I2C-Buffer. Es ist deutlich zu sehen, dass die Einzelwerte nicht bei 252 aufhören, sondern uint8_t-gerecht bis 255 weiterlaufen und mit 0 wieder anfangen. Im 242ten Feld steht auch korrekt 242+10 (krieg ich im Moment sogar im Kopf hin, das ist 252) - und danach gehts weiter und bis über den Zahlenüberlauf hinaus.

Mist, ich hab mich im beschränkten Zahlenraum der 8bittigen, unsigned Welt verheddert.

Danke für die geduldigen Denkanstösse.