MSP430G2553, I2C read falsche Reihenfolge bei der Ausgabe

Gast #8035411
Lesenswert?

Hallo,

Ich habe ein simples Programm geschrieben, um mit I2C Daten auf einen Sensor oder LCD zu schreiben bzw. lesen. Beim Lesen vom 3Achsen-Sensor ADXL345 habe ich jetzt das Problem, dass er bei der Datenausgabe die Werte verschoben ausgibt.Es sollten für jede Achse 2 Bytes ( 1.Low /2.High) ausgegeben werden, d.h. xL-Achse = axis(0), xH =axis(1), yL = axis(2) usw. bis zH = axis(5) Tatsächlich wird aber xL =axis(1), xH =axis(2)...zH =axis(0) ausgegeben. Bei Spektrum Analyser sind die Daten noch in der richtigen Reihenfolge, irgendwie muß der Fehler beim abspeichern passieren. Technisch lösbar ist das ja,Ich lass die Ausgabe über die serielle Konsole einfach bei 1 anfangen und hänge die 0 dran (wird im Programm so gemacht), ist aber als Lösung unbefriedigend. Vielleicht weiss jemand wo der Fehler ist.

lg Christian

Angehängte Dateien:
#8035426
Lesenswert?

Harald K. schrieb:

Der Kommentar ist falsch.

Dein Kommentar ist falsch…

@TO Ansonsten verschieben sich nicht so einfach ein paar Bytes im Speicher. Woher weißt du denn, dass die Bytes alle um eins verschoben sind? Auch wenns vermutlich nichts mit dem Problem zu tun hat, solltest du am Ende der Transmission ein NACK vor dem Stop setzen.

Oliver

: Bearbeitet durch User
#8035445
Lesenswert?

1
int maxindex = 5;      //maxindex = (maximum of read bytes)-1  
2
I2C_ReadByte(address,0x32,axis,maxindex); //read 6 bytes from address 0x32-0x37
3
      for(int i = 1;i <= maxindex; i++)    
4
      { 
5
      UCA0TXBUF = axis[i];
6
      }
7

8
      UCA0TXBUF = axis[0];

Mal gekürzt auf das wesentliche. Vielleicht erkennst du jetzt das Problem.

: Bearbeitet durch User
#8035494
Lesenswert?

Oliver S. schrieb:

Dein Kommentar ist falsch…

Ach ja?

Zeile 30

1
    int maxindex = 5;      //maxindex = (maximum of read bytes)-1

Zeile 51

1
      I2C_ReadByte(address,0x32,axis,maxindex); //read 6 bytes from address 0x32-0x37

Die Funktion I2C_ReadByte mit dieser Signatur

1
unsigned char I2C_ReadByte(uint8_t address, unsigned char registerAddr, uint8_t* data,int index)

enthält wiederum diese Schleife hier (ab Zeile 144):

1
for(int i=0;i < index; i++)
2
{
3
  data[i] = UCB0RXBUF;         // Read data    
4
  while (!(IFG2 & UCB0RXIFG)); // Wait for receive buffer to be ready
5
}

Der Funktion wird als letzter Parameter beim Aufruf "maxindex" übergeben, das wiederum landet in "index". Damit steht da effektiv

1
for(int i=0;i < 5; i++)
2
{
3
  data[i] = UCB0RXBUF;         // Read data    
4
  while (!(IFG2 & UCB0RXIFG)); // Wait for receive buffer to be ready
5
}

Und das liest fünf Bytes ein. Die landen in den ersten fünf Elementen des Arrays "axis".

Naja, und dann geschieht der andere Fehler mit der For-Schleife, die in diesem Fall bei 1 zu zählen beginnt, und damit bei der Ausgabe das erste Element des Arrays "axis" unterschlägt, und beim zweiten beginnt ...

(Daß die Variablennamen ausgesprochen ungeschickt gewählt sind, muss man wohl nicht erwähnen; was in der Funktion "index" genannt wird, sollte wohl besser "count" heißen, weil das die Anzahl der zu lesenden Bytes ist ...)

Gast #8035499
Lesenswert?

Hallo,

Danke für die Rückmeldungen. Wenn ich maxindex = 6 erhöhe, gibt der spektrumanalyser natürlich 7 Bytes aus(siehe Anlage1), letztes ist 0 (reg0x38), weil das kein Datenregister ist. Dieses Byte wird anscheinend wie vorher bei 6 Bytes wieder in axis(0) eingeschrieben.Ich vermute dass er es nicht schafft den ersten Meßwert in axis(0) zu schreiben, erst bei 2.Durchlauf der Schleife dann in axis(1). So verschiebt sich die Übertragung und am Funktionsende bleibt im Buffer vom Sensor das letzte Byte hängen. Erst beim nochmaligen Funktionsaufruf wird es dann übertragen und landet so in axis(0).Die einfachste Lösung ist 7 Bytes zu übertragen und nur axis(1)- axis(6) verwenden ,(siehe Anlage2) auch nicht optimal aber schon besser. lg Christian

Angehängte Dateien:
#8035504
Lesenswert?

Christian L. schrieb:

spektrumanalyser

Du meinst einen Logikanalysator. Ein Spektrumanalysator ist etwas vollkommen anderes.

Abgesehen davon solltest Du Deine Ausgabeschleife korrigieren. Die ist falsch.

Darauf hat Dich schon Chris hingewiesen.

Ändere das hier

1
for(int i = 1;i <= maxindex; i++)    
2
{   
3
  UCA0TXBUF = axis[i];
4
  __delay_cycles(5000);
5
}
6

7
UCA0TXBUF = axis[0];
8
__delay_cycles(5000);
9

10
UCA0TXBUF = 0x0D;
11

12
__delay_cycles(500000);  //wait busy

zu

1
for (int i = 0; i < maxindex; i++)    
2
{   
3
  UCA0TXBUF = axis[i];
4
  __delay_cycles(5000);
5
}

Abgesehen davon: In Deiner I2C-Leseroutine pollst Du, ob der I2C-Empfänger fertig ist:

1
while (!(IFG2 & UCB0RXIFG)); // Wait for receive buffer to be ready

Warum machst Du beim Beschreiben der UART nicht das gleiche, sondern wartest mit delay_cycles?

#8035545
Lesenswert?

Harald K. schrieb im Beitrag #8035494: ;-) Hausaufgabe für den TO erkläre den Unterschied for(int i=0;i < index; i++) for(int i=0;i <=index; i++) for(int i=1;i < index; i++) for(int i=1;i <=index; i++)

Und leg dir deine Definition zu: z.B. Gezählt wird ab 0 Das Thema ist älter 30 Jahre.... Jeder machts richtig aber anders ;-) Das Thema sehe ich immer wieder: HF Dämpfung 3 dB aber als HF Verstärkung ausgedrückt -3dB ....

: Bearbeitet durch User
#8035590
Lesenswert?

Harald K. schrieb:

Und das liest fünf Bytes ein. Die landen in den ersten fünf Elementen des Arrays "axis".

Verkürzte Aufmersamkeitsspanne? Lies einfach mal die nächsten Zeilen nach der Schleife. Da wird das 6. Byte eingelesen.

Harald K. schrieb:

Abgesehen davon solltest Du Deine Ausgabeschleife korrigieren. Die ist falsch.

Darauf hat Dich schon Chris hingewiesen.

Verkürzte Aufmerksamkeitsspanne? Da steht doch nun extra ein Kommentar über der Schleife, warum die so ist, und die Problembeschreibung dazu steht im Eingangsbeitrag. Die komische Schleife ist ein vermeintlicher „Fix“, um die verschobenen Daten in der richtigen Reihenfolge auszugeben.

@TO Vermutlich verheddert sich deine Einleseroutine, und liest statt der Register 0x32-0x37 die Register um eins verschoben ein. Und zufällig ist der Wert in im letzten Register der, den du aus dem ersten erwartest.

Wenn du tatsächlich einen Logikanalysator hast, zähl nochmal genau nach, wie viele Datenbytes da tatsächlich übertragen werden.

Oliver

Beitrag #8035591 wurde vom Autor gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren