- fchao-Sinus-Wechselrichter AliExpress         
Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 11 bis 20 von 34

Thema: SRF02. Wie ohne Timer Messwert-Abfrage steuern

  1. #11
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Anzeige

    Praxistest und DIY Projekte
    Ich mache mit PICs rum ... Datenblatt von Atmel ... weder einen Preis für Didaktik noch für Chipdesign verdient. Jetzt kann ich verstehen, weswegen viele I2C für kompliziert halten ...
    Seit einigen Wochen denke ich, dass PICs vielleicht die bessere Alternative sind: mein Program mer, der erste, der mir wirklich sehr gut gefällt, hat nen PIC. Der SRF02, der ja ziemlich gut funktioniert, hat auch nen PIC.

    Ok, ich habe jetzt mal rumbastelt am Quellcode und dies hier
    Code:
    //      30. Sept 2014, 14:ff
    //      Hier der Code von oben, mit Modifikationen (siehe Klebwax)
    
      cli(); tmr1  = 0; sei();      // Timer 1 starten
      i2c_start (Sadd + I2C_WRITE); // Starte Slave lesen
      i2c_write ( 0x00 );           // write address = dieses Byte soll gelesen werden
            i2c_stop();             //
    
      for ( ; ; )
      {                             //
        i2c_start (Sadd + I2C_READ);  // Slave bereit zum Lesen?
        lobyte  = i2c_readNak();      // Byte lesen... ACK
            i2c_stop();             //
        if ( lobyte > 200 ) break;
        uputs0 ("\r\tlbt "); uputs0u ( lobyte );
        .....
    in allerlei Variationen ausgekostet. Fazit: dieses Byte nimmt im Verlauf der Messung ansteigende Werte an bis die Messung (vermutlich) fertig ist, danach wird die Versionsnummer - aktuell 6 - gelesen.

    WENN ich z.B. bei >200 abbreche, dann fange ich schon mal viele Messungen ab, der Timer hat dann auch Werte, die zur Laufzeit "hin und zurück" passen.

    WENN ich bei 6 abbreche, dann hat üblicherweise die Messung nicht wirklich angefangen, dann läuft der Timer bis so etwa 2 bis 4 mal (ein Timerschritt sind 50µs). Die Variante "Abbruch bei 6 - Neustart lesen - Abbruch bei 6" funktioniert dann eher. Offensichtlich läuft dieses Hochtickern von Null bis zum Endwert und da kommt man eben an der Sechs schon beim Hochtickern vorbei. Die Versionsnummer ist 6.

    WENN ich bei 255 abbreche - abbrechen möchte - dann läuft der Controller sofort ins Koma. Irgendwie ominös, diesen Wert hatte ich nie gesehen, allenfalls etwas bei 240 und knapp drüber.

    Die Versuche leiden natürlich durch Zeitprobleme. Wenn ich zu schnell abfrage dann gibst Fehlfunktionen aber ich hoffe, dass ich diese Geschichten, die meist reproduzierbar waren, ordentlich interpretiert habe.

    Jedenfalls weiß ich jetzt, dass ich nicht die genannten 65 ms warten muss. Eine Messung geht teilweise deutlich schneller und passt gut in meine sonstigen, teils noch geplanten Aktivitäten, zumal ich zwei Ultraschallsensoren alternierend abfrage.
    Ciao sagt der JoeamBerg

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    @oberallgeier
    Du mußt den Returnwert von "i2c_start (Sadd + I2C_WRITE)" auswerten. So wie ich das in meinem Pseudocode geschrieben habe

    if(i2c_start(Adresse und Write) == 0) {
    .....
    Code:
    Erklärung in der Dokumentation zur Bibliothek (siehe obigen Link "... Master lib..") :
    unsigned char i2c_start     (      unsigned char      addr      )      
    
    Issues a start condition and sends address and transfer direction.
    
    Parameters:
            addr     address and transfer direction of I2C device
    
    Return values:
            0     device accessible
            1     failed to access device
    1 heißt, das Device ist nicht ansprechbar, hat nicht mit ACK geantwortet.

    Wer schreibt eigentlich den Code, den du da so postest, z.B. den Bascom Code. Ich sehe an keiner Stelle, daß ACK bzw NAK ausgewertet wird. Da wird überall blind in den Bus hineingerufen, ob ein Device nun antwortet oder gar nicht da ist. Das wird dann auch noch als Beispielcode veröffentlicht.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  3. #13
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    ... Du mußt den Returnwert von "i2c_start (Sadd + I2C_WRITE)" auswerten ... if(i2c_start(Adresse und Write) == 0) { ...
    Sorry, ja, danke. Zu Beginn dieser Litanei, den ich nicht zitiert hatte, hab ich es ja noch richtig:
    Code:
    //      Messung starten auf Sensor Sadd
    // - - - - - - - - - - - - - - -
      if (!(i2c_start (Sadd + I2C_WRITE)))  // Slave bereit zum schreiben?
      {                                     //   dann Werte schreiben
        i2cdmy  =  i2c_write (  00 );       // Buffer Startadresse setzen     
        i2cdmy  =  i2c_write ( 0x51 );      // Startbefehl SRF02
                   i2c_stop();              // Zugriff beenden
      }                                     //
      else                  // Weiter mit if (!(i2c_start( Sadd + I2C_WRITE )))
      {                                     //
        uputs0("\r\t## SRF_rdat\r");
        wms (   10);
        return 9901;                        // Return mit Fehlercode
      }                     // Ende if (!(i2c_start( Sadd + I2C_WRITE )))
    Und danach - hat das dauernde Ändern zu Schlamperei geführt. Hast ja Recht.

    ... Wer schreibt eigentlich den Code, den du da so postest, z.B. den Bascom Code ...
    Bascom sind Beispiele aus dem RN Wi ki, das kann ich nicht. Die C-Sequenzen sind von mir - sicher mehr schlecht als recht :-/ . Die I²C-Bibliothek ist von PFleury.
    Ciao sagt der JoeamBerg

  4. #14
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo zusammen,

    natürlich weitere Unterstützung (leider auch Fragen) von mir.


    @oberallgeier

    Die Defines für die TWI-Schnittstelle sind angegeben in twi.h im Verzeichnis ...\GCC-COMPILER\... \avr\include\util\

    #define TW_STATUS_MASK (_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3) )

    #define TW_STATUS (TWSR & TW_STATUS_MASK)

    Und die Form der hier benutzten Definition passt dann natürlich auch zu den 'Gegenstücken' um in einer case()-Anweisung die case-Sprungstellen zu finden.
    Die 'Gegenstücke' sind also sinnvollerweise auch in der Datei twi.h zu finden.
    Beispielsweise mit:
    #define TW_MT_SLA_ACK 0x18

    Somit ist es sehr wohl relevant, ob man nun die vorhandenen Defines nutzt oder "TwiStatus = TWSR >> 3".

    switch (TW_STATUS) {
    case TW_MT_SLA_ACK: xxx
    wird funktionieren.

    Aber
    TwiStatus = TWSR >> 3;
    switch (TwiStatus) {
    case TW_MT_SLA_ACK: xxx
    wird nicht mehr funktionieren, da nun die Bits mit >> 'versetzt' zu den 'Gegenstück'-Define stehen.

    Genauso wie es schon wichtig ist, dass man NICHT das Register TWSR in seinem switch() benutzt, da dann ja immer noch die letzten beiden Bits TWPS0 und TWPS1 zum Einstellen vom Prescaler enthalten sind, und dann auch nicht mehr zu den 'Gegenstücken' in der case-Orgie passen werden.


    Dein letzter Beitrag deutet ja darauf hin, dass während der Messung dieses 'merkwürdige' Versionsregister 0 eben nicht das macht was in der Doku steht.
    Nicht gut.



    @Klebwax

    Tut mir leid, jetzt kommen eher Fragen

    Und was passiert tatsächlich mit folgenden beiden C-Codezeilen?

    Erzeuge STOP mit sofort folgendem START in der TWI-Hardware:

    TWCR = (1<<TWSTO)|(1<<TWINT) | (1<<TWEN)|(1<<TWIE);
    TWCR = (1<<TWSTA) |(1<<TWINT) | (1<<TWEN)|(1<<TWIE);


    Der Compiler macht daraus:
    4d6: 85 e9 ldi r24, 0x95 ; 149
    4d8: 80 93 bc 00 sts 0x00BC, r24 <<== Register für TWI-Hardware im mega168 und anderen AVRs.

    4dc: 85 ea ldi r24, 0xA5 ; 165
    4de: 80 93 bc 00 sts 0x00BC, r24


    Hier liegen wir garantiert unter den 1.3 us und nun stellen sich mir folgenden Fragen:
    Was macht die Hardware tatsächlich, wenn sie STOP'en und sofort wieder START'en soll?
    Wird dann der Softwareteil beim START'en verzögert? Kann ich mir beim besten Willen nicht vorstellen.
    OK, nach dem START wird es etwas dauern, bis im TWSR das Bit TWINT wieder gesetzt wird. Klar, das macht die Hardware.

    Wenn ich die TWI-Hardware benutze, dann sollte ich natürlich nicht dein angegebenes "... und im Code darauf gewartet wird. ..." dahingehend wörtlich nehmen, dass ich nun eine Schleife im Code bauen soll, die zwischen STOP und START prüft, "... das sich der Status ändert ..."?

    Kannst du deine Erklärung genauer formulieren, bzw. mir eine Erklärung geben, die ich verstehe?


    Da die TWI-Hardware, nach einem durch die Software angegebenem STOP-Kommando an das Register TWCR, sich nicht mehr per Interrupt meldet, da nämlich kein Status-Wert für diese Aktion definiert ist im TWSR-Register (ODER habe ich diese Info noch nicht gefunden!), kann ich somit den nächsten START-Aufruf tatsächlich nur ohne Interrupt-Kontrolle erzeugen.
    Also auch im Extremfall wie oben angegeben.


    Im Handbuch finde ich folgendes: (mega48 bis 328 )

    Im Kapitel "Overview of the TWI Module" Unterpunkt "Bus Interface Unit":
    "When in Transmitter mode, the value of the received (N)ACK bit can be determined by the value in the TWSR."
    Also hier noch keine Angabe, was im TWSR nach einem STOP steht.

    Im Kapitel "Using the TWI" ist das Bild "Interfacing the Application to the TWI in a Typical Transmission" angegeben, welches die Aktionen von Software und Hardware sehr schön im (typischen) Zusammenspiel zeigt.
    Hinter dem STOP wird hier nichts mehr angegeben.
    Hast du hier eine Info, ob, und wie, der STOP-Zustand auf dem BUS im TWSR 'zu sehen' ist?

    Und das dazu wohl wichtigste Kapitel:
    "Overview of the TWI Module" Unterpunkt "Control Unit" ist zu finden, wann das Bit TWINT im TWSR gesetzt wird um anzuzeigen, das die Hardware fertig ist.
    • After the TWI has transmitted a START/REPEATED START condition.
    • After the TWI has transmitted SLA+R/W.
    • After the TWI has transmitted an address byte.
    • After the TWI has lost arbitration.
    • After the TWI has been addressed by own slave address or general call.
    • After the TWI has received a data byte.
    • After a STOP or REPEATED START has been received while still addressed as a Slave.
    • When a bus error has occurred due to an illegal START or STOP condition.
    Dort ist KEINE ANGABE vorhanden, das ein STOP das Bit setzt.
    Aus meiner Sicht ist somit nicht zu prüfen, wann das STOP 'fertig' ist. --> Alles eben beim ATmega und nicht in einem PIC.


    Gruß aus dem frühen neuen Tag
    Sternthaler


    Nachtrag:
    Vielleicht doch ne' Lösung vorhanden?

    In "Transmission Modes" Unterkapitel "Miscellaneous States" steht natürlich noch etwas zu diesem "illegal START or STOP condition"
    Table 22-6. Miscellaneous States

    0x00 Bus error due to an illegal START or STOP condition
    No TWDR action 0 1 1 X
    Only the internal hardware is affected, no STOP condition is sent on the bus. In all cases, the bus is released and TWSTO is cleared.
    Geändert von Sternthaler (30.09.2014 um 23:34 Uhr) Grund: 'illegal condition' aus dem Handbuch hinzugefügt.
    Lieber Asuro programieren als arbeiten gehen.

  5. #15
    Erfahrener Benutzer Roboter-Spezialist Avatar von schorsch_76
    Registriert seit
    25.03.2012
    Ort
    Kurz vor Neuschwanstein
    Alter
    48
    Beiträge
    456
    Hier
    TWCR = (1<<TWSTO)|(1<<TWINT) | (1<<TWEN)|(1<<TWIE);
    TWCR = (1<<TWSTA) |(1<<TWINT) | (1<<TWEN)|(1<<TWIE);

    muss man eigentlich warten bis das STO wieder zurück esetzt wurde (siehe Tabelle in DS).

    Seite 229 Atmega328 Doku: Table 21-2. Status codes for Master Transmitter Mode
    bzw. Table 21-3 für Master Receive.

    Man kann auch STO und STA gleichzeitig setzen. Siehe die genannten Tabellen.

  6. #16
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Erstmal danke für Eure Mühe, Geduld, Hilfe und Erklärungen.

    Zitat Zitat von Klebwax Beitrag anzeigen
    ... Du mußt den Returnwert von "i2c_start (Sadd + I2C_WRITE)" auswerten
    ... Da wird überall blind in den Bus hineingerufen ... auch noch als Beispielcode ...
    Nochmal zum Auswerten der Busanfrage. Derzeit, im Aufbau- und Teststadium habe ich nur zwei baugleiche Sensoren auf 0xE0 und 0xE2 angeschlossen. Wenn ich I²C fahre, dann prüfe ich standardmässig immer auf aktuell angeschlossene/vorhandene Devices in der Startphase des Controllers/Programms. Manchmal über den ganzen, meist aber nur über einen begrenzten Adressbereich. Ausgabe aufs Terminal.
    Code:
      SRF02_look ( );               // Suche angeschlossene Sensoren 0xE0..0xFE    SRF
    Code:
      while ( 1 )                   //
    //for ( u16 such=0xE0; such <= 0xFC; such = such + 2 )
      {                             // Teste nur I2C-Adressbereich der US-Sensoren
        if(!(i2c_start(such)))      // Slave bereit zum schreiben?
        {                           // 
          i2c_stop();               // Zugriff beenden
    // - - - - - - - - - - - - - - - -
          uputs0 ("\r\tUSdev addr\t");        // Melde zugriffbereiten Slave
          uputs0u (such); uputs0hex (such);         // ..mit dezimaler und Hex-Adresse
          jaflag = 55;              //
        }                           //
        else                        // Melde jetzt: Kein Byte geschrieben
        {                           //   und Fehlermelde-Strich
          if ( jaflag == 55 )       // Flag "Slave erkannt" ??
          {                         //
            uputs0 ("\r\t");        // .. dann neue Zeile für Nein-Strich(e)
          }                 // Ende if ( jaflag = 55; )
                                    
          jaflag    =  0;           // Flag zurücksetzen
          uputs0 ("-");             // Nein-Strich
    //    uputs0 ("\r-   ");        //
    //    uputs0hex (such);         // ..mit dezimaler und Hex-Adresse
          i2c_stop();               // Zugriff im Fehlerfall beenden, sonst SDA low
        }                   // Ende if(!(i2c_start(such)))
                                    //
        if ( such == 0xFE ) break;
        if ( such <= 0xFC ) such    =  such + 2;
    
      }             // Ende while ( 1 ), war for ( uint8_t such=0xE0; such <= 0xFE;
    Das kommt dann so aufs Terminal (dazu die Meldung zum Start-Kalibrieren - das eigentlich unnötig ist) :
    Code:
        C506x21-32(319) CiCo babyo328/20MHz 30 Sep 2014 19:42
        CIR: irLED=PB1, CIR PC0ff ...
        UART0 115 kBd    RxTx-buff 64/64.
    
        Init I²C ok
    
        I²C-Dev 0xE0-0xFE    NoDev =: '-'
        USdev addr    224=0xE0
        USdev addr    226=0xE2
        --------------        End    254=0xFE
    
        Kal SRF02 224=0xE0    End
        Kal SRF02 226=0xE2    End
    In der Entwicklungsphase neige ich dazu (mehr als sonst) leichtfertig zu programmieren, sprich: Busverfügbarkeit weglassen. Damit kann man manchmal schon frühzeitig Fehler provozieren. Dass die Leichtfertigkeit sich auch in den fertigen Code reinschmuggelt - kommt bei mir vor :-/

    ABER : aktuell sind nur die beiden Sensoren am Bus, es ist ein Master-Slave-Betrieb und aktuell nur der Timerinterrupt vom Boardtimer mit Heartbeat-LED. Da sollte der Bus sauber sein, es sei denn, ich habe irgendwo ein i2c_stop vergessen oder so was Ähnliches.

    Beispielcodes. Stimmt, das ist ein eigenes Thema. Ich hatte ne ganze Weile Mühe mit dem Code für den Master aus dem R N - Wissen zu TWI Slave mit avr-gcc. Der wird als getestet signiert - lief aber bei mir nicht (stand ja auch nix von "erfolgreich getestet"). Aber meist sind die Beispielcodes schon recht hilfreich und ohne die hätte ich viel mehr Mühe gehabt in C einzusteigen. Und in die ganze Controllertechnik.
    Ciao sagt der JoeamBerg

  7. #17
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Sternthaler Beitrag anzeigen
    @Klebwax

    Tut mir leid, jetzt kommen eher Fragen

    Und was passiert tatsächlich mit folgenden beiden C-Codezeilen?

    Erzeuge STOP mit sofort folgendem START in der TWI-Hardware:

    TWCR = (1<<TWSTO)|(1<<TWINT) | (1<<TWEN)|(1<<TWIE);
    TWCR = (1<<TWSTA) |(1<<TWINT) | (1<<TWEN)|(1<<TWIE);


    Der Compiler macht daraus:
    4d6: 85 e9 ldi r24, 0x95 ; 149
    4d8: 80 93 bc 00 sts 0x00BC, r24 <<== Register für TWI-Hardware im mega168 und anderen AVRs.

    4dc: 85 ea ldi r24, 0xA5 ; 165
    4de: 80 93 bc 00 sts 0x00BC, r24


    Hier liegen wir garantiert unter den 1.3 us und nun stellen sich mir folgenden Fragen:
    Was macht die Hardware tatsächlich, wenn sie STOP'en und sofort wieder START'en soll?
    Wird dann der Softwareteil beim START'en verzögert? Kann ich mir beim besten Willen nicht vorstellen.
    OK, nach dem START wird es etwas dauern, bis im TWSR das Bit TWINT wieder gesetzt wird. Klar, das macht die Hardware.

    Wenn ich die TWI-Hardware benutze, dann sollte ich natürlich nicht dein angegebenes "... und im Code darauf gewartet wird. ..." dahingehend wörtlich nehmen, dass ich nun eine Schleife im Code bauen soll, die zwischen STOP und START prüft, "... das sich der Status ändert ..."?

    Kannst du deine Erklärung genauer formulieren, bzw. mir eine Erklärung geben, die ich verstehe?


    Da die TWI-Hardware, nach einem durch die Software angegebenem STOP-Kommando an das Register TWCR, sich nicht mehr per Interrupt meldet, da nämlich kein Status-Wert für diese Aktion definiert ist im TWSR-Register (ODER habe ich diese Info noch nicht gefunden!), kann ich somit den nächsten START-Aufruf tatsächlich nur ohne Interrupt-Kontrolle erzeugen.
    Also auch im Extremfall wie oben angegeben.


    Im Handbuch finde ich folgendes: (mega48 bis 328 )

    Im Kapitel "Overview of the TWI Module" Unterpunkt "Bus Interface Unit":
    "When in Transmitter mode, the value of the received (N)ACK bit can be determined by the value in the TWSR."
    Also hier noch keine Angabe, was im TWSR nach einem STOP steht.

    Im Kapitel "Using the TWI" ist das Bild "Interfacing the Application to the TWI in a Typical Transmission" angegeben, welches die Aktionen von Software und Hardware sehr schön im (typischen) Zusammenspiel zeigt.
    Hinter dem STOP wird hier nichts mehr angegeben.
    Hast du hier eine Info, ob, und wie, der STOP-Zustand auf dem BUS im TWSR 'zu sehen' ist?

    Und das dazu wohl wichtigste Kapitel:
    "Overview of the TWI Module" Unterpunkt "Control Unit" ist zu finden, wann das Bit TWINT im TWSR gesetzt wird um anzuzeigen, das die Hardware fertig ist.
    • After the TWI has transmitted a START/REPEATED START condition.
    • After the TWI has transmitted SLA+R/W.
    • After the TWI has transmitted an address byte.
    • After the TWI has lost arbitration.
    • After the TWI has been addressed by own slave address or general call.
    • After the TWI has received a data byte.
    • After a STOP or REPEATED START has been received while still addressed as a Slave.
    • When a bus error has occurred due to an illegal START or STOP condition.
    Dort ist KEINE ANGABE vorhanden, das ein STOP das Bit setzt.
    Aus meiner Sicht ist somit nicht zu prüfen, wann das STOP 'fertig' ist. --> Alles eben beim ATmega und nicht in einem PIC.


    Gruß aus dem frühen neuen Tag
    Sternthaler


    Nachtrag:
    Vielleicht doch ne' Lösung vorhanden?

    In "Transmission Modes" Unterkapitel "Miscellaneous States" steht natürlich noch etwas zu diesem "illegal START or STOP condition"
    Table 22-6. Miscellaneous States

    0x00 Bus error due to an illegal START or STOP condition
    No TWDR action 0 1 1 X
    Only the internal hardware is affected, no STOP condition is sent on the bus. In all cases, the bus is released and TWSTO is cleared.
    Wenn ich deinen Text richtig verstehe, willst du mir sagen, zwischen Stop und Start muß eine Delay gemacht werden, ich liege falsch wenn locker sage "das kann man gleich hintereinander machen". Das mag bei den AVRs wohl sein, glaub ich aber eher nicht.
    Bei mir geht sofort eine große Warnleuchte an, wenn ich ein Delay im Code sehe. Ist dieselbe Leuchte, die angeht, wenn ein neues Gerät von Panzerband zusammengehalten wird.
    muss man eigentlich warten bis das STO wieder zurück gesetzt wurde (siehe Tabelle in DS).
    Das ist so ein gängiges Verfahren, ich kann aber nicht sagen, ob das hier klappt. In diesem Fall ist noch etwas anders, der TWI-Controler wartet mit einem Start, bis der Bus idle ist, und am Ende eines Stops wird der Bus idle.

    Was aber sicher nicht geht ist

    TWCR = (1<<TWSTO)|(1<<TWINT) | (1<<TWEN)|(1<<TWIE);
    TWCR = (1<<TWSTA) |(1<<TWINT) | (1<<TWEN)|(1<<TWIE);

    da wird in der zweiten Zeile TWISTO auf Null gesetzt, und in der Zeit ist ein Stop nicht erzeugt. Möglicherweise hat der TWI-Controler noch garnicht mitbekommen, daß TWISTO gesetzt war, er läuft ja nicht mit dem selben Takt, wie die CPU, sondern mit dem TWI-Clock oder einem vielfachen davon.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  8. #18
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Vielleicht plage ich mich noch mit dem alten 20 MHz-DSO an die Sache, aber ich glaube, da bekomme ich vertrauenswürdige Ergebnisse zum Start/Stop- bzw. Stop-Start-Problem nur deutlich unter meinem aktuellen Bustakt (explizit nenne ich 500 kHz, TWBR ist dann 12). Übrigens nennt das Datenblatt 8272D–AVR–05/12 aus Seite 340:
    Code:
    tBUF    Bus free time between a STOP and    fSCL = 100kHz 4.7 –    µs
            START condition                     fSCL > 100kHz 1.3 –    µs
    Ciao sagt der JoeamBerg

  9. #19
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693

    Busverfügbarkeit, die zweite

    Zitat Zitat von Klebwax Beitrag anzeigen
    @oberallgeier ... Du mußt den Returnwert von "i2c_start (Sadd + I2C_WRITE)" auswerten ...
    Wie oben geschrieben, das geschieht normalerweise. Und jetzt ist (wieder mal) Anlass darüber nachzudenken. Grundlage ist ordnungsgemäßes Programmieren von sicherem und schnellen Code für eine Singel-Master-I²C-Übertragung.

    MUSS ich - und wenn ja, WARUM, beim I²C-Master zu Beginn einer I²C-Übertragung den Returnwert auswerten? ICH (also mein Controller) sendet. Als Master. Da hat doch niemand den Bus lahmzulegen und ich müsste die früheren Aktionen ordnungsgemäß abgeschlossen haben. Ausnahme ist Mister Murphy-Law, der schon mal, wie sein Kollege Wackel-Kontakt und andere, dreinpfuschen kann. Aber normalerweise sollte doch der I²C-Bus zu Beginn der Übertragung nicht besetzt sein - ist ja kein Multimaster.

    Beim anschließenden Schreiben oder Lesen wird/kann das sinnvoll sein. Aber auch da überlege ich noch.

    Nicht dass es mir auf die paar zusätzlichen Maschinenbefehle für das "if" ankäme. Ich finde nur überflüssige Befehle sind ebenso unschönes Programmieren wie falsche.
    Ciao sagt der JoeamBerg

  10. #20
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    1.023
    Zitat Zitat von oberallgeier Beitrag anzeigen
    MUSS ich - und wenn ja, WARUM, beim I²C-Master zu Beginn einer I²C-Übertragung den Returnwert auswerten? ICH (also mein Controller) sendet.
    Weil dir eventuell seit dem letzten PowerUp ein EMP-Puls auf dem I2C-Bus den Slave aus dem Tritt gebracht hat und dieser Slave vielleicht keinen Reseteingang besitzt, über den du ihn programmtechnisch wieder zur Ordnung rufen könntest.
    Du kannst die Abfrage auch weglassen und stattdessen den Controller regelmässig vorbeugend eine I2C-Zauberformel sprechen lassen. Das ist irgendwas wie "mindestens 8x einen H-L-Wechsel auf der Clockleitung, während die Datenleitung H-Pegel hat". Könnte in der Philips-Doku (bzw. NXP) über den I2C-Bus stehen, müsste ich aber erst suchen.

    Konkretes Beispiel gefällig?
    Mein aktuelles Projekt mit I2C-Bus hängt nach dem Flashen häufig.
    Ein einziger Controller als Master und ein einziger Gesprächspartner, der nur Slavemodus kann; alles ganz elementar und minimal.
    Mein eigener, ursprünglicher Ansatz, den Bus in einen geordneten Zustand zu bringen war, zu Beginn jedes Datenaustauschs das I2C-Modul des Controllers zu deaktivieren, wieder zu aktivieren und dann einen I2C-Startzustand auf den Bus zu bringen.
    Nette Idee, hilft aber leider nicht. Ein PowerUp dagegen hilft immer. Vermutlich liegt das Problem darin begraben, dass das Flashen den Controller aus einer laufenden I2C-Kommunikation rausreisst, der Slave mangels Reset-Eingang aber in undefiniertem Zustand verharrt. Ich habe das noch nicht weiterverfolgt, weil ich bei der aktuellen Anwendung die Windows-Option habe: Power OFF , dann Power ON .

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Ähnliche Themen

  1. [ERLEDIGT] Probleme mit IF-Abfrage / Timer
    Von sammler im Forum C - Programmierung (GCC u.a.)
    Antworten: 11
    Letzter Beitrag: 25.04.2011, 11:41
  2. SRF02 über RS232 Beispielcode ohne Funktion?
    Von TobiasBlome im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 10.05.2009, 14:21
  3. problem mit button-abfrage im timer (c#)
    Von Roboman93 im Forum Open Source Software Projekte
    Antworten: 4
    Letzter Beitrag: 29.12.2008, 17:40
  4. SRF02 Messwert in Millimeter ermitteln
    Von Stiffer im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 29.03.2008, 12:00
  5. Messwert Diagramm erstellen... aber wie?
    Von raptor_79 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 15.11.2007, 08:30

Berechtigungen

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

Labornetzteil AliExpress