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
> 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?
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.
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...
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
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
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
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
Hi
>für slaveadress habe ich einmal die 0x38 eingesetzt für den bma020, habe>es aber auch mit 0x70 und 0x71 ausprobiertBeitrag "Re: BMA020 über TWI auslesen"
MfG Spess
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
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,®ister,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.
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.
> 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?
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
> 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.
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
> 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.
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 :)
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.