-
        

Ergebnis 1 bis 1 von 1

Thema: LSM303D an Atomic 6DOF mit Software I2C . LSM303 gibt keine Daten ...

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    07.11.2004
    Beiträge
    332

    LSM303D an Atomic 6DOF mit Software I2C . LSM303 gibt keine Daten ...

    Anzeige

    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.
    Code:
    #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:
    Code:
    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:
    Code:
    //==================================================================
    // 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:
    Code:
    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_OUT_X_L_A);        // get the accelerometer field x from the LM303
        LM303_y_accel=read_Integer_LH_I2c(LM303_ADR,ADDR_OUT_Y_L_A);
        LM303_z_accel=read_Integer_LH_I2c(LM303_ADR,ADDR_OUT_Z_L_A);
        
        LM303_Temperature=read_Integer_LH_I2c(LM303_ADR,ADDR_OUT_TEMP_L);

    Hat jemand eine ähnliche Konfiguration ?

    Edit: Vermute den Fehler hier:
    Code:
        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.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken Bildschirmfoto2.jpg   Bildschirmfoto3.jpg   Bildschirmfoto4.jpg  
    Geändert von Ritchie (19.12.2014 um 17:38 Uhr) Grund: Weitere Informationen und Quellcode beigefügt
    Kaum macht man es richtig, schon funktioniert's ...

Ähnliche Themen

  1. I2C LSM303 auslesen
    Von boecki91 im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 24.02.2012, 12:03
  2. Atmega 8 I2C mit 4x20 LCD keine Funktion
    Von likevista im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 08.09.2011, 21:42
  3. 6DOF: Gyro, Beschleunigung, GPS was mit was abgleichen?
    Von reflection im Forum Sensoren / Sensorik
    Antworten: 5
    Letzter Beitrag: 03.02.2009, 18:39
  4. Gibt keine Kommastellen aus ?!
    Von Roberto im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 16.11.2005, 12:52
  5. Antworten: 6
    Letzter Beitrag: 30.05.2005, 19:14

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •