PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C Verbindung bleibt hängen



deko
27.12.2012, 20:18
Hallo,
ich versuche gerade einen MPU6050 über I2C anzusprechen, nur leider scheitere ich schon in der Initialisierungsphase.

Nutze ich als Dev-Adresse 0x68 dann hängt er sich bei "i2c_start_wait(Devaddr+I2C_WRITE);" auf.
Nutze ich als Dev-Adresse 0x69 dann hängt er sich bei "i2c_write(0x6B);" auf.

Änderung durch zusätzliche Pullup-Widerstände:

Als Anhang gibs noch Mitschnitte einmal mit Adresse 68 und einmal mit 69
bei 68 sendet er sich tot, immer wieder die gleiche Abfolge (die zu sehen ist)
bei 69 nur so wie gezeigt danach bleibt Clock auf Low und Data ist wider High



Ich nutze die Lib von Peter Fleury

Woran kann das liegen? Wie sprech ich das kleine Teil an?

Sourcecode:

#include <avr/interrupt.h> //UART
#include <avr/io.h>
#include <stdlib.h>
#include <stdint.h>
#include "test.h"
#include <inttypes.h>
#include <util/delay.h>

#include "uart.h"
#include "i2cmaster.h"

#define Devaddr 0x69 // device address of MPU6050 0x68 oder 0x69

//screen /dev/ttyS5 9600 8N1

int main(void)
{
unsigned char ret;
_delay_ms(1000);
i2c_init(); // init I2C interface

uart_init();

sei();

uart_puts("Started\r\n");

i2c_start_wait(Devaddr+I2C_WRITE); // set device address and write mode

i2c_write(0x6B);// Register Adress
i2c_write(0x01);// Data send
i2c_stop();

while (1)
{
_delay_ms(2000);
}
return 0;
}

deko
28.12.2012, 11:24
ich habe nun nochmal zusätzliche Pull-up Widerstände eingesetzt
--> auf Data passiert nun was

Aber er bleibt trotzdem hängen...

pirndi
28.12.2012, 11:31
Hy!

Ich kenne jz das Bauteil nicht auswendig aber kann es sein das du auf Read umschalten musst um zb ein Ack zu bekommen bevor es weitergeht?

mfg Pirndi

HeXPloreR
28.12.2012, 11:38
http://flyduino.net/MPU6050-Break-Out-onboard-33V-reg

Das Board hat seinen 4k7 PullUps ja schon drauf... ich vermute du hast sie nicht an 5V(Vcc) gehängt? Es bönötigt 5V Spannung, die dann runter auf 3,3V geregelt werden.

Deine While Schleife ist eine Endlosschleife, die alle 2000ms durchgeführt wird - ohne das sie was anderes tut sobald das Programm dort angekommen ist. Vielleicht den I²C start (funktionsaufruf) da rein legen?

Du meinst sicher Adresse 0x6B > "#define DevAddr 0x6B" nicht 0x68.

Welches hast Du denn genau-finde mindestens zwei?
https://www.sparkfun.com/products/11028
Das darf nur 3,4V bekommen!!!

pirndi
28.12.2012, 11:52
Hab mir das Datenblatt mal durchgesehen da sieht es aus als wenn du auf ein ACK warten musst. Dann sollte dein code etwa so aussehen:



if(!(i2c_start(ADW + I2C_WRITE))) //Slave bereit zum schreiben?
{
i2c_write(0x01);
i2c_rep_start(ADR);
x = i2c_readAck();
return 1;
}
else
{
i2c_readNak();
i2c_stop();

return 0;

}


in einer variable hier ist es x steht dann ack oder nck drinn ob das senden OK wahr oder nicht. der code sollte nur als hilfe dienen denn musst halt anpassen :p

pirndi

deko
28.12.2012, 12:00
ich habe den hier:
http://www.ebay.de/itm/MPU-6050-3-Axis-Gyro-Gyroscope-Accelerometer-Sensor-Module-for-Arduino-/181018466904?pt=Bauteile&hash=item2a258a9a58

es wird mit 5V versorgt
die pullups habe ich gegen 3,3V gesetzt (ohne externe pullups war data immer low...)

Wegen der Adresse hatte ich das gefunden:
// Default I2C address for the MPU-6050 is 0x68.
// But only if the AD0 pin is low.
// Some sensor boards have AD0 high, and the
// I2C address thus becomes 0x69.

Die while schleife wird wie oben beschrieben leider nicht mal erreicht.

Ich kann ja mal mit den READ-Bit etwas spielen und mal 0x6B als Adresse ausprobieren.

Danke schon mal

hat noch einer eine Idee

oberallgeier
28.12.2012, 12:06
...Nutze ich als Dev-Adresse 0x68 dann hängt er sich bei "i2c_start_wait(Devaddr+I2C_WRITE);" auf.
Nutze ich als Dev-Adresse 0x69 dann hängt er sich bei "i2c_write(0x6B);" auf ...Welchen Wert hat Dein I2C-WRITE ??

Es macht Sinn, die originale Spezifikation des I²C-Busses, UM10204 von NXP, zu lesen.
... Data transfers follow the format shown in Figure 9. After the START condition (S), a slave address is sent. This address is seven bits long followed by an eighth bit which is a data direction bit (R/W) — a ‘zero’ indicates a transmission (WRITE), a ‘one’ indicates a request for data (READ) ...Also ist jede ungerade Adresse zum Schreiben ebenso falsch wie ne gerade Adresse zum Lesen.

Ob die Fehlfunktion(en) nur an der fehlerhaften Adresse liegt/en habe ich jetzt nicht nachgesehen.

Viel Erfolg



... Ich kann ja mal mit den READ-Bit etwas spielen und mal 0x6B als Adresse ausprobieren ...Hmmm, sicher, klar kannst Du. Muss aber nicht sein *ggg*. Auch da macht sich die Anlehnung an die Dokumentation meist bezahlt.

deko
28.12.2012, 12:19
/** defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_READ 1

/** defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_WRITE 0

ist dann doch so wie es sein soll oder nicht?

pirndi
28.12.2012, 13:04
http://invensense.com/mems/gyro/documents/PS-MPU-6000A.pdf auf seite 37

du beginnst mit write adresse + i2c_wrtite
dann sendet er ein ACK das du dann lesen musst dann kannst du wieder schreiben dann kommt wieder ein ACK und dann die Daten.

Prüf auch nochmal die Adressen die kann man durch umpinnen ändern sieh mal nach ob da alles richtig ist.

- - - Aktualisiert - - -

http://www.i2cdevlib.com/docs/html/_m_p_u6050_8h_source.html hier hab ich noch eine header gefunden! da sind alle befehle drinnen die du senden kannst.

mit dem pin AD0 kannst du die adresse änderen wenn gnd dann nimmst du 0x68 + i2c_read bzw 0x68 + i2c_write wenn du AD0 auf high setzte dann nimmst du 0x69

deko
28.12.2012, 14:08
AD0 ist High

Ich verstehe die Welt nicht mehr:
i2c_start(0b11010010); //Write Mode geht

ABER: i2c_start_wait(Devaddr+I2C_WRITE); //Devaddr=0x69, I2C_WRITE=0 geht nicht


jetzt klappt das schreiben schon mal

beim Lesen gibt es aber Probleme:

uart_puts("Started\r\n");

i2c_start(0b11010010); //Write Mode
i2c_write(0x6B);// Register Adress
i2c_write(0x01);// Data send
i2c_stop();

i2c_start(0b11010010); //Write Mode
i2c_write(0x1B);// Register Adress
i2c_write(0x00);// Data send
i2c_stop();

i2c_start(0b11010010); //Write Mode
i2c_write(0x1C);// Register Adress
i2c_write(0x00);// Data send
i2c_stop();

i2c_start(0b11010010); //Write Mode
i2c_write(0x6B);// Register Adress
i2c_write(0x00);// Data send
i2c_stop();

_delay_ms(1);
i2c_start(0b11010010); //Write Mode
i2c_write(0x75);

_delay_ms(1);
i2c_rep_start(0b11010011); // set device address and read mode
ret = i2c_readNak(); // read one byte
i2c_stop();

uart_puts("Dev: ");
uart_puti(ret);
uart_puts("\r\n");

Beim "ret = i2c_readNak();" hängt er sich auf
der Slave schickt ihn kein Ack und keine Daten Clock bleibt auf low

Links auf den Bild ist der ausschnitt von:

i2c_start(0b11010010); //Write Mode
i2c_write(0x75);
Rechts der von:

i2c_rep_start(0b11010011); // set device address and read mode
ret = i2c_readNak(); // read one byte
i2c_stop();

oberallgeier
28.12.2012, 15:03
... i2c_start(0b11010010); //Write Mode geht ... i2c_start_wait(Devaddr+I2C_WRITE); //Devaddr=0x69, I2C_WRITE=0 geht nicht ...Auf die Schnelle, weil bei mir der Kaffee schon warm da steht:

0b11010010 = 0xD2 und das ist nicht 0x68 (die GERADE Adresse ... siehe oben). Und 0x69 + 0 ist 0x69 - und das ist auch keine gerade Zahl. Übrigens 0x68 = 0b1101000.