- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 23

Thema: [I²C] Beschleunigungssensor gibt kein ACK aus

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    34
    Beiträge
    1.192
    Hallo,
    das TWINT hat damit erst mal nichts zu tun. TWINT wird gesetzt wenn die aktuelle Übertragung abgeschlossen ist.
    Außerdem wäre die Abfrage des TWINT-Bits so falsch. Richtig müsste es heißen if(TWCR & 128 ) oder if(TWCR & (1<<TWINT)).
    TWINT ist nur ein Bit im Register TWCR und ist an siebter Stelle, d.h. TWINT ist immer 7.
    7 dezimal ist 111 binär, und in der if-Abfrage steht also: 111 & 1 , das gibt immer 1, ist also kein Wunder warum er über UART dann "TWINT = 1" ausgibt
    Das steht also in keiner Verbindung dazu, was auf dem Bus passiert.

    ACK auslesen:
    if( TWSR ==0x18 || TWSR==0x28 ){/*Ack wurde erkannt*/} beim Senden
    if( TWSR ==0x40 || TWSR==0x50 ){/*Ack wurde erkannt*/} beim Lesen
    Die Zahlen kommen von Seite 183 und 186 im Datenblatt. $ bzw 0x bedeutet hexadezimal.

    Grüße,
    Bernhard

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.09.2009
    Ort
    Geilenkirchen
    Beiträge
    419
    Vielen Dank!
    Das bringt mich schon einen ganzen Schritt weiter.
    Er empfängt jetzt jedenfalls schonmal ACK´s
    Aber irgendwie macht er nicht merh weiter nachdem ich stoppe und dann wieder starte.
    Code:
    uart_init (); 
    TWBR = 00010001;
    i2c_start ();
    while(!( TWSR == 0x08) )
    {}
    uart_write ("Start ");
    TWDR = 0b01110000; //sla +R
    TWCR = 0b10000100; // senden
    while(!( TWSR ==0x18 || TWSR==0x28 ))
    {}
    uart_write ("ACK empfangen ");
    TWDR = 0b00000010; //2. register
    TWCR = 0b10000100; //senden
    while(!( TWSR ==0x18 || TWSR==0x28 ))
    {}
    uart_write ("ACK2 empfangen ");
    TWCR = 10010100; //Stop
    while( !(TWCR & 128) )
    {}                     //warten
    uart_write ("Stop ");
     
    i2c_start ();
    while(!( TWSR == 0x08) )
    {}
    uart_write ("Start2 ");
    TWDR = 0b01110001;
    TWCR = 0b10000100; // senden
    while(!( TWSR ==0x18 || TWSR==0x28 ))
    {}
    uart_write ("ACK3 empfangen ");
    Das letzte, was ich empfange ist "STOP"
    Aber eigneltich mache ich beim Starten ja genau das gleiche, wie oben auch.
    Aber ich bekomme einfach kein START2.
    Was mache ich falsch?

    Gruß
    Olaf

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    34
    Beiträge
    1.192
    Hier fehlt noch ein 0b, momentan ist das noch dezimal:
    Code:
    TWCR =10010100; //Stop

    Grüße, Bernhard

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.09.2009
    Ort
    Geilenkirchen
    Beiträge
    419
    Oh, sowas dummes
    Danke vielmals, es funktioniert jetzt.
    Ich erhalte alle ACK´s.
    Wenn ich dem Sensor seine Masse wegnehme, dann bekomme ich keine ACK´s.
    Also er fühlt sich jedenfalls angesprochen und funktioniert.

    Jetzt habe ich nur noch eine Frage.
    Wann beginnt der Sensor zu senden?
    Automatsich, anchdem das ACK angekommen ist oder muss man erst TWINT auf 1 setzen?
    Sobald er gesendet hat, steht dann der wert sofort im TWDR register?

    Gruß
    Olaf

  5. #5
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    34
    Beiträge
    1.192
    Hallo,
    Wenn ich dem Sensor seine Masse wegnehme, dann bekomme ich keine ACK´s.
    Also er fühlt sich jedenfalls angesprochen und funktioniert.
    Wunderbar, dass das funktioniert. (Wenn du dem Sensor die Masse wegnimmst, kann er logischerweise nicht antworten, da er für's ACK ja auf Masse ziehen muss, die dann ja fehlt.)

    Der Master kann steuern, ob er lesen oder schreiben will, das geschieht mit der Adresse, genauer: mit dem niedrigsten Bit.
    Siehe: http://rn-wissen.de/index.php/I2C#Adressierung

    Du brauchst ungefähr diesen Ablauf:
    Code:
    I2C-Start
    Sende Slave-Adresse+Write
    Sende Nummer des Registers, das ausgelesen werden soll
    I2C-Stop oder Repeatet-Start
    Sende Slave-Adresse+Read
    Lese vom Bus ("       TWCR=0b10000100;    while(!(TWCR&128)){};    return TWDR;       ")
    I2C-Stop
    Ich würde dir auch noch empfehlen, einzelne Codeabschnitte als Methoden/Funktionen zu programmieren, das erhöht die Lesbarkeit/Übersicht, lässt sich wiederverwenden und bringt meistens weniger Fehler mit sich

    Grüße,
    Bernhard
    Geändert von BMS (02.04.2012 um 16:37 Uhr)

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    22.09.2009
    Ort
    Geilenkirchen
    Beiträge
    419
    Hallo
    Vieln Dank für deine Antwort.
    Es ist mir gerade gelungen die Chip ID auszulesen: 0b010

    Wenn du dem Sensor die Masse wegnimmst, kann er logischerweise nicht antworten, da er für's ACK ja auf Masse ziehen muss, die dann ja fehlt
    Das habe ich gemacht um zu sehen, dass acuh wirklich der Sensor mit mir redet und das ACK nicht sonstwoher kommt

    Jetzt gehts daran schöne, nutzerfreundliche und schnelle Funktionen zu schreiben.
    Aber ein Problem habe ich da noch.
    Und zwar muss ich trotz der Überprüfung des Statusregisters nach dem Start und nach dem Senden warten, damit alles funktioniert (_delay_ms (1)
    Ich habe die Startfunktion ein wenig umgeschrieben, aber das bringt auch nichts:
    Code:
    void i2c_start()
    {
     TWCR=0b10100100;        //TWEN, TWSTA und TWINT; unschön, aber geht ;)
     while(!( TWSR ==0x08 || TWSR==0x10 )) ;    //warten bis fertig start oder repeated start
    _delay_us (10); //Ohne delay geht es momentan nicht
    }
    Also nach dem Senden muss ich erst auf TWINT warten und dann auf das ACK ?

    Ich habe gerade gesehen, dass es 2 Register gratis dazu gibt
    2 Ungenutzte Register, in die man schreiben kann, was man will, 2Byte Speicher umsosnt!

    Gruß
    Olaf

    Gruß
    Olaf

  7. #7
    Erfahrener Benutzer Roboter Genie Avatar von BMS
    Registriert seit
    21.06.2006
    Ort
    TT,KA
    Alter
    34
    Beiträge
    1.192
    Und zwar muss ich trotz der Überprüfung des Statusregisters nach dem Start und nach dem Senden warten, damit alles funktioniert (_delay_ms (1)
    Ich habe die Startfunktion ein wenig umgeschrieben, aber das bringt auch nichts
    Mit welcher Geschwindigkeit betreibst du denn nun den Bus? (SCL-Frequenz)?
    Evtl musst du auch mal das Datenblatt von deinem Sensor durchschauen, ob in dieser Hinsicht etwas von Verzögerungen drinsteht. Auch die maximale Taktfrequenz vom Bus für den Sensor müsste da drinstehen.
    Von I2C-EEPROMs weiß ich z.B., dass sie ungefähr 1ms zum Schreiben von einem Byte benötigen.
    Also nach dem Senden muss ich erst auf TWINT warten und dann auf das ACK ?
    In dem Moment, wo TWINT entsprechend gesetzt wurde, ist die komplette Datenübertragung abgeschlossen. Ob das ACK dabei empfangen wurde, kannst du dann ja auslesen. Auf das ACK musst du in diesem Sinne nicht "warten".
    Ich würde den Controller auch nicht in eine Endlosschleife schicken zwecks ACK. Falls kein ACK kommt, würde ich die Übertragung abbrechen. Sonst wartet der Prozessor ewig wenn der Sensor mal nicht angeschlossen ist. Besser ist dann eine Art Fehlerbehandlung.

    Grüße, Bernhard

Ähnliche Themen

  1. DCF77 gibt kein Signal
    Von .:markus:. im Forum Elektronik
    Antworten: 13
    Letzter Beitrag: 06.08.2010, 17:10
  2. Beschleunigungssensor
    Von oratus sum im Forum Sensoren / Sensorik
    Antworten: 12
    Letzter Beitrag: 01.11.2009, 00:31
  3. Beschleunigungssensor
    Von bastman im Forum Sensoren / Sensorik
    Antworten: 3
    Letzter Beitrag: 01.11.2006, 08:53
  4. MyAVR- Board gibt kein masse
    Von senk im Forum AVR Hardwarethemen
    Antworten: 49
    Letzter Beitrag: 03.11.2005, 19:48
  5. Beschleunigungssensor
    Von BlackBroom im Forum Sensoren / Sensorik
    Antworten: 1
    Letzter Beitrag: 14.07.2005, 20:52

Berechtigungen

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

LiFePO4 Speicher Test