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.
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
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
Danke für die pdf aber das habe ich schon gelesen ich weiß ja wie es funktioniert aber ich finde meinen Fehler einfach nicht
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
>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
für slaveadress habe ich einmal die 0x38 eingesetzt für den bma020, habe es aber auch mit 0x70 und 0x71 ausprobiert
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
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?
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
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
hier ist der code mit aufgabenstellung Die case-Anweisungen werden durch eine matlab gui ausgelöst, das ist alles fertig
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.
ja genau habe es auch schon mal mit dieser i2c_communicate versucht bzw da ansätze raus genommen aber es hat auch nicht funktioniert
meine slave_adress gebe ich mit 112 vor, da ist das nach links schieben schon abgehandelt
> 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.
Hast du eigentlich einen Hardware Debugger? Kannst du ihn bedienen? Hängt sich dein Programm auf? Wenn ja, wo?
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.