Forum: Mikrocontroller und Digitale Elektronik MSP430G2553, I2C read falsche Reihenfolge bei der Ausgabe


von Christian L. (Gast)


Angehängte Dateien:

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

von Harald K. (kirnbichler)


Lesenswert?

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

Der Kommentar ist falsch. Es werden nur 5 Bytes gelesen, denn "maxindex" 
hat den Wert 5.

von Oliver S. (oliverso)


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
von Chris K. (kathe)


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
von Oliver S. (oliverso)


Lesenswert?

Chris K. schrieb:
> Mal gekürzt auf das wesentliche. Vielleicht erkennst du jetzt das
> Problem.

Wer? Und welches Problem?

Der Code ist so, weil der angeblich nur so die Daten in der richtigen 
Reihenfolge ausgibt. Gelesen und geschrieben werden die Indices 0-5, was 
nach Adam Riese nunmal 6 Bytes sind.

Oliver

von Chris K. (kathe)


Lesenswert?

1
      for(int i = 1;i <= maxindex; i++)    
2
     { 
3
      UCA0TXBUF = axis[i];


Forschleife start bei 0 oder 1  ;-)
1
 
2
 for(int i = 1;i <= maxindex; i++)    
3
     { 
4
      UCA0TXBUF = axis[i-1];

: Bearbeitet durch User
von Harald K. (kirnbichler)


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 ...)

von Christian L. (Gast)



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

von Harald K. (kirnbichler)


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?

von Chris K. (kathe)


Lesenswert?

Harald K. schrieb:
;-)
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
von Oliver S. (oliverso)


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.
von Oliver S. (oliverso)


Lesenswert?

Nachtrag:

Wie man das NACK am Ende an die richtige Stelle bekommt, zeigt 
(vermutlich) der Code hier:
https://robert-fromm.info/teaching/vl_mra/307_msp_i2c/

Oliver

von Harald K. (kirnbichler)


Lesenswert?

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

Ja, das habe ich tatsächlich übersehen. Das ist dann einfach zuviel des 
Schwachsinns.

von Wastl (hartundweichware)


Lesenswert?

Harald K. schrieb:
> Ja, das habe ich tatsächlich übersehen. Das ist dann einfach zuviel des
> Schwachsinns.

... und weil ihr alle so böse seid, ist der TO jetzt beleidigt
und hat sich abgemeldet. Das Forums-Leben ist so hart ....

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.