Forum: Mikrocontroller und Digitale Elektronik BMA020 über TWI auslesen


von BMA (Gast)


Angehängte Dateien:

Lesenswert?

Hallo.

Ich habe ein Problem damit, einen BMA020 über TWI auszulesen bzw Daten 
hinzusenden. Mein Problem liegt wahrscheinlich in der TWI_SEND bzw 
TWI_RECEIVE Funktion. Als Parameter übergebe ich bei TWI_SEND die 
SlaveAdress 0x38, RegisterAdress 0x70 sowie Data. Beim TWI_RECEIVE 
übergebe ich die SlaveAdress 0x38 und die RegisterAdress 0x71.

Könnte mir evtl jemand sagen, wo meine Fehler evtl liegen bei den 
Funktionen?

LG

von Stefan F. (Gast)


Lesenswert?

> Ich habe ein Problem damit, einen BMA020 über TWI
> auszulesen bzw Daten hinzusenden.

Welches Problem hast du, welche Symptome hast du beobachtet? Was hast du 
bereits getan, um den Fehler einzukreisen? Hast du ein dazu geeignetes 
Messgerät? Hast du überhaupt schonmal i2c verwendet?

von spess53 (Gast)


Lesenswert?

Hi

>Als Parameter übergebe ich bei TWI_SEND die
>SlaveAdress 0x38, RegisterAdress 0x70 sowie Data. Beim TWI_RECEIVE
>übergebe ich die SlaveAdress 0x38 und die RegisterAdress 0x71.

Deine twi.c erwartet als Adresse die um ein Bit nach links geshifteten 
0x38, also 0x70.
1
void TWI_SendAddress(uint8_t Adress, uint8_t Direction)
2
{
3
  if (Direction==0)
4
  {
5
    Adress&=0xFE;
6
  }
7
  else
8
  {
9
    Adress|=0x01;

Das RW-Bit wird mit 'Direction' festgelegt. Die Registeradresse des 
BMA020 liegen im Bereich 0x00...0x15.

MfG Spess

von BMA (Gast)


Lesenswert?

Ich habe bisher noch nie mit I2C gearbeitet, die Funktionen waren alle 
schon gegeben bis auf die Receive und Send, diese sollte ich 
programmieren mit Hilfe der vorgegebenen Funktionen. Ich habe bisher 
alle möglichen Parameter verändert usw. ich denke, dass mein Ablauf vom 
Send (Start->Adresse und Registeradresse (wirte-bit) senden->Daten 
senden->Stop) und Receive (Start->Adresse und Registeradresse 
(write-bit) senden->neuer Start->Adresse und Registeradresse (read-Bit) 
senden->Register lesen->Stop) passt, jedoch klappt irgendeine 
kleinigkeit nicht und ich komme einfach nicht drauf...

von spess53 (Gast)


Lesenswert?

Hi

>Ich habe bisher noch nie mit I2C gearbeitet, die Funktionen waren alle
>schon gegeben bis auf die Receive und Send, diese sollte ich
>programmieren mit Hilfe der vorgegebenen Funktionen.

Dann lies dich erst mal ein, wie I2C so tickt:

http://www.nxp.com/documents/user_manual/UM10204.pdf

MfG Spess

von BMA (Gast)


Lesenswert?

Danke für die pdf aber das habe ich schon gelesen ich weiß ja wie es 
funktioniert aber ich finde meinen Fehler einfach nicht

von spess53 (Gast)


Lesenswert?

Hi

>uint8_t TWI_ReciveData(uint8_t SlaveAdress, uint8_t RegisterAdress)
>{
>  //uint8_t ReceiveData;              //Variable fuer die empfangenden Daten
>  TWI_StartCondition();              //Start der TWI Kommunikation
>  TWI_SendAddress(SlaveAdress, 0); //Senden der Slave- und
>                                     Registeradresse, write senden
>  TWI_RepeatedStartCondition();      //Erneuter Start der TWI Kommunikation
>  TWI_SendAddress(SlaveAdress, 1);        //Senden der Slave- und
>                                          Registeradresse, read senden
>  TWDR=RegisterAdress;  ?????????
>  TWI_ReadData();                  //Lesen der zu empfangenden Daten
>  TWI_StopCondition();              //Beenden der TWI Kommunikation
>  return (0);                    //Rückgabe der empfangenen Daten
>}

Was soll das 'TWDR=RegisterAdress;' machen? Die Registeradresse des 
BMA020 (0x00...0x15), die du lesen willst, muss nach 
'TWI_SendAddress(SlaveAdress, 0);' gesendet werden. Siehe Figure 16 auf 
S.35.

MfG Spess

von BMA (Gast)


Lesenswert?

ah stimmt danke der Ausdruck sollte heißen, dass ich da zeige, welches 
register gelesen werden soll

TWI_StartCondition();
TWI_SendAddress(SlaveAdress, 0);
TWDR=RegisterAdress;
TWI_WriteData(Data);
TWI_StopCondition();

Was ist denn an diesem Konstrukt falsch beim Send? Ich gebe ja nen Start 
vor, anschließend sende ich die Adresse und das write-Bit, danach die 
Registeradresse zB 0x14, anschließend die Daten, die ich senden will und 
zum schluss das Stop

von spess53 (Gast)


Lesenswert?

Hi

>danach die Registeradresse zB 0x14,

Mit 'TWDR=RegisterAdress;'?

Deine Senderoutine sieht so

>void TWI_WriteData(uint8_t Data)
>{
>  TWDR=Data;            // legt Data ins Senderegister
>  TWCR=(1<<TWINT)|(1<<TWEN); // Setzt TWI interrupt flag zurueck, Enable TWI
>  while (!(TWCR & (1<<TWINT)));  // wartet bis TWDR uebertragen ist
>  while((TWSR & 0xF8) != 0x28);  // prueft acknoledgement
>}

aus. Dort wird als erstes TWDR mit Data überschrieben. Also ist 
TWDR=RegisterAdress; sinnlos.

MfG Spess

von BMA (Gast)


Lesenswert?

wie wird es denn gemacht? also die send funktion?

von spess53 (Gast)


Lesenswert?

Hi

>wie wird es denn gemacht? also die send funktion?
1
TWI_StartCondition();
2
TWI_SendAddress(SlaveAdress, 0);
3
TWI_WriteData(RegisterAdress);
4
TWI_WriteData(Data);
5
TWI_StopCondition();

Was setzt du für 'SlaveAdress' ein?

MfG Spess

von BMA (Gast)


Lesenswert?

für slaveadress habe ich einmal die 0x38 eingesetzt für den bma020, habe 
es aber auch mit 0x70 und 0x71 ausprobiert

von spess53 (Gast)


Lesenswert?

Hi

>für slaveadress habe ich einmal die 0x38 eingesetzt für den bma020, habe
>es aber auch mit 0x70 und 0x71 ausprobiert

Beitrag "Re: BMA020 über TWI auslesen"

MfG Spess

von BMA (Gast)


Lesenswert?

ah okay also mein send sieht nun so aus:

void TWI_SendData(uint8_t SlaveAdress, uint8_t RegisterAdress, uint8_t 
Data)
{
  TWI_StartCondition();
  TWI_SendAddress(SlaveAdress, 0);
  TWI_WriteData(RegisterAdress);
  TWI_WriteData(Data);
  TWI_StopCondition();
}

Parameter: Slaveadress: 0x70 , RegisterAdress: 0x14, Data =Data

Ist es denn dann nun so richtig?

Und passt die Receive so:

uint8_t TWI_ReciveData(uint8_t SlaveAdress, uint8_t RegisterAdress)
{
  TWI_StartCondition();
  TWI_SendAddress(SlaveAdress, 0);
  TWI_WriteData(RegisterAdress);
  TWI_RepeatedStartCondition();
  TWI_SendAddress(SlaveAdress, 1);
  TWI_ReadData();
  TWI_StopCondition();
  return (0);
}

Paramter: SlaveAdress: 0x70, RegisterAdress: 0x14?

von spess53 (Gast)


Lesenswert?

Hi

Ich kann eigentlich kein c. Aber dein TWI_ReadData(void) gibt ein einen 
Wert zurück:

uint8_t TWI_ReadData(void)

Also sollte es etwa so

...
 uint8_t ReceiveData;
...
...
 ReceiveData=TWI_ReadData();
 TWI_StopCondition();
 return (ReceiveData);
}

aussehen.

Abgesehen davon kann Leseroutine immer nur ein Byte auslesen. Eine 
Koordinate besteht aber aus 2 Bytes.

MfG Spess

von BMA (Gast)


Lesenswert?

habe es nun so reingebracht aber es funktioniert immer noch nicht

von spess53 (Gast)


Lesenswert?

Hi

>habe es nun so reingebracht aber es funktioniert immer noch nicht

Dann wird es langsam Zeit für den kompletten Coded und den Schaltplan.

MfG Spess

von BMA (Gast)


Angehängte Dateien:

Lesenswert?

hier ist der code mit aufgabenstellung

Die case-Anweisungen werden durch eine matlab gui ausgelöst, das ist 
alles fertig

von Stefan F. (Gast)


Lesenswert?

Alternativ könntest du es mal mit meiner TWI Routine versuchen:

http://stefanfrings.de/mikrocontroller_buch/index.html Kapitel 11.4.

uint8_t register=2;
uint8_t buffer[6];
uint8_t count=i2c_communicate(0x38,&register,1,buffer,6);

Anschließend hast du im Buffer die 6 Bytes der drei Achsen X, Y und Z.

Nachtrag: Jetzt, wo die Aufgabenstellung klar ist, sehe ich, dass du die 
vorgegebenen TWI Funktionen nutzen sollst.

von Stefan F. (Gast)


Lesenswert?

Beachte, dass die vorgegebenen TWI Funktionen die 7 Bit Slave Adresse 
NICHT nach links schieben, wie es das TWI Protokoll verlangt. Du musst 
das daher selbst erledigen:

uint8_t slaveAddress=(0x38 << 1);

Die 6 Messwerte (2 pro Bytes Achse) stehe in den Registern 0x02 bis 
0x07.

Für die ersten Versuche kannst du diese Register einfach auslesen. Denn 
nach dem Power-On Reset arbeitet der Chip schon mit sinnvoller 
Konfiguration.

Erst wenn das klappt, würde ich versuchen, den Chip mit irgendwelchen 
Konfigurations-Settings zu beladen.

von BMA (Gast)


Lesenswert?

ja genau habe es auch schon mal mit dieser i2c_communicate versucht bzw 
da ansätze raus genommen aber es hat auch nicht funktioniert

von BMA (Gast)


Lesenswert?

meine slave_adress gebe ich mit 112 vor, da ist das nach links schieben 
schon abgehandelt

von Stefan F. (Gast)


Lesenswert?

> aber es hat auch nicht funktioniert

Ich habe meinen Code mit diesem Chip verifiziert, das war meine erste 
konkrete Anwendung für den Code.

Wenn bei Dir die Slave Adresse stimmt (muss bei meinem Code 0x38 sein) 
und die Registeradresse auch stimmt, dann hast du möglicherweise 
Probleme wegen einem Hardwarefehler.

> aber es funktioniert immer noch nicht

WAS funktioniert nicht? Hat die Steckdose keinen Strom? Macht dein Radio 
komische Geräusche? Wird der Sensor Heiß? Hängt die I2C Kommunikation 
(wenn ja, wo)? Bekommst du unplausible Werte (wenn ja, welche)?

Beantworte diese Frage mal etwas detaillierter, damit wir nicht blind 
raten müssen.

Welches Problem hast du, welche Symptome hast du beobachtet?
Hast du ein dazu geeignetes Messgerät?

von BMA (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang einmal die Matlab-GUI. (Treiber R2012a muss installiert werden 
32 Bit)

Sensor angeklemmt wie folgt:
PC0 -> SCK PC1 -> SDI
INT -> INT0 (PD2)
Spannung (3,2V oder 5V) auf UIN, UPullup, CSB
Masse auf GND und SDO

USART: PD0 -> RXD PD1 -> TXD
RS232 SPare über Adapter an PC angeschlossen

Werte kommen gar keine an! Kann die Gui mit dem Controller verbinden, es 
geschieht jedoch nichts

Sensor wird leicht warm

von Stefan F. (Gast)


Lesenswert?

> Spannung (3,2V oder 5V) auf UIN, UPullup, CSB

Also verwendet du scheinbar nicht den nackten Chip, sondern das Modul 
vom ELV Verlag. Zwei Sachen dazu:

Die Pegelwandler auf diesem Modul sind relatisch schwach. Du darfst sie 
nicht durch weitere Pull-Up Widerstände (z.B. auf dem 
Mikrocontroller-Board) belasten.

korrekt: SDO musst du mit GND verbinden, im Datenblatt des Chips steht 
das leider irreführend anders. Aber im Datenblatt des ELV Moduls ist es 
unmissverständlich dargestellt.

> Spannung (3,2V oder 5V)

Was heisst oder? Du must schon die gleiche Spannung verwenden, wie beim 
Mikrocontroller.

> Sensor wird leicht warm

Wird der BMA020 Chip warm, oder andere Bauteile in dessen Nähe? Die 
Stromaufnahme des Sensors ist so gering, dass er unmöglich spürbar warm 
werden kann.

> Werte kommen gar keine an! Kann die Gui mit dem Controller verbinden
Moment mal, ich dachte wir sind dabei, deinen Programmcode zu prüfen. 
Diese EXE Datei darf und will nicht ausführen.

beschreibe, was auf der I2C Schnittstelle passiert. Welche Signale 
treten dort auf?

Hast du ein dazu geeignetes Messgerät?

Ich glaube, du hast hier zu viele Baustellen auf einmal. Du hast eine 
Hardware, bei der nu nicht sicher bist, ob sie funktioniert. Und due 
hast mehrere Softwarekomponenten, bei denen du nicht sicher bist. Und 
dann bist auch nicht sicher, ob dein eigener Programmcode Ok ist.

Kreise das problem ein, und fange mit einem leeren Programm an:

Schließe an einen I/O Port acht LED's an und gebe ein Byte aus. Prüfe, 
ob die LED's wie erwartet leuchten. Wiederholde dies mit 
unterschiedlichen Werten.

Wenn das klappt, dann lese nur das Register 0 aus, zeige den Wert mit 
den LED's an und prüfe, ob er mit dem Datenblatt überein stimmt.

Dann sehen wir weiter.

Den ganzen Kram mit der Ablaufsteuerung und PC Kommunikation lässt du 
erstmal aus. Das stört nur.

von BMA (Gast)


Lesenswert?

Also auf die Pullup doch keine Spannung drauf? habe im internet mehrere 
Anschlusspläne gefunden und dort war immer Spannung auf den Pullups

Diese ganze Kommunikation funktioniert laut Prof., nur die TWI_INIT, 
TWI_SEND, TWI_Receive und USART_INIT, USART_SEND sollte neu geschrieben 
werden das sind die einzigen 5 Funktionen, wo etwas falsch sein kann, 
die anderen Funktionen (Data_Sync usw funktionieren alle einwandfrei). 
An Matlab muss auch nichts geändert werden, dort muss nur ein COM-Port 
ausgewählt werden...

Das was ich mit einem Messgerät überprüft habe, waren der CLK Pin und 
der SDA Pin für das TWI, diese waren beide auf einem High-Pegel

von Stefan F. (Gast)


Lesenswert?

> Also auf die Pullup doch keine Spannung drauf?

Das habe ich nicht geschrieben. Ich habe geschrieben, dass du die 
Leitungen nicht durch Zusätzliche Pullups auf der 
Mikrocontroller-Platien belasten darfst.

> Diese ganze Kommunikation funktioniert laut Prof., nur die TWI_INIT,
> TWI_SEND, TWI_Receive und USART_INIT, USART_SEND sollte neu geschrieben
> werden

Wie gesagt, zu viele Unbekannte auf einen Schlag. Reduziere den Code auf 
das absolute Minimum. Wenn ein pferd sich nicht bewegt, fängst du auch 
nicht damit an, das Futter zu untersuchen, sondern schaust zuerst nach, 
ob das Herz noch schlägt.

> Das was ich mit einem Messgerät überprüft habe, waren der CLK Pin
> und der SDA Pin für das TWI, diese waren beide auf einem High-Pegel

Wann waren sie auf High Pegel? Wenn diese beiden Leitungen ständig auf 
High stehen, findet gar keine Kommunikation statt. Jerdoch ist ein 
normales Multimeter kaum dazu geeignet, dies zu untersuchen. Ein 
Logikanalyzer oder notfalls ein Oszilloskop eignen sich schon eher.

Abgesehen davon durchsuche nochmal den ganze Thread nach Fragezeichen. 
Du hast mehr als die Hälfte aller Rückfragen noch nicht beantwortet. So 
können wir Dir nicht weiter helfen.

ich klinke mich jetzt erstnal aus - bis morgen.

von Stefan F. (Gast)


Lesenswert?

Hast du eigentlich einen Hardware Debugger? Kannst du ihn bedienen? 
Hängt sich dein Programm auf? Wenn ja, wo?

von BMA (Gast)


Lesenswert?

Habe meinen Fehler gefunden....

Und zwar lag es daran, dass ich die switch - case Struktur auch im main 
aufrufen muss und dort alle Funktionen pro case ausführen muss, nicht 
bei den cases im Interrupt...

Vielen Dank euch allen für die hilfreichen Tipps :)

von Stefan F. (Gast)


Lesenswert?

Der Prof hat dich schön in die Irre geführt. Und du solltest Dich mal 
mit Debugging Methoden beschäftigen - auch wenn das für die aktuelle 
Aufgabe nicht mehr nötig scheint.

von BMA (Gast)


Lesenswert?

Ja das kann man wohl sagen...

Habe zusätzlich noch 3 Aufgaben mit JTAG-Debugging gehabt ;) die gingen 
eigentlich ohne größere Probleme

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.