PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LSM303D an Atomic 6DOF mit Software I2C . LSM303 gibt keine Daten ...



Ritchie
19.12.2014, 12:44
Hallo Zusammen,

ich habe ein LSM303D Board (Pololu LSM303D) an ein Atomic 6DOF XBEE Ready von Pololu Board via einen Software I2C Bus angeschlossen.
Hierbei verwende ich die freien RTS/CTS Ausgänge des Atomic Boards um mit dem LSM303D Board
zu reden. Ich bekomme jedoch keine Daten gesendet.

Beide Boards arbeiten mit 3.3V. Auf dem LSM303D Board sind bereits PullUps (4.7kOhm) vorhanden,
daher habe ich beide Boards direkt verbunden, ohne zusätzlichen Pullup.

Auch lasse ich das LSM303D Board von dem Atomic Board versorgen (XBEE Schnittstelle).

Wenn ich die Spannungen am Board VDD und Vin messe, erhalte ich 3.27 Volt.

Der Logic Analyser sagt mir das ich beim Lesen kein ACK vom LSM303D bekomme, aber ACK von gesendeten Werten.
Mir scheint es so, als ob das LSM303D Board die Datenleitung nicht gegen NULL ziehen kann,
obwohl ich die Datenleitung via DDR (Open Drain) ansteuere.

Hier der verwendete Quellcode.
Header Def.


#define SCLPORT PORTD //TAKE PORTD as SCL OUTPUT WRITE
#define SCLDDR DDRD //TAKE DDRB as SCL INPUT/OUTPUT configure
#define SDAPORT PORTD //TAKE PORTD as SDA OUTPUT WRITE
#define SDADDR DDRD //TAKE PORTD as SDA INPUT configure
#define SDAPIN PIND //TAKE PORTD TO READ DATA
#define SCLPIN PIND //TAKE PORTD TO READ DATA
#define SCL PD3 //PORTD.3 PIN AS SCL PIN
#define SDA PD2 //PORTD.2 PIN AS SDA PIN
#define SOFT_I2C_SDA_LOW SDADDR|=((1<<SDA))
#define SOFT_I2C_SDA_HIGH SDADDR&=(~(1<<SDA))
#define SOFT_I2C_SCL_LOW SCLDDR|=((1<<SCL))
#define SOFT_I2C_SCL_HIGH SCLDDR&=(~(1<<SCL))


Funktionen:


void SoftI2CInit()
{
SDAPORT&=(1<<SDA);
SCLPORT&=(1<<SCL);

SOFT_I2C_SDA_HIGH;
SOFT_I2C_SCL_HIGH;
}

void SoftI2CStart()
{
SOFT_I2C_SCL_HIGH;
H_DEL;

SOFT_I2C_SDA_LOW;
H_DEL;
}

void SoftI2CStop()
{
SOFT_I2C_SDA_LOW;
H_DEL;
SOFT_I2C_SCL_HIGH;
Q_DEL;
SOFT_I2C_SDA_HIGH;
H_DEL;
}

uint8_t SoftI2CWriteByte(uint8_t data)
{
uint8_t i;

for(i=0;i<8;i++)
{
SOFT_I2C_SCL_LOW;
Q_DEL;
if(data & 0x80)
SOFT_I2C_SDA_HIGH;
else
SOFT_I2C_SDA_LOW;

H_DEL;
SOFT_I2C_SCL_HIGH;
H_DEL;
while((SCLPIN & (1<<SCL))==0);
data=data<<1;
}

//The 9th clock (ACK Phase)
SOFT_I2C_SCL_LOW;
Q_DEL;
SOFT_I2C_SDA_HIGH;
H_DEL;
SOFT_I2C_SCL_HIGH;
H_DEL;
uint8_t ack=!(SDAPIN & (1<<SDA));
SOFT_I2C_SCL_LOW;
H_DEL;

return ack;

}


uint8_t SoftI2CReadByte(uint8_t ack)
{
uint8_t data=0x00;
uint8_t i;

for(i=0;i<8;i++)
{
SOFT_I2C_SCL_LOW;
H_DEL;
SOFT_I2C_SCL_HIGH;
H_DEL;
while((SCLPIN & (1<<SCL))==0);
if(SDAPIN &(1<<SDA))
data|=(0x80>>i);
}
SOFT_I2C_SCL_LOW;
Q_DEL; //Soft_I2C_Put_Ack
if(ack)
{
SOFT_I2C_SDA_LOW;
}
else
{
SOFT_I2C_SDA_HIGH;
}
H_DEL;
SOFT_I2C_SCL_HIGH;
H_DEL;
SOFT_I2C_SCL_LOW;
H_DEL;
SOFT_I2C_SDA_HIGH; // was missing!!

return data;

}


Funktion im Programm:


//================================================== ================
// Read one integer value from the I2C BUs connected Compass
// Low Byte and the High Byte
//================================================== ================

int read_Integer_LH_I2c(unsigned char BusAdr,unsigned char registerAdr)
{
char ret;
int retValue;

SoftI2CStart(); // Send Start Signal
SoftI2CWriteByte(BusAdr); // the requested SLAVE Address (WRITE)
SoftI2CWriteByte(registerAdr); // Send the requested Register
SoftI2CStart(); // Restart Signal
SoftI2CWriteByte(BusAdr+1); // Send Requested SLAVE Address (READ)
ret=SoftI2CReadByte(1); // read first byte (ACK)
retValue = ret; // Add the low byte
ret=SoftI2CReadByte(0); // read second byte and last (NACK)
SoftI2CStop(); // Stop Transmission
retValue += (ret << 8); // Shift the High Byte
return retValue; // get the value back
}


Aufruf:


void read_CompassValues(void)
{
LM303_x_magnet=read_Integer_LH_I2c(LM303_ADR,ADDR_ OUT_X_L_M); // get the magnetic field x from the LM303
LM303_y_magnet=read_Integer_LH_I2c(LM303_ADR,ADDR_ OUT_Y_L_M);;
LM303_z_magnet=read_Integer_LH_I2c(LM303_ADR,ADDR_ OUT_Z_L_M);;

LM303_x_accel=read_Integer_LH_I2c(LM303_ADR,ADDR_O UT_X_L_A); // get the accelerometer field x from the LM303
LM303_y_accel=read_Integer_LH_I2c(LM303_ADR,ADDR_O UT_Y_L_A);
LM303_z_accel=read_Integer_LH_I2c(LM303_ADR,ADDR_O UT_Z_L_A);

LM303_Temperature=read_Integer_LH_I2c(LM303_ADR,AD DR_OUT_TEMP_L);



Hat jemand eine ähnliche Konfiguration ?

Edit: Vermute den Fehler hier:


SDAPORT&=~(1<<SDA); // Set Output to zero (low)
MCUCR |= PUD; // Disable Pull Ups
SCLPORT&=~(1<<SCL); // Set Output to zero (low)

Da der Port mit "0" vorbelegt sein muss, damit der Three State Mode arbeitet.
Edit2:
Jetzt noch die Pullups abgeschaltet. Sieht schon besser aus.


Gruss R.